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

Unity中跨类引用公共属性始终为Null,求正确实现方法

Unity中正确引用其他脚本属性的方法

问题根源

你当前代码的错误在于CameraManager的Awake方法中使用了gameObject.AddComponent<GameManager>(),这会给相机对象添加一个全新的GameManager组件,而非引用场景中已存在的、挂载在GameManager空对象上的那个组件。这个新创建的组件的lastTile属性自然未被赋值,所以始终为null。

正确的引用方式

1. Inspector面板手动赋值(最推荐)

这种方法直观且性能最优,适合固定存在的场景对象:

  • 修改CameraManager的代码,将gameManager字段设为public:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraManager : MonoBehaviour
{
    private Vector3 currPos;
    private Vector3 newPos;
    public float CamMoveSpeed = 5f;
    // 改为public,允许在Inspector中赋值
    public GameManager gameManager;

    private void Start() { }

    private void Update() {
        if (gameManager?.lastTile != null) {
            currPos = transform.position;
            Vector3 tilePos = gameManager.lastTile.transform.position;
            newPos = new Vector3(currPos.x + tilePos.x, currPos.y + tilePos.y, currPos.z + tilePos.z);
            transform.position = Vector3.Lerp(currPos, newPos, CamMoveSpeed * Time.deltaTime);
            Debug.Log("Moving Camera...");
        } else {
            Debug.LogWarning("gameManager.lastTile is NULL");
        }
    }
}
  • 在Unity编辑器中,选中挂载CameraManager的相机对象,在Inspector面板找到CameraManager组件,将场景中的GameManager空对象拖到Game Manager字段上即可。

2. 通过FindObjectOfType自动查找

适合场景中只有一个GameManager实例的情况,在初始化时查找:

private void Awake() {
    // 查找场景中第一个GameManager组件实例
    gameManager = FindObjectOfType<GameManager>();
}

注意:FindObjectOfType会遍历场景中所有对象,性能开销较大,仅在初始化(如Awake/Start)时调用,不要放在Update中。

3. 通过GameObject.Find按对象名称查找

如果你明确知道场景中GameManager对象的名称,也可以通过名称定位后获取组件:

private void Awake() {
    // 先找到名为GameManager的对象,再获取其GameManager组件
    GameObject gmObj = GameObject.Find("GameManager");
    if (gmObj != null) {
        gameManager = gmObj.GetComponent<GameManager>();
    }
}

注意:如果场景中有多个同名对象,GameObject.Find只会返回第一个找到的对象,需确保对象名称唯一。

4. 单例模式(适合全局管理类)

如果GameManager是全局唯一的管理类,可以将其设为单例,方便任何脚本随时引用:

  • 修改GameManager代码:
public class GameManager : MonoBehaviour {
    public GameObject tilePrefab;
    public GameObject startTile;
    public GameObject lastTile;

    // 单例实例
    public static GameManager Instance;

    private void Awake() {
        // 确保全局唯一
        if (Instance == null) {
            Instance = this;
            DontDestroyOnLoad(gameObject); // 可选,跨场景保留
        } else {
            Destroy(gameObject);
        }
    }
}
  • 在CameraManager中直接引用:
private void Update() {
    if (GameManager.Instance?.lastTile != null) {
        // 使用GameManager.Instance.lastTile进行操作
        currPos = transform.position;
        Vector3 tilePos = GameManager.Instance.lastTile.transform.position;
        newPos = new Vector3(currPos.x + tilePos.x, currPos.y + tilePos.y, currPos.z + tilePos.z);
        transform.position = Vector3.Lerp(currPos, newPos, CamMoveSpeed * Time.deltaTime);
        Debug.Log("Moving Camera...");
    } else {
        Debug.LogWarning("gameManager.lastTile is NULL");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:31:02