You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity C#中不引用脚本名动态跨脚本调用函数的问题

问题根源

你用Component类型声明sendTo变量,而Component是Unity所有组件的基类,它本身并没有testFunction这个自定义方法,所以直接调用会编译报错——即使Inspector里赋值了正确的组件,编译器也无法识别基类上的自定义方法。

解决方案

以下几种方法都支持在Inspector中动态赋值组件,满足你的动态关联需求:

方案1:使用接口(推荐,类型安全)

定义一个包含目标方法的接口,让所有需要被调用的脚本实现这个接口,既可以在Inspector中拖放任意实现该接口的组件,又能安全调用方法。

  1. 定义接口:
using UnityEngine;

public interface ITestable
{
    void testFunction();
}
  1. 修改simpleSwitch脚本实现接口:
using UnityEngine;

public class simpleSwitch : MonoBehaviour, ITestable
{
    public void testFunction()
    {
        Debug.Log("Working!");
    }
}
  1. 修改receiverScript的变量类型为接口:
using UnityEngine;

public class receiverScript : MonoBehaviour
{
    public ITestable sendTo;

    void Start()
    {
        if(sendTo != null)
        {
            sendTo.testFunction();
        }
    }
}
  • 优点:类型安全,编译时就能检查错误,性能最优。
  • 缺点:需要所有目标脚本都实现该接口,适合有统一方法规范的场景。

方案2:使用dynamic类型(快速实现,无类型检查)

把sendTo的类型转为dynamic,编译器会跳过类型检查,运行时直接调用方法。

修改receiverScript:

using UnityEngine;

public class receiverScript : MonoBehaviour
{
    public Component sendTo;

    void Start()
    {
        if(sendTo != null)
        {
            ((dynamic)sendTo).testFunction();
        }
    }
}
  • 优点:无需修改目标脚本,快速实现动态调用。
  • 缺点:无编译时类型检查,如果赋值的组件没有testFunction方法,运行时会抛出异常,性能略低于接口方案。

方案3:使用Unity的消息发送(反射调用)

利用Unity的SendMessage方法,通过反射调用目标组件的方法,只要组件存在该方法就能调用。

修改receiverScript:

using UnityEngine;

public class receiverScript : MonoBehaviour
{
    public Component sendTo;

    void Start()
    {
        if(sendTo != null)
        {
            sendTo.SendMessage("testFunction", SendMessageOptions.DontRequireReceiver);
        }
    }
}
  • 优点:完全不需要修改目标脚本,灵活性极高。
  • 缺点:反射调用性能最差,且方法名是字符串,拼写错误只会在运行时暴露,无法编译检查。

内容的提问来源于stack exchange,提问作者BenjaminSimon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:45:58