(Unity 2D手机)我需要区分按钮触摸和屏幕触摸

发布于 2025-01-18 05:47:40 字数 4476 浏览 1 评论 0原文

我正在制作一款手机 2d 游戏。我在屏幕右下角有一个发射激光的按钮。我确实有一个喷气背包脚本,当触摸屏幕时,它会增加力量让玩家上升。但是当我触摸射击按钮时,它会发射激光并让玩家上升。我需要区分它们。

Jetpack 脚本:

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);
        }
    }
}

移动 UI 控制器脚本:

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();
    }
}

请帮忙!先感谢您。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

潇烟暮雨 2025-01-25 05:47:40

从根本上讲,您的问题是您有两项重叠的输入检查。您在右下角有一张检查,并进行覆盖整个屏幕的检查。但是由于整个屏幕都包含右下角,因此它们都同时发生。

有多种方法可以团结一致,我不会全部介绍它们。但是,我将概述我认为是最好的方法。

分层UI按钮

我不确定您是如何进行当前输入检查(代码似乎只处理键盘输入?),但这是使用帆布上使用按钮的理想用例。您只需在屏幕上放置两个按钮即可。一个占用整个屏幕,另一个在角落的顶部。您可以通过进入gameObject&gt;可以轻松地放置按钮;创建&gt; ui&gt;按钮。 “ 并根据需要进行配置。

然后,您禁用图像组件以防止它们覆盖整个屏幕,瞧!两个不矛盾的按钮。

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 exampleand 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.

萌能量女王 2025-01-25 05:47:40

在您的脚本中,我将检查我的触摸或指针是否位于 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);
        }
    }

,并且 IsOverUI() 如下所示

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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文