You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity移动端2D游戏多按钮同时触摸功能故障求助

问题排查与修复方案

核心问题分析

  1. RectangleContainsScreenPoint参数缺失:该方法需要传入对应相机参数(UI画布类型不同,相机要求有差异),原代码未传递,导致检测逻辑失效。
  2. 转义字符错误:代码中GetComponent&lt;RectTransform&gt;()是HTML转义写法,Unity无法识别,应改为GetComponent<RectTransform>()。
  3. 触摸状态未重置:TouchPhase.Ended时未将对应按钮的布尔变量设为false,导致按下后状态一直保持。
  4. 多触摸互斥:原代码用else if,同一时间只能识别一个按钮,无法实现同时前进+转向的需求。
  5. 组件依赖问题:若按钮是UI元素,无需添加BoxCollider2D,UI自带的Image/Button组件已包含碰撞检测;若为世界空间按钮,需确保RectTransform和BoxCollider2D的尺寸匹配。

修复后的完整代码

using UnityEngine;

public class BikeScript : MonoBehaviour
{
    WheelJoint2D[] wheelJoints;
    JointMotor2D BackTire;

    public GameObject button1_Thrt;
    public GameObject button2_Brake;
    public GameObject button3_Left;
    public GameObject button4_Right;

    public bool Thrt = false;
    public bool Brake = false;
    public bool Left = false;
    public bool Right = false;

    // 根据画布类型获取对应相机
    private Camera GetUICamera()
    {
        if (button1_Thrt != null)
        {
            Canvas canvas = button1_Thrt.GetComponentInParent<Canvas>();
            return canvas?.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas?.worldCamera;
        }
        return Camera.main;
    }

    private bool IsTouchingButton(GameObject button, Vector2 touchPosition)
    {
        if (button == null)
            return false;

        RectTransform rectTransform = button.GetComponent<RectTransform>();
        if (rectTransform == null)
        {
            Debug.LogError($"按钮{button.name}缺少RectTransform组件");
            return false;
        }

        return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, touchPosition, GetUICamera());
    }

    void FixedUpdate()
    {
        if (Input.touchCount > 0)
        {
            // 先重置所有状态,再根据当前触摸更新
            ResetButtonStates();

            for (int i = 0; i < Input.touchCount; i++)
            {
                Touch touch = Input.GetTouch(i);
                Vector2 touchPos = touch.position;

                switch (touch.phase)
                {
                    case TouchPhase.Began:
                    case TouchPhase.Stationary:
                    case TouchPhase.Moved:
                        // 用独立if,支持多按钮同时触发
                        if (IsTouchingButton(button1_Thrt, touchPos))
                        {
                            Debug.Log("触摸油门按钮");
                            Thrt = true;
                        }
                        if (IsTouchingButton(button2_Brake, touchPos))
                        {
                            Debug.Log("触摸刹车按钮");
                            Brake = true;
                        }
                        if (IsTouchingButton(button3_Left, touchPos))
                        {
                            Debug.Log("触摸左转向按钮");
                            Left = true;
                        }
                        if (IsTouchingButton(button4_Right, touchPos))
                        {
                            Debug.Log("触摸右转向按钮");
                            Right = true;
                        }
                        break;
                    case TouchPhase.Ended:
                    case TouchPhase.Canceled:
                        // 若触摸结束在按钮范围内,重置对应状态
                        if (IsTouchingButton(button1_Thrt, touchPos)) Thrt = false;
                        if (IsTouchingButton(button2_Brake, touchPos)) Brake = false;
                        if (IsTouchingButton(button3_Left, touchPos)) Left = false;
                        if (IsTouchingButton(button4_Right, touchPos)) Right = false;
                        break;
                }
            }
        }
        else
        {
            // 无触摸时重置所有状态
            ResetButtonStates();
        }
    }

    // 统一重置按钮状态
    private void ResetButtonStates()
    {
        Thrt = false;
        Brake = false;
        Left = false;
        Right = false;
    }
}

额外注意事项

  • 按钮组件配置:
    • 若为UI按钮:确保按钮挂载Image(或Text)+RectTransform,无需手动添加BoxCollider2D,Unity会自动处理UI碰撞检测。
    • 若为世界空间按钮:确保BoxCollider2D的尺寸与RectTransform的尺寸完全匹配,且相机能正确捕捉按钮的屏幕位置。
  • 引用赋值:在Unity编辑器中,将四个按钮对象拖拽到BikeScript组件的对应字段中,确保引用不为null。
  • 画布设置:若使用Screen Space - Camera模式,需将画布的Render Camera设置为场景中的主相机。

内容的提问来源于stack exchange,提问作者Geo367

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 14:13:13