How to use Event Trigger to control your character with Button and how to move it by holding down a button?
Technologies used in TETRY 3D Part 2
I will explain it again in this article. The purpose of this article is to register an Event to the Button and detect the state of the button when it is continuously pressed. We need to send input at regular intervals to keep the button pressed. In this case, we’ve made it so that the button is pressed once every 0.1 seconds.
Contents
Demonstration
First, let me show you how it works first.
Pressing the move button will move you one step.
Then press and hold the button to start continuous movement.
Registering Events to Button.
First, we add an Event Trigger component to the Button object we created.
Then you’ll need this code.
using UnityEngine;
using UnityEngine.EventSystems;
public class bodywalk : MonoBehaviour
{
//Button Object
public GameObject leftbutton;
public GameObject rightbutton;
//Events to register on the button. Both on and off.
private EventTrigger.Entry entry = new EventTrigger.Entry();
private EventTrigger.Entry entry0 = new EventTrigger.Entry();
private EventTrigger.Entry entry2 = new EventTrigger.Entry();
private EventTrigger.Entry entry20 = new EventTrigger.Entry();
//Press and hold timer.
private float tm = 0;
//The flag for a single button press
private bool leftok = true;
private bool rightok = true;
//Walking motion switching
private Animator animator;
// Start is called before the first frame update
void Start()
{
setButton();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
Moving();
}
void setButton()
{
//Create an event for the left button.
EventTrigger _leftbutton = leftbutton.GetComponent<EventTrigger>();
entry.eventID = EventTriggerType.PointerDown; //When the button is pressed.
entry0.eventID = EventTriggerType.PointerUp; //When the button is released.
//LeftMove() is registered as an event when the button is pressed
entry.callback.AddListener((eventData) => { LeftMove(); });
//Register LeftMoveOff() as an event when the button is released
entry0.callback.AddListener((eventData) => { LeftMoveOff(); });
//Register the created event to the button.
_leftbutton.triggers.Add(entry);
_leftbutton.triggers.Add(entry0);
//Create an event for the right button.
EventTrigger _rightbutton = rightbutton.GetComponent<EventTrigger>();
entry2.eventID = EventTriggerType.PointerDown;
entry20.eventID = EventTriggerType.PointerUp;
entry2.callback.AddListener((eventData) => { RightMove(); });
entry20.callback.AddListener((eventData) => { RightMoveOff(); });
_rightbutton.triggers.Add(entry2);
_rightbutton.triggers.Add(entry20);
}
//When the left button is pressed by a single shot.
void LeftMove()
{
if (leftok)
{
animator.SetBool("walking", true);
transform.rotation = Quaternion.Euler(0, 180, 0);
//Initialize the timer when you keep pressing it.
tm = 0;
transform.position = new Vector3(transform.position.x - 0.1f, transform.position.y, transform.position.z);
if(transform.position.x < -9.0f)
{
transform.position = new Vector3(-9.0f, transform.position.y, transform.position.z);
}
}
//Press and hold flag
leftok = false;
}
//When the left button is released
void LeftMoveOff()
{
animator.SetBool("walking", false);
//When the button is released, the single-shot flag is set to true.
leftok = true;
}
//Right button
void RightMove()
{
if (rightok)
{
animator.SetBool("walking", true);
transform.rotation = Quaternion.Euler(0, 0, 0);
tm = 0;
transform.position = new Vector3(transform.position.x + 0.1f, transform.position.y, transform.position.z);
if (transform.position.x > 9.0f)
{
transform.position = new Vector3(9.0f, transform.position.y, transform.position.z);
}
}
rightok = false;
}
void RightMoveOff()
{
animator.SetBool("walking", false);
rightok = true;
}
//Behaviour when pressed and held down
void Moving()
{
if (!leftok && rightok)
{
//Immediately after pressing, tm is 0, so it is added by Time.deltaTime.
if (tm == 0)
{
tm += Time.deltaTime;
}
//Move to position when tm is 0.25 seconds.
else if (tm >= 0.25 && tm < 0.26)
{
transform.position += transform.right / 20;
if (transform.position.x < -9.0f)
{
transform.position = new Vector3(-9.0f, transform.position.y, transform.position.z);
}
}
//Move to position when tm is 0.35 seconds.
else if (tm >= 0.35)
{
transform.position += transform.right / 20;
if (transform.position.x < -9.0f)
{
transform.position = new Vector3(-9.0f, transform.position.y, transform.position.z);
}
//The tm returns to 0.15 seconds and is pushed again after 0.1 seconds.
tm = 0.15f;
}
//Wait for 0.25 seconds.
else { tm += Time.deltaTime; }
}
else if (leftok && !rightok)
{
if (tm == 0)
{
tm += Time.deltaTime;
}
else if (tm >= 0.25 && tm < 0.26)
{
transform.position += transform.right / 20;
if (transform.position.x > 9.0f)
{
transform.position = new Vector3(9.0f, transform.position.y, transform.position.z);
}
}
else if (tm >= 0.35)
{
transform.position += transform.right / 20;
if (transform.position.x > 9.0f)
{
transform.position = new Vector3(9.0f, transform.position.y, transform.position.z);
}
tm = 0.15f;
}
else { tm += Time.deltaTime; }
}
//Initialize tm when the button leaves
else if (leftok || rightok)
{
tm = 0;
}
}
}
It’s long, so I’ll explain it one at a time.
First, let’s talk about variables.
//Button Object
public GameObject leftbutton;
public GameObject rightbutton;
//Events to register on the button. Both on and off.
private EventTrigger.Entry entry = new EventTrigger.Entry();
private EventTrigger.Entry entry0 = new EventTrigger.Entry();
private EventTrigger.Entry entry2 = new EventTrigger.Entry();
private EventTrigger.Entry entry20 = new EventTrigger.Entry();
//Press and hold timer.
private float tm = 0;
//The flag for a single button press
private bool leftok = true;
private bool rightok = true;
//Walking motion switching
private Animator animator;
Button is specified from Inspector. It is both left and right.
Enter the events for each of the left and right buttons to be pressed and released in EventTriger.
We will explain below tm later.
void setButton()
{
//Create an event for the left button.
EventTrigger _leftbutton = leftbutton.GetComponent<EventTrigger>();
entry.eventID = EventTriggerType.PointerDown; //When the button is pressed.
entry0.eventID = EventTriggerType.PointerUp; //When the button is released.
//LeftMove() is registered as an event when the button is pressed
entry.callback.AddListener((eventData) => { LeftMove(); });
//Register LeftMoveOff() as an event when the button is released
entry0.callback.AddListener((eventData) => { LeftMoveOff(); });
//Register the created event to the button.
_leftbutton.triggers.Add(entry);
_leftbutton.triggers.Add(entry0);
}
SetButton() registers an event to Button.
I stored EventTrigger in the _leftbutton, and
Add a button press/release action to the entry and entry0 you just set.
entry has LeftMove() and
For Entry0, LeftMoveOff() will run when the button is released.
Register the event created by trigger.Add.
If you register the right button in the same way, the button will become available.
Detects a long press of a button.
First, we’ll look at the code for a single shot.
void LeftMove()
{
if (leftok)
{
animator.SetBool("walking", true);
transform.rotation = Quaternion.Euler(0, 180, 0);
//Initialize the timer when you keep pressing it.
tm = 0;
transform.position = new Vector3(transform.position.x - 0.1f, transform.position.y, transform.position.z);
if(transform.position.x < -9.0f)
{
transform.position = new Vector3(-9.0f, transform.position.y, transform.position.z);
}
}
//Press and hold flag
leftok = false;
}
//When the left button is released
void LeftMoveOff()
{
animator.SetBool("walking", false);
//When the button is released, the single-shot flag is set to true.
leftok = true;
}
The leftok is true if it is a single shot and will be false if you keep pressing it.
tm is used as an interval between consecutive button presses. It returns to 0 when a single press is made.
Leftok will be false after one move.
LeftMoveOff() returns lefok to true when you release the button, so that it starts again from a single shot.
The next code is when you press it in succession, but it’s longer because I made it common to both sides.
“else if (leftok && !rightok)” below is the right action, so I’ll explain the first half.
void Moving()
{
if (!leftok && rightok)
{
//Immediately after pressing, tm is 0, so it is added by Time.deltaTime.
if (tm == 0)
{
tm += Time.deltaTime;
}
//Move to position when tm is 0.25 seconds.
else if (tm >= 0.25 && tm < 0.26)
{
transform.position += transform.right / 20;
if (transform.position.x < -9.0f)
{
transform.position = new Vector3(-9.0f, transform.position.y, transform.position.z);
}
}
//Move to position when tm is 0.35 seconds.
else if (tm >= 0.35)
{
transform.position += transform.right / 20;
if (transform.position.x < -9.0f)
{
transform.position = new Vector3(-9.0f, transform.position.y, transform.position.z);
}
//The tm returns to 0.15 seconds and is pushed again after 0.1 seconds.
tm = 0.15f;
}
//Wait for 0.25 seconds.
else { tm += Time.deltaTime; }
}
else if (leftok && !rightok)
{
if (tm == 0)
{
tm += Time.deltaTime;
}
else if (tm >= 0.25 && tm < 0.26)
{
transform.position += transform.right / 20;
if (transform.position.x > 9.0f)
{
transform.position = new Vector3(9.0f, transform.position.y, transform.position.z);
}
}
else if (tm >= 0.35)
{
transform.position += transform.right / 20;
if (transform.position.x > 9.0f)
{
transform.position = new Vector3(9.0f, transform.position.y, transform.position.z);
}
tm = 0.15f;
}
else { tm += Time.deltaTime; }
}
//Initialize tm when the button leaves
else if (leftok || rightok)
{
tm = 0;
}
}
Leftok and rightok will move the left long push to avoid pressing and holding the left and right buttons at the same time.
First, since tm starts at 0, we wait 0.25 seconds with tm += Time.deltaTime;.
The move is made when tm reaches 0.25. Then when it reaches 0.35, the move is made again and tm is set back to 0.15 seconds.
So after 0.35, 0.1 seconds is followed by 0.25, so the buttons are hit continuously at 0.1 second intervals.
When either button is released, tm is set to 0.
How it’s used in TETRY 3D
Because TETRY 3D was moving blocks one square at a time, the emphasis was on crisp movement rather than seamless movement. So regular movement spacing was useful, but I think there are many different approaches to movement when used in other games.
In this case, we used the movement code almost as it is, but there is a possibility that the movement speed may change depending on the number of frames.
Also, since TETRY 3D had to register the target of the operation to the button each time because the blocks to be operated on changed from one to the next, this was done by scripting from the acquisition of the Button object.
That was the technology used in the second TETRY 3D.
Thank you for your close reading.
- Tags:
- C#
- Commentary
- Game
0 Comments