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


少有人走的路

















