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

Unity中如何让脚本仅在单个GameObject触发?建筑交互异常求助

解决Unity多建筑交互时Canvas同时激活的问题

问题根源

  1. 全局状态冲突:你依赖的BuildingManager.interactable是全局变量,只要玩家进入任意一个建筑的触发区,所有挂载BuildingScript的建筑都会检测到这个状态为true,按下E键时就会同时激活各自的Canvas。
  2. 触发逻辑错误:OnTriggerEnter2D中,非Player碰撞体进入触发区时会直接把interactable设为false,这会导致玩家交互被意外中断。
  3. 冗余代码:Update里调用enterBuilding时传入的Collider参数完全没被使用,属于无效逻辑。

修复方案

取消全局状态依赖,让每个建筑独立管理自己的交互状态:

  1. 给每个建筑添加独立的范围标记变量,替代全局的interactable
  2. 仅在玩家进入/离开当前建筑的触发区时,更新该建筑的交互状态
  3. 仅当玩家在当前建筑范围内时,才响应E键输入

修改后的完整代码

using UnityEngine;

public class BuildingScript : MonoBehaviour
{
    [SerializeField] private Canvas buildingUI;
    // 标记玩家是否在当前建筑的触发范围内
    private bool isPlayerInRange = false;

    private void Update()
    {
        // 只有玩家在当前建筑范围内,且按下E键时才激活UI
        if (isPlayerInRange && Input.GetKeyDown(KeyCode.E))
        {
            buildingUI.gameObject.SetActive(true);
            BuildingManager.canMove = false;
        }
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        // 只有Player进入时,才标记当前建筑可交互
        if (other.CompareTag("Player"))
        {
            isPlayerInRange = true;
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        // 只有Player离开时,才取消标记
        if (other.CompareTag("Player"))
        {
            isPlayerInRange = false;
            // 可选:离开时关闭当前建筑的UI
            buildingUI.gameObject.SetActive(false);
            BuildingManager.canMove = true;
        }
    }
}

额外优化建议

  • 如果需要关闭其他建筑的UI,可以在激活当前UI时,遍历所有BuildingScript实例,关闭除当前之外的其他UI,或者在BuildingManager里维护当前激活的UI引用,切换时关闭旧的。
  • 去掉了没用的building变量,如果你后续不需要用到可以直接删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:42:57