I want a UI up arrow button to be able to detect if it is pressing down. It is a child of a canvas in a 3D scene. My target platform is webGL for both desktops and mobiles. I coded not only the control of the up arrow UI button but also the control of keyboard arrow button for desktops.

The keyboard control worked fine in PC but the UI arrow button didn't work as expected both in desktop and mobile.

I tried the OnPointerDown() function attaching to the UI up arrow button and the logged it. The log didn't even show up when the UI button is pressed down both in desktop and mobile.

It seems the OnPointerDown() needs the image of the button to receive raycast so its image component Raycast target option is on.

Isn't the onPointerDown() supposed to be used in detecting press down of UI component by both mouse in desktop and touch in mobile?

How to get the UI button to be notified when it is pressed down? Any approach other than onPointerDown() which can do the same thing?

My scripts are here:

the one attached to the car object to be controlled

using UnityEngine;

public class CarPlayerControl : MonoBehaviour {

public float speed = 40;
private bool touchCtrl = false;
private float xInput = 0f;
private float zInput = 0f;

void Awake(){
    //if (Input.touchSupported && Application.platform 
         //     != RuntimePlatform.WebGLPlayer){
        //touchCtrl = true;
        //}
        }

void FixedUpdate(){

    xInput = 0f;
    zInput = 0f;

    if (touchCtrl)
    {

    }
    else //keyboard control in desktop
    {
        xInput = Input.GetAxis("Horizontal");
        zInput = Input.GetAxis("Vertical");
    }

    Move(xInput, zInput);
}

public void Move(float xInput, float zInput)
{
    float xMove = xInput * speed * Time.deltaTime;
    float zMove = zInput * speed * Time.deltaTime;

    float x = KeepXWithinRange(xMove);
    float y = transform.position.y;
    float z = KeepZWithinRange(zMove);

    transform.position = new Vector3(x, y, z);
}

private float KeepXWithinRange(float xMove){
    float x = transform.position.x + xMove;
    return Mathf.Clamp(x, 0, 900);
}

private float KeepZWithinRange(float zMove)
{
    float z = transform.position.z + zMove;
    return Mathf.Clamp(z, -470, 500);
}
}

and the one attached to the UI Up arrow button

using UnityEngine;

public class ButtonUpControl : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public GameObject car;
private CarPlayerControl carPlayerControl;
private bool mouseDown;
private float xInput;

void Awake()
{
    carPlayerControl = car.GetComponent<CarPlayerControl>();
    mouseDown = false;
}
void Start()
{

}

void FixedUpdate()
{
    if (mouseDown) {
        xInput = 1.0f;
    }
    else {
        xInput = 0f; 
    }

    carPlayerControl.Move(xInput, 0f);
}

public void OnPointerDown(PointerEventData eventData)
{
    mouseDown = true;
    Debug.Log("on ptr down btn up ");
}

public void OnPointerUp(PointerEventData eventData)
{
    mouseDown = false;
    Debug.Log("on ptr up btn up ");
}
}
  • Have you ensured an Event System exists in your scene Hierarchy ? you can also attach and EventTrigger to your buttons and drag and drop the public Methods there. – Omar Guendeli Dec 5 at 14:18
  • Hey! Why dont you use onClick.eventlistener? You can wrap any function up with it, even some simple bool. Make sure to include Unitys UI library to use the button directly inside your script. – Prometheus Dec 5 at 23:36

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.