Unity开发Pickup脚本仅单对象生效多对象UI文本不显示问题求助
问题根因
Pickup类的displayTxt被声明为静态变量,该类的所有实例共享同一份变量值,场景中所有挂载Pickup脚本的拾取物都会覆盖这个值。- 每帧所有
Pickup实例的Update方法按顺序执行,只要有一个拾取物超出玩家交互范围,就会把displayTxt赋值为空,只有最后执行Update且在交互范围内的拾取物的赋值会生效,因此表现为仅单个拾取对象能正常显示文本。
修复方案
方案1:由Tooltip全局查询范围内拾取物(逻辑简单,适合拾取物数量少的场景)
- 去掉
Pickup类中displayTxt的static修饰符,改为实例变量,同时删除Pickup的Update中给displayTxt赋值的相关逻辑。 - 修改
Tooltip脚本逻辑如下:
using UnityEngine; using UnityEngine.UI; public class Tooltip : MonoBehaviour { public Text textObject; public float interactRadius = 3f; // 和Pickup脚本的判定半径保持一致 public Transform playerTrans; // 拖拽玩家对象到Inspector面板赋值 void Update() { string showText = ""; // 检测玩家范围内所有碰撞体 Collider[] hitColliders = Physics.OverlapSphere(playerTrans.position, interactRadius); foreach (var collider in hitColliders) { Pickup pickup = collider.GetComponent<Pickup>(); if (pickup != null) { showText = $"Press E to Collect {pickup.item.ToString()}"; // 处理拾取逻辑 if (Input.GetKeyDown(KeyCode.E)) { Destroy(collider.gameObject); showText = ""; } // 仅显示最近的第一个拾取物提示,避免重叠 break; } } textObject.text = showText; } }
方案2:拾取物主动上报状态(性能更好,适合拾取物数量多的场景)
- 将
Tooltip改为单例模式,避免滥用静态变量:
using UnityEngine; using UnityEngine.UI; public class Tooltip : MonoBehaviour { public static Tooltip Instance; public Text textObject; [HideInInspector] public Pickup currentActivePickup; void Awake() { Instance = this; } public void SetTip(string content, Pickup pickup) { textObject.text = content; currentActivePickup = pickup; } public void ClearTip(Pickup pickup) { // 只有发起清空的拾取物是当前正在显示的拾取物时才执行清空,避免误清 if (currentActivePickup == pickup) { textObject.text = ""; currentActivePickup = null; } } }
- 修改
Pickup脚本逻辑如下:
using UnityEngine; public class Pickup : MonoBehaviour { public enum Items { Garbage, Dishes, Water, Milk } public Items item; public float radius = 3f; public Transform playerTrans; // 拖拽玩家对象赋值 void Update() { float dist = Vector3.Distance(playerTrans.position, transform.position); if (dist <= radius) { string tipText = $"Press E to Collect {item.ToString()}"; Tooltip.Instance.SetTip(tipText, this); if (Input.GetKeyDown(KeyCode.E)) { Tooltip.Instance.ClearTip(this); // 补充你的背包/销毁拾取物逻辑 Destroy(gameObject); } } else { Tooltip.Instance.ClearTip(this); } } }
注意事项
- 静态变量仅适合存储全局唯一的共享数据,不要用于存储每个实例独立的状态,否则会出现值被其他实例覆盖的问题
- 如果存在多个拾取物范围重叠的情况,可以额外添加距离排序逻辑,仅显示距离玩家最近的拾取物提示,避免文本冲突
内容的提问来源于stack exchange,提问作者Robin257
相关产品推荐
相关产品推荐

