Home > Net >  (Unity 2d Mobile) I need to differentiate between button touch and screen touch
(Unity 2d Mobile) I need to differentiate between button touch and screen touch

Time:04-01

Im making a mobile 2d game. I have a button to shoot lasers on the right bottom of the screen. And i do have a jetpack script that when touched on screen it add force to make the player go up. But when i touch the shoot button it shoots laser and also makes the player go up. I need to differentiate them.

Jetpack Script:

public class Jetpack : MonoBehaviour
{

    public static Jetpack instance;

    public float speed, jumpForce;

    Rigidbody2D rb;

    ParticleSystem ps;

    public float health = 3f;

    public TMPro.TextMeshProUGUI HealthText;

    public TMPro.TextMeshProUGUI GoldText;

    public float Gold = 0f;

    public Transform laserSpawnPosition;

    public GameObject laser;

    public AudioClip[] audios;

    public string prefHighScore = "The High Score: ";

    public float score;

    public float highScore;

    public float scoreMultiplier = 1f;

    public TMPro.TextMeshProUGUI ScoreText;

    public TMPro.TextMeshProUGUI HighScoreText;

    public GameObject panelGameOver;

    //public bool isShooting = false;

    private void Awake()
    {

        rb = GetComponent<Rigidbody2D>();

        instance = GetComponent<Jetpack>();

        ps = GetComponentInChildren<ParticleSystem>();

        HealthText.text = health   "";

        GoldText.text = Gold   "";

        panelGameOver.SetActive(false);
    }

    // Start is called before the first frame update
    void Start()
    {

        score = 0;

        health = 3f;

        Gold = 0;

        highScore = PlayerPrefs.GetInt(prefHighScore, 0);

        Time.timeScale = 1;

        HighScoreText.text = "Your High Score: "   highScore;
    }

    // Update is called once per frame
    void Update()
    {
        
        ScoreText.text = (int)score   "";

        score  = Time.deltaTime * 10 * scoreMultiplier;

        GoldText.text = (int)Gold   "";

        HealthText.text = (int)health   "";

        if (Input.GetKeyDown(KeyCode.Space))
        {
            ps.Play();
        }
       
        
        // new                      // new
        if (Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0) || Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
        {
            rb.AddForce(Vector2.up * jumpForce);
        }

        if (Input.GetKeyUp(KeyCode.Space))
        {
            ps.Stop();
        }

        if (health <= 0)
        {
            Debug.Log("You are dead...");

            //HealthText.text = "0";

            panelGameOver.SetActive(true);

            Time.timeScale = 0;
        }

        //if (Input.GetButtonDown("Fire1"))
        //{
            //FireLaser();

            //Debug.Log("Shooting Laser");
        //}
    }

    public void AddHealth()
    {
        health  = 1;
    }

    public void AddGold()
    {
        Gold  = 1;
    }

    void FireLaser()
    {

        Instantiate(laser, laserSpawnPosition.position, Quaternion.identity);

        PlayLaserSound();

    }

    public void MobileFireLaser()
    {
        FireLaser();
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Gold")
        {
            AddGold();

            PlayGoldSound();

            Debug.Log("Gold: "   Gold);

            Destroy(collision.gameObject);
        }
    }

    public void PlayHitSound()
    {
        AudioSource.PlayClipAtPoint(audios[0], new Vector3(transform.position.x, transform.position.y, transform.position.z));
    }

    public void PlayHealthSound()
    {
        AudioSource.PlayClipAtPoint(audios[1], new Vector3(transform.position.x, transform.position.y, transform.position.z));
    }

    public void PlayGoldSound()
    {
        AudioSource.PlayClipAtPoint(audios[2], new Vector3(transform.position.x, transform.position.y, transform.position.z));
    }

    public void PlayLaserSound()
    {
        AudioSource.PlayClipAtPoint(audios[3], new Vector3(transform.position.x, transform.position.y, transform.position.z));
    }

    private void OnDisable()
    {
        if (score > highScore)
        {
            PlayerPrefs.SetInt(prefHighScore, (int)score);
        }
    }
}

Mobile UI Controller Script:

public class MobileUICtrl : MonoBehaviour
{


    public GameObject player;

    Jetpack playerCtrl;

    // Start is called before the first frame update
    void Start()
    {
        playerCtrl = player.GetComponent<Jetpack>();
    }

    public void MobileFireLaser()
    {
        playerCtrl.MobileFireLaser();
    }
}

Please help! Thank you in advance.

CodePudding user response:

Fundamentally, your problem is that you have two different input checks that overlap. You have a check in the bottom right corner, and a check that covers the whole screen. But since the whole screen includes the bottom right corner, they both happen at the same time.

There are a number of ways to deal with this in Unity, and I won't cover them all. However, I will outline what I feel is the best approach.

Layered UI Buttons

I'm not sure how you're doing your current input check (the code only seems to handle keyboard input?) but this is the perfect use case for using Buttons on the Canvas. You can simply place two buttons on the screen. One that takes up the whole screen, and another on top of it in the corner. You can easily place buttons by going into GameObject > Create > UI > Button.Unity button creation example and configuring them as desired.

Then you disable the Image component to prevent them from covering the whole screen, and voila! Two buttons that don't contradict eachother. Disabled image component.

CodePudding user response:

In your script I would check that if my touch or pointer is over ui

if (Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0) || Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
    {
        //Here I would check if my pointer or touch is over UI if not I will add force
        If(!IsOverUI()){
            rb.AddForce(Vector2.up * jumpForce);
        }
    }

and IsOverUI() would look like following

public bool IsOverUI()
{
    PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
    eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    List<RaycastResult> results = new List<RaycastResult>();
    EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
    return results.Count > 0;
}
  • Related