unity3d学习(四)unity的脚本之间的相互调用

勇哥注:

对于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的实例拖动到ScriptAscriptB字段中。


关于这一种方式勇哥图解一下,如下图:

在test1中要引用test2对象。可以先定义一个public 字段。

image.png

光这样肯定是不行的,因为运行时temp1会为null。

我们接下来在unity的编辑器中可以把这个属性赋值为test2这个脚本所在的对象即可。

image.png

这个时候你再运行,就会发现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.");  
    }  
}

注意事项

  1. 性能考虑FindObjectOfType 和 GameObject.Find 在运行时查找对象会消耗性能,特别是在大型场景中。因此,尽量在StartAwake方法中查找一次并缓存引用。

  2. 空引用:在调用其他脚本的方法之前,确保引用不是null,以避免空引用异常。

  3. 代码可读性:保持代码结构清晰,以便其他开发者能够轻松理解脚本之间的依赖关系。

通过以上方法,你可以在Unity的C#脚本中实现多个脚本之间的互相调用。




本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2024-10-24 13:50:53 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864