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

Unity开发Pickup脚本仅单对象生效多对象UI文本不显示问题求助

问题根因
  • Pickup类的displayTxt被声明为静态变量,该类的所有实例共享同一份变量值,场景中所有挂载Pickup脚本的拾取物都会覆盖这个值。
  • 每帧所有Pickup实例的Update方法按顺序执行,只要有一个拾取物超出玩家交互范围,就会把displayTxt赋值为空,只有最后执行Update且在交互范围内的拾取物的赋值会生效,因此表现为仅单个拾取对象能正常显示文本。
修复方案

方案1:由Tooltip全局查询范围内拾取物(逻辑简单,适合拾取物数量少的场景)

  1. 去掉Pickup类中displayTxt的static修饰符,改为实例变量,同时删除Pickup的Update中给displayTxt赋值的相关逻辑。
  2. 修改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:拾取物主动上报状态(性能更好,适合拾取物数量多的场景)

  1. 将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;
        }
    }
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:27:01