我正在Unity中构建一个Doodle Jump的克隆来自学基础并遇到问题。这场比赛的流程如下:
主菜单 ---(点击开始) - > 等级选择 ---(点击等级) - > 选定级别
玩家控制的对象实际上是在主菜单屏幕中创建的。它从一开始就可以控制GameObject.DontDestroyOnLoad()阻止它在每个场景转换中被销毁。进入所选级别后,相机会附加一个脚本,让它与你的角色一起移动。
我在LateUpdate方法中有一些处理相机移动的代码:
void LateUpdate () {
if (gameObject.transform.position.y > transform.position.y) {
Vector3 newPosition = new Vector3(transform.position.x, gameObject.transform.position.y, transform.position.z);
transform.position = Vector3.SmoothDamp(transform.position, newPosition, ref currentVelocity, smoothSpeed * Time.deltaTime);
}
}
但为了使其正常工作,我需要能够引用播放器(上面代码中的gameObject)。我最初是通过使用
来做到这一点的GameObject gameObject = GameObject.Find("Doodler");
在相同的LateUpdate方法中,但我没有理由每帧都找到Doodler,因为它不会被替换,直到你击中游戏结束。出于这个原因,我将GameObject.Find行移动到Start方法中,但它似乎没有找到Doodler,因此相机不会移动。任何人都可以帮忙吗?
编辑:
我现在将Start方法更改为:
private GameObject gameObject;
void Start() {
gameObject = GameObject.Find("Doodler");
Debug.Log("START Found the Doodler: " + gameObject.GetInstanceID());
}
而不是:
void Start() {
GameObject gameObject = GameObject.Find("Doodler");
Debug.Log("START Found the Doodler: " + gameObject.GetInstanceID());
}
这似乎有效。我猜第二种方法意味着LateUpdate无法访问gameObject?
最终解决方案:
虽然编辑中的代码确实有效,但它会发出警告,因为我调用了我的GameObject gameObject,这是一个预定义的对象,指的是脚本附加到的对象。最终代码应如下所示:
private GameObject doodler;
void Start() {
doodler = GameObject.Find("Doodler");
Debug.Log("START Found the Doodler: " + doodler.GetInstanceID());
}
答案 0 :(得分:3)
在您的问题编辑和您找到的修补程序之后,我仍然认为由于您当前的代码而值得为此问题留下答案。
显然,您需要先创建一个变量global,然后才能在另一个函数中访问它。你已经解决了这个问题,但是你还不知道还有一个很大的问题,当你试图从另一个函数访问本地函数中声明的变量时,你有一个错误。您应该收到原始代码的错误,但您没有。
您目前正在执行此操作:
private GameObject gameObject;
void Start()
{
gameObject = GameObject.Find("Doodler");
}
然后在LateUpdate
函数中使用它:
void LateUpdate ()
{
if (gameObject.transform.position.y > transform.position.y) {...}
}
<强>问题强>:
您的脚本派生自MonoBehaviour
,Behaviour
派生自Component
,然后派生自Component
。
在gameObject
脚本中,有一个名为&#34; GameObject
&#34;的变量。这是一种public GameObject gameObject { get; }
。声明如下:
MonoBehaviour
由于您的脚本派生自gameObject
,因此It refers to the
变量已经声明并可供您使用。 that this script is attached to.
{游戏物体{1}}。
事实上,现在,您应该收到类似这样的警告:
严重级代码描述项目文件行抑制状态 警告CS0108&#39; YourScript.gameObject&#39;隐藏继承的成员 &#39; Component.gameObject&#39 ;.如果想要隐藏,请使用new关键字。
怎么做:
您当然可以使用new
关键字隐藏它并删除该警告:
private new GameObject gameObject;
不要那样做。不要为你的变量命名&#34; gameObject
&#34;或已从MonoBehaviour
类中使用的任何名称。您将遇到此代码的许多问题。我已经看到了由此引起的几个问题,很难发现这就是问题所在。像下面这样的东西应该没问题:
private GameObject doodler;
void Start()
{
doodler = GameObject.Find("Doodler");
}
答案 1 :(得分:0)
处理此问题的一种(多种)方法是使用SceneManager.sceneLoaded回调(https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager-sceneLoaded.html)。因此,您可以在加载新场景后执行“查找”操作。
但是,如果您在上面引用的这个脚本已经在“Doodler”游戏对象上并且您获得了null ref错误,那么可能还有另一个问题。 MonoBehaviour类中的“gameObject”成员应始终是组件(MonoBehaviour派生类)附加到的gameObject。如果那个已经消失了,那么你就会强迫它以某种方式被摧毁,但是Monobehaviour仍然活着,这很奇怪。