勇哥注:
对于unity脚本之间的相互调用。
FindObjectOfType这个应该是unity封闭的反射功能,它需要加缓存,否则影响速度。最常用的方式应该还是公共变量引用和静态方法调用。
1. 通过公共变量引用
你可以在一个脚本中定义一个公共变量来引用另一个脚本的实例。然后在Unity编辑器中手动将这个引用设置好。
脚本A (ScriptA.cs):
using UnityEngine; public class ScriptA : MonoBehaviour { public ScriptB scriptB; // 引用ScriptB的实例 void Start() { if (scriptB != null) { scriptB.SomeMethodInScriptB(); } else { Debug.LogError("ScriptB reference is not set."); } } }
脚本B (ScriptB.cs):
using UnityEngine; public class ScriptB : MonoBehaviour { public void SomeMethodInScriptB() { Debug.Log("Method in ScriptB called."); } }
在Unity编辑器中,你需要将ScriptB
的实例拖动到ScriptA
的scriptB
字段中。
关于这一种方式勇哥图解一下,如下图:
在test1中要引用test2对象。可以先定义一个public 字段。
光这样肯定是不行的,因为运行时temp1会为null。
我们接下来在unity的编辑器中可以把这个属性赋值为test2这个脚本所在的对象即可。
这个时候你再运行,就会发现temp1有值了,不是null了。
2. 通过FindObjectOfType
查找
如果你知道某个脚本实例的类型,并且它在场景中只有一个实例,你可以使用FindObjectOfType
来查找它。
脚本A (ScriptA.cs):
using UnityEngine; public class ScriptA : MonoBehaviour { void Start() { ScriptB scriptB = FindObjectOfType<ScriptB>(); if (scriptB != null) { scriptB.SomeMethodInScriptB(); } else { Debug.LogError("ScriptB instance not found."); } } }
脚本B (ScriptB.cs):
using UnityEngine; public class ScriptB : MonoBehaviour { public void SomeMethodInScriptB() { Debug.Log("Method in ScriptB called."); } }
3. 通过事件和委托
使用事件和委托可以实现更松散的耦合,并且允许多个监听者响应一个事件。
脚本A (ScriptA.cs):
using UnityEngine; using System; public class ScriptA : MonoBehaviour { public event Action OnEventTriggered; void Start() { // 触发事件 if (OnEventTriggered != null) { OnEventTriggered(); } } }
脚本B (ScriptB.cs):
using UnityEngine; using System; public class ScriptB : MonoBehaviour { void Start() { ScriptA scriptA = FindObjectOfType<ScriptA>(); if (scriptA != null) { scriptA.OnEventTriggered += SomeMethodInScriptB; } } void OnDestroy() { ScriptA scriptA = FindObjectOfType<ScriptA>(); if (scriptA != null) { scriptA.OnEventTriggered -= SomeMethodInScriptB; } } void SomeMethodInScriptB() { Debug.Log("Method in ScriptB called by event."); } }
4. 通过静态变量或方法
如果某个方法或变量是全局的,你可以考虑将其定义为静态。
脚本A (ScriptA.cs):
using UnityEngine; public class ScriptA : MonoBehaviour { void Start() { ScriptB.SomeStaticMethodInScriptB(); } }
脚本B (ScriptB.cs):
using UnityEngine; public class ScriptB : MonoBehaviour { public static void SomeStaticMethodInScriptB() { Debug.Log("Static method in ScriptB called."); } }
注意事项
性能考虑:
FindObjectOfType
和GameObject.Find
在运行时查找对象会消耗性能,特别是在大型场景中。因此,尽量在Start
或Awake
方法中查找一次并缓存引用。空引用:在调用其他脚本的方法之前,确保引用不是
null
,以避免空引用异常。代码可读性:保持代码结构清晰,以便其他开发者能够轻松理解脚本之间的依赖关系。
通过以上方法,你可以在Unity的C#脚本中实现多个脚本之间的互相调用。

