勇哥注:
对于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#脚本中实现多个脚本之间的互相调用。