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

Unity读取多个物体Vector3存入数组全为0的问题排查与解决

问题分析与修复方案

你的数组所有值都是0,主要有两个核心原因,咱们一个个拆解:

1. 变量初始化时机不匹配

你的Pos脚本里,pos字段是在Update()里每帧更新的,但GetPos的Start()方法只会在游戏启动时执行一次——此时Update()还没跑第一帧,所以你获取到的pos还是Unity默认的Vector3.zero(public字段未手动赋值时,默认就是全0向量)。

2. 隐性命名冲突坑

GetPos里的数组名字叫Pos,刚好和你的脚本类名Pos完全一致,这会让编译器产生歧义,虽然不一定直接报错,但很容易导致逻辑混乱,是非常不好的编码习惯。


修复步骤

第一步:修正命名冲突

先把GetPos里的数组改名,比如改成objectPositions,避免和类名重复:

public class GetPos : MonoBehaviour 
{
    // 改名规避冲突
    public Vector3[] objectPositions = new Vector3[41]; 
    // ... 其他代码
}

第二步:同步位置更新时机

根据你的需求选择对应的方案:

方案A:实时同步位置(推荐,适配你的Pos脚本逻辑)

把数组赋值逻辑移到Update()里,每帧更新最新位置,同时提前缓存组件引用避免性能浪费:

public class GetPos : MonoBehaviour 
{
    public Vector3[] objectPositions = new Vector3[41]; 
    // 建议直接在Inspector面板拖入物体,比Find更可靠
    public GameObject Go;
    public GameObject Mediterranean;
    // 提前缓存组件引用
    private Pos goPos;
    private Pos medPos;

    private void Start() 
    {
        goPos = Go.GetComponent<Pos>();
        medPos = Mediterranean.GetComponent<Pos>();
    }

    private void Update()
    {
        // 每帧同步最新位置到数组
        objectPositions[0] = goPos.pos;
        objectPositions[1] = medPos.pos;
        // ... 剩下39个物体的赋值逻辑
    }
}

方案B:仅获取初始位置

如果不需要实时更新位置,修改Pos脚本在启动时就初始化pos:

public class Pos : MonoBehaviour 
{ 
    public Vector3 pos; 

    private void Start() 
    {
        // 启动时直接获取初始位置,无需等待Update
        pos = transform.position; 
    } 

    // 如果不需要实时更新,Update可以直接删除
    // void Update() { pos = transform.position; } 
}

这样GetPos的Start()就能拿到正确的初始位置了。


针对41个物体的优化建议

手动写41次GameObject.Find和GetComponent太繁琐易出错,推荐批量处理方案:

给所有需要收集位置的物体添加同一个标签(比如PositionTarget),然后批量查找:

public class GetPos : MonoBehaviour 
{
    public Vector3[] objectPositions; 
    private List<Pos> posScripts = new List<Pos>();

    private void Start() 
    {
        // 批量查找带目标标签的物体
        GameObject[] targetObjects = GameObject.FindGameObjectsWithTag("PositionTarget");
        // 同步数组长度与物体数量
        objectPositions = new Vector3[targetObjects.Length];
        // 批量缓存组件引用
        foreach (var obj in targetObjects)
        {
            Pos posScript = obj.GetComponent<Pos>();
            if (posScript != null)
            {
                posScripts.Add(posScript);
            }
        }
    }

    private void Update()
    {
        // 批量更新数组位置
        for (int i = 0; i < posScripts.Count; i++)
        {
            objectPositions[i] = posScripts[i].pos;
        }
    }
}

这样不管物体数量多少,只要给物体加标签就能自动收集,维护起来方便很多。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:20:35