我是Unity和C#的新手,希望您能帮助我解决问题。我无法在线找到解决方案。
我正在研究在youtube上找到的寻路教程。我想从另一个脚本更改我的搜寻器克隆中的目标。我可以通过以下方式更改速度:
obj.GetComponent<Unit> ().Speed =20;
效果很好,但是我不知道如何更改目标。我可以在运行时通过从资产中将另一个目标拖放到检查器字段上来手动更改目标。如何使用另一个脚本中的代码执行相同的操作?
我尝试过:
obj.GetComponent<Unit> ().Target = John (UnityEngine.Transform);
但我收到此错误:
Assets / Scripts / spawner.cs(23,38):错误CS0103:名称“ John”在当前上下文中不存在
和
Assets / Scripts / spawner.cs(23,57):错误CS0119:表达式表示“类型”,其中期望有“变量”,“值”或“方法组”
当我要求时:
Debug.Log (obj.GetComponent<Unit> ().Target );
我明白了:
Peter(UnityEngine.Transform) UnityEngine.Debug:Log(对象) spawner:FixedUpdate()(位于Assets / Scripts / spawner.cs:24)
您能帮我正确的语法吗?
我的脚本是:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class spawner : MonoBehaviour {
public Transform spawnPos;
public GameObject spawnee;
GameObject obj;
GameObject objt;
void Update () {
if((Input.GetKey (KeyCode.G))) {
Instantiate(spawnee, spawnPos.position, spawnPos.rotation);
}
}
void FixedUpdate () {
if((Input.GetKey (KeyCode.H))) {
obj = GameObject.Find ("Seeker(Clone)");
obj.GetComponent<Unit> ().Speed =20;
obj.GetComponent<Unit> ().Target = John (UnityEngine.GameObject);
Debug.Log (obj.GetComponent<Unit> ().Target );
}
}
}
答案 0 :(得分:2)
Popup
变量是Transform
的一种,您想在运行时通过脚本对其进行更改。
根据您的屏幕截图,您有一个名为“ John”的游戏对象和另一个名称为“ Peter”的游戏对象,该对象未在屏幕截图中显示,而是在代码中显示。您正在寻找GameObject.Find
函数。找到彼得或约翰对象,获取Target
,然后将其分配给transform
。这比您想象的要容易。
您的目标
Target
找到Peter和John游戏对象:
public Transform Target;
将目标设置为Peter
GameObject peterObject = GameObject.Find("Peter");
GameObject johnObject = GameObject.Find("John");
将目标设置为约翰
obj.GetComponent<Unit> ().Target = peterObject.transform;
答案 1 :(得分:1)
因此,如果我正确理解了您的代码,则您尝试将一个新的Object实例化,并将Target
设置为此新对象Transform
的组件。
在您的代码中,您还会遇到另一个错误:
按下键时 here不断地每帧发射!我认为您宁愿使用Input.GetKey
,因此每次点击仅触发一次。
然后,我建议您不要在任何Find
方法中调用类似GetComponent
或Update
之类的东西。它们非常昂贵。最好添加其他变量以一次存储这些引用,并在以后重用。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class spawner : MonoBehaviour
{
public Transform spawnPos;
public GameObject spawnee;
private GameObject obj;
// private GameObject objt;
// here we store and re-use the Unit component reference
Unit unit;
// You need an additional variable for the Object you instantiate
GameObject lastInstantiatedObject;
private void Awake()
{
// do those expensive methods already and only once in the beginning
obj = GameObject.Find ("Seeker(Clone)");
unit = obj.GetComponent<Unit>();
}
private void Update () {
// use GetKeyDown to fire only once per click
if((Input.GetKeyDown (KeyCode.G)))
{
// store a reference to the instaiated object so you can access it later
lastInstantiatedObject = Instantiate(spawnee, spawnPos.position, spawnPos.rotation);
}
}
privte void FixedUpdate ()
{
if((Input.GetKeyDown (KeyCode.H)))
{
// unit was set already in Awake so we can reuse the reference
// anyway just in case the object was not there yet while Awake
// add a little check
if(!unit)
{
Awake();
}
// if unit is still not set you have an error and should not go ahead
if(!unit)
{
Debug.LogError("For some reason unit could not be set!", this);
return;
}
unit.Speed =20;
// Before going on you should add a similar check for the lastInstantiatedObject variable
if(!lastInstantiatedObject)
{
Debug.LogError("No object instanitated so far or it was destroyed again!", this);
return;
}
// Target is of type Transform
// Usually to get a component you would have to call
// lastInstantiatedObject.GetComponent<TypeOfComponent>()
// but Trasnform is an exception. Since every GameObject has a Transform
// component, you can use the shortcut lastInstantiatedObject.transform
unit.Target = lastInstantiatedObject.transform;
Debug.Log (unit.Target);
}
}
}