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

Play模式下禁用Player脚本后Jump功能仍触发的问题咨询

问题与解答

问题场景

场景中有2个Player对象,每个都挂载了负责Jump功能的Player脚本。正常运行时点击Jump按钮,两个Player都会跳跃,符合预期。但在Play模式下禁用其中一个Player的脚本后,点击Jump按钮,两个Player依然会跳跃,这是为什么?

用到的代码如下:

查找按钮代码

private void Start() {
        characterColliderTrigger = transform.GetComponentInChildren<BoxCollider2D>();
        characterCollider = transform.GetComponent<BoxCollider2D>();

        GameObject[] movementButtons = GameObject.FindGameObjectsWithTag("MovementButtons");
        foreach (GameObject buttonObject in movementButtons)
        {
            Button button = buttonObject.GetComponent<Button>();
            if (button != null)
            {
                if (button.name == "MoveLeftButton")
                {
                    MoveLeftButton = button;
                }
                else if (button.name == "MoveRightButton")
                {
                    MoveRightButton = button;
                }
                else if (button.name == "JumpButton")
                {
                    JumpButton = button;
                }
            }
        }

        StartCoroutine(AssignButtons());
    }

绑定按钮代码

IEnumerator AssignButtons()
    {
        yield return new WaitForSeconds(0.5f);
    //JUMP BUTTON
        EventTrigger jumpEventTrigger = JumpButton.gameObject.AddComponent<EventTrigger>();
        EventTrigger.Entry jumpPointerDown = new EventTrigger.Entry();
        jumpPointerDown.eventID = EventTriggerType.PointerDown;
        jumpPointerDown.callback.AddListener((data) => { Jump(); });
        jumpEventTrigger.triggers.Add(jumpPointerDown);
    
    }

Jump函数代码

public void Jump()
    {
        if(canJump && !someoneOnTop)
        {
            rb.velocity = new Vector2(rb.velocity.x,25);
            canJump = false;
        }
    }

问题原因

  1. 重复绑定事件:每个Player脚本启动时,都会给同一个JumpButton添加EventTrigger组件,并把自己的Jump()方法绑定到按钮的点击事件上。最终按钮的回调列表里有两个Jump()方法,分别对应两个Player实例。
  2. 禁用脚本不清理回调:Player脚本被禁用时,只是暂停了它的生命周期函数(比如Update),但已经绑定到按钮事件里的方法引用不会自动消失。点击按钮时,依然会调用这两个Jump()方法。
  3. Jump方法未检查脚本状态:即使脚本被禁用,Jump()方法里没有判断当前脚本是否启用,所以只要被调用就会执行跳跃逻辑。

解决办法

方法1:在禁用脚本时移除回调,或在Jump里检查状态

  • 给Player脚本添加OnDisable()方法,移除按钮上的对应回调:
private void OnDisable()
{
    if(JumpButton == null) return;
    EventTrigger trigger = JumpButton.GetComponent<EventTrigger>();
    if(trigger == null) return;

    // 找到PointerDown类型的事件条目,移除自己的Jump回调
    foreach(var entry in trigger.triggers.Where(e => e.eventID == EventTriggerType.PointerDown))
    {
        entry.callback.RemoveListener((data) => Jump());
    }
}
  • 或者直接在Jump()方法开头判断脚本是否启用:
public void Jump()
{
    if(!enabled) return; // 脚本禁用时直接退出
    if(canJump && !someoneOnTop)
    {
        rb.velocity = new Vector2(rb.velocity.x,25);
        canJump = false;
    }
}

方法2:改用集中式的按钮事件处理

不让每个Player去绑定按钮,而是给按钮单独写一个处理脚本,点击时主动找所有启用的Player调用跳跃:

public class ButtonHandler : MonoBehaviour
{
    private Button jumpButton;

    private void Start()
    {
        jumpButton = GetComponent<Button>();
        jumpButton.onClick.AddListener(TriggerJump);
    }

    private void TriggerJump()
    {
        // 只找启用状态的Player脚本
        Player[] activePlayers = FindObjectsOfType<Player>(includeInactive: false);
        foreach(Player player in activePlayers)
        {
            player.Jump();
        }
    }
}

这种方式下,禁用的Player会被自动排除,无需额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 09:35:32