0

在 Unity 中使用 C# 进行编程需要大量的样板文件。这部分归因于 C#,但也归因于引擎本身的设计决策。

我不能自己构造 MonoBehaviours 的事实意味着我需要编写如下代码来强制执行正确的初始化:

using System;
using System.Collections.Generic;
using UnityEngine;


public class MyClass : MonoBehaviour
{
    private int a;
    private float b;
    private string c;
    private List<int> lst;

    public static MyClass Construct (int a, float b, string c,List<int> lst)
    {
        //Boiler-plate stuff
        var go = new GameObject ();
        var mc = go.AddComponent<MyClass> ();

        /*
         * This part is fugly. The static method is setting
         * fields on the object. The responsibility to be
         * fully initialized after construction should
         * lie on the object. 
         * I could easily forget to set fields from the
         * outside.
         */
        mc.a = a;
        mc.b = b;
        mc.c = c;
        mc.lst = lst;

        return mc;
    }

    //Same as above, but this time without constructing a new GameObject.
    public static MyClass AddTo (GameObject go,int a, float b, string c,List<int> lst)
    {
        var mc = go.AddComponent<MyClass> ();

        mc.a = a;
        mc.b = b;
        mc.c = c;
        mc.lst = lst;

        return mc;
    }

}

有没有办法在 Xamarin Studio 中为此创建代码片段以减少样板,或任何其他花哨的技巧来自动化编写这些函数的过程?

目前,我未完成的尝试使用 Xamarin 编辑器模板如下所示:

public static $classname$ Construct(){
}

其中 $classname$ 调用一个函数来获取当前类的名称。我认为实际上不可能在函数头中列出类的标识符。

只是为了先发制人:我知道可以创建不从 MonoBehaviour 派生的类,但让我们假设这个类实际上需要 GameObject 的功能。

4

1 回答 1

2

我猜你正在寻找一些工厂模式。

根据具体情况,我有 3 条建议:

1 预制件

避免使用样板代码,这就是为什么使用预制件并实例化它们如此普遍的原因。这是原型模式。声明一组序列化属性并实例化当前原型的克隆(这就是您试图通过代码执行的操作)。

2 唤醒时初始化

如果您的对象始终使用一组定义的值进行初始化,请在 Awake 中而不是在构造函数中初始化它们。如果不是,那么每个组件在任何情况下都应该提供相关的构造函数重载(作为 init 方法,因为你不能依赖构造函数),或者被包装在工厂中。

3 使用拉姆达

如果您仍然喜欢或出于某些原因需要坚持过程对象创建,则可以避免为每个类声明方法,而只需传递一个负责初始化对象的方法。就像是:

public class Test : MonoBehaviour {
    public int foobar;
}

public static T CreateAndAttach<T>(Action<T> init)
     where T : MonoBehaviour
{
    GameObject go = new GameObject();
    T t = go.AddComponent<T>();

    init(t);
    return t;
}

//usage
CreateAndAttach<Test>(t => { t.foobar = 10; });   

我不能自己构造 MonoBehaviours 的事实意味着我需要编写如下代码来强制执行正确的初始化

事实是,它是位于引擎一侧的MonoBehaviours组件的 C# 包装器,并且拥有它们的生命周期的是引擎。它们是您要求并可能释放的事实上的资源(如纹理、网格等其他资源)。C++

于 2015-06-14T15:38:01.177 回答