【问题标题】:How can I address a script I don't know the type of?如何处理我不知道类型的脚本?
【发布时间】:2013-05-21 20:09:44
【问题描述】:

我的游戏使用多种不同的游戏模式,我想根据所选的游戏模式在场景开始时生成不同的 GameController 脚本。然后其他项目(例如 Enemies)将引用主 GameController,无论是 GameController_Mode1、GameController_Mode2 等。但是如果我不知道类型,我如何让其他对象引用它?

Unity iOS 需要严格的统一脚本类型,所以我不能使用鸭子类型来解决这个问题。

【问题讨论】:

    标签: unity3d unityscript


    【解决方案1】:

    您可以像在 C# 中那样执行此操作,polymorphism。从单个基本 Controller 类派生所有控制器。然后您的 GameController var 可以设置为派生控制器的任何实例化(参见下面示例中的 Start())。

    这是一个使用简单控制器的快速示例:

    #pragma strict
    
    var controller : MyController;
    
    class MyController  {
    var data : int;
    public function MyController(){
        this.data = 42;
    }
    public function Print(){
        Debug.Log("Controller: " + this.data);
    }
    }
    class MyController1 extends MyController {
    public function MyController1(){
        this.data = 43;
    }
    public function Print(){
        Debug.Log("Controller1: " + this.data);
    }
    }
    class MyController2 extends MyController {
    public function MyController2(){
        this.data = 44;
    }
    public function Print(){
        Debug.Log("Controller2: " + this.data);
    }
    }
    
    function Start () {
    controller = new MyController();
    controller.Print(); // prints Controller: 42
    
    controller = new MyController1();
    controller.Print(); // prints Controller1: 43
    
    controller = new MyController2();
    controller.Print(); // prints Controller2: 44
    }
    

    我假设您的游戏控制器共享函数名称,唯一的区别是每个函数中的代码。

    [更新]

    关于Heisenbug下面的评论:如果您的控制器是组件,您可以使用GetComponent获取基类控制器。

    基类(BaseController.js):

    class BaseController extends MonoBehaviour{
        public function Print(){
            Debug.Log("BaseController");
        }
    }
    

    扩展类(Controller1.js):

    class Controller1 extends BaseController {
        public function Print(){
            Debug.Log("Controller1: " + this.data);
        }
    }
    

    测试:

    var controller : BaseController;
    controller = gameObject.GetComponent("BaseController"); //.GetComponent(BaseController) also works
    controller.Print(); // will print "Controller1" if actual attached component is a Controller1 type
    

    【讨论】:

    • @Heisenbug 当您说从另一个脚本访问基类仍然很困难时,您是指另一个 GameObject 吗?因为我可以轻松地将我的基类移动到一个单独的脚本文件中,并且它可以按预期工作。
    • 哇!这完美地工作。非常感谢杰达克。我对使用“扩展”关键字不是很有经验。我已经尝试阅读它,但我认为这意味着它是基类 + 扩展类(向基类添加任何其他代码)是否正确?或者扩展类可以使用基类中存在的变量和函数吗?无论哪种方式,这都是非常强大的。我喜欢这个网站! :)
    • @Essential 子类(扩展类)可以定义它喜欢的任何变量和函数,但你不能直接调用它们,除非你知道你指向哪个子类,这是另一个问题。跨度>
    【解决方案2】:

    虽然看起来已经有一些很好的答案,但值得一提的是 Unity 的 SendMessage 系统。如果您需要做的只是调用另一个对象 SendMessage 上的函数,那么这是一种非常简单的方法。

    http://docs.unity3d.com/Documentation/ScriptReference/GameObject.SendMessage.html

    简而言之,您可以使用以下语法:

    TargetGameObject.SendMessage("targetFunction", argument, SendMessageOptions.DontRequireReceiver);
    

    您还可以使用 SendMessage 从 C# 脚本调用 javascript 函数,反之亦然。

    【讨论】:

    • 谢谢 Luke,我没有想到 SendMessage()。将是一个简单的选择,尽管我认为性能显然比 Jerdak 的方法慢。
    • Jerdak 的解决方案肯定会表现得更好,但对于快速的东西,SendMessage() 非常棒。
    猜你喜欢
    • 2016-09-25
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多