英文:
Trying to reference a public property from another class/object and it's always null
问题
我有一个附加到名为GameManager的空对象的C#脚本。该脚本名为GameManager.cs
。以下是前几行:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
public GameObject tilePrefab;
public GameObject startTile;
public GameObject lastTile;
我有另一个附加到摄像机的脚本,名为CameraManager.cs
。我试图从GameManager
引用lastTile
,但它始终为null。以下是CameraManager.cs
的完整代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraManager : MonoBehaviour
{
private Vector3 currPos;
private Vector3 newPos;
public float CamMoveSpeed = 5f;
GameManager gameManager;
private void Awake() {
gameManager = gameObject.AddComponent<GameManager>();
}
private void Start() {
}
private void Update() {
if (gameManager.lastTile != null) {
currPos = gameObject.transform.position;
Vector3 tilePos = gameManager.lastTile.transform.position;
newPos = new Vector3(currPos.x + tilePos.x, currPos.y + tilePos.y, currPos.z + tilePos.z);
this.transform.position = Vector3.Lerp(currPos, newPos, CamMoveSpeed * Time.deltaTime);
Debug.Log("Moving Camera...");
} else {
Debug.LogWarning("gameManager.lastTile is NULL");
}
}
}
这个最新的版本基于这个Stack Overflow问题。之前的版本基于这个Stack Overflow问题。
引用另一个脚本/类的值的正确方法是什么?
英文:
I have a C# script attached to an empty object called GameManager. The script is GameManager.cs
. Here are the first few lines:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
public GameObject tilePrefab;
public GameObject startTile;
public GameObject lastTile;
I have another script attached to a camera called CameraManager.cs
. I'm attempting to reference lastTile
from GameManager
but it's always null. Here is the full code for CameraManager.cs
:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraManager : MonoBehaviour
{
// Start is called before the first frame update
private Vector3 currPos;
private Vector3 newPos;
public float CamMoveSpeed = 5f;
GameManager gameManager;
private void Awake() {
gameManager = gameObject.AddComponent<GameManager>();
}
private void Start() {
}
private void Update() {
if (gameManager.lastTile != null) {
currPos = gameObject.transform.position;
Vector3 tilePos = gameManager.lastTile.transform.position;
newPos = new Vector3(currPos.x + tilePos.x, currPos.y + tilePos.y, currPos.z + tilePos.z);
this.transform.position = Vector3.Lerp(currPos, newPos, CamMoveSpeed * Time.deltaTime);
Debug.Log("Moving Camera...");
} else {
Debug.LogWarning("gameManager.lastTile is NULL");
}
}
}
This latest iteration is based on this SO question. The previous iteration was based on this SO question.
What is the proper way to reference a value from another script/class?
答案1
得分: 1
我只需将属性设为public,然后在检视器中将其分配给GameManager对象的相应字段。我能够在awake
方法中移除所有内容。
英文:
All I had to do was make the property public and then assign it in the inspector by dragging the GameManager object to the corresponding field. I was able to remove everything in the awake
routine.
答案2
得分: 0
在你的相机类的awake
方法中,你使用AddComponent
方法为gameManager
分配了一个新实例的GameManager
脚本,这个新实例被创建在与相机管理类相同的对象上。这意味着相机管理类引用的GameManager
类实际上不是在GameManager
游戏物体上的那个。
通常,人们在处理GameManager
类时会使用单例结构。
基本上,你可以在GameManager
类中创建一个静态字段,类型为GameManager
,并在GameManager
类的Awake
方法中将其分配为自身的实例。类似这样:
public class GameManager : MonoBehaviour {
public GameObject tilePrefab = new GameObject("Name");
public GameObject startTile = new GameObject("Name");
public GameObject lastTile = new GameObject("Name");
public static GameManager Instance;
private void Awake(){
Instance = this;
}
}
然后,你可以在任何其他类中使用你的游戏管理器,使用这一行代码:GameManager.Instance.lastTile
。
英文:
In the awake method of your camera class you assign gameManager with AddComponent, that will create a new instance of the GameManager script on the same object that your camera manager class is on, meaning that the reference that your camera manager class has to the GameManager class is not the one that’s on your GameManager gameObject.
What people do usually with GameManager classes is to use a Signlton structure
Basically you can have a static field of type GameManager in your GameManager class and assign it to its own instance on the Awake method of your GameManager class. Something like this
public class GameManager : MonoBehaviour {
public GameObject tilePrefab = new GameObject("Name");
public GameObject startTile = new GameObject("Name");
public GameObject lastTile = new GameObject("Name");
public static GameManager Instance;
private void Awake(){
Instance = this;
}
}
And then you can use your game manager in any other class with this line GameManager.Instance.lastTitle
答案3
得分: -3
public class GameManager : MonoBehaviour {
public GameObject tilePrefab;
public GameObject startTile;
public GameObject lastTile;
}
看起来你从未将这些变量分配给任何内容,因此它们将始终为null。
要使它们不为null,你需要将它们分配给某些内容,例如:
public class GameManager : MonoBehaviour {
public GameObject tilePrefab = new GameObject("Name");
public GameObject startTile = new GameObject("Name");
public GameObject lastTile = new GameObject("Name");
}
或者你可以通过以下方式动态设置它们:
private void Update() {
gameManager.lastTile = new GameObject("Name");
}
英文:
public class GameManager : MonoBehaviour {
public GameObject tilePrefab;
public GameObject startTile;
public GameObject lastTile;
}
It doesnt look like your ever assigning these variables to anything, therefore they will always be null.
For them not to be null you need to assign them to something e.g.
public class GameManager : MonoBehaviour {
public GameObject tilePrefab = new GameObject("Name");
public GameObject startTile = new GameObject("Name");
public GameObject lastTile = new GameObject("Name");
}
Or you can set them dynamically by doing
private void Update() {
gameManager.lastTile = new GameObject("Name");
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论