Шаблон для конструирования компонентов в Unity с C#

Программирование на C# в Unity требует огромного количества котельной плиты. Отчасти это связано с 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, чтобы уменьшить сложность, или какие-то другие хитрые трюки для автоматизации процесса написания этих функций?

Моя незаконченная попытка в настоящее время выглядит так с Xamarin editor-templates:

public static $classname$ Construct(){
}

Где $ classname $ вызывает функцию для получения имени текущего класса. Я не думаю, что на самом деле можно перечислить идентификаторы класса в заголовке функции.

Просто чтобы упредить людей: я знаю, что можно создавать классы, которые не являются производными от MonoBehaviour, но давайте предположим, что этот класс действительно нуждается в функциональности GameObject.

1 ответ

Я думаю, что вы ищете какой-то заводской шаблон.

В зависимости от контекста у меня есть 3 предложения:

1 сборные

Избегайте кода котельной плиты, поэтому так часто используются сборные конструкции и их создание. Это образец прототипа. Объявите набор сериализованных свойств и создайте экземпляр клона текущего прототипа (это то, что вы пытаетесь сделать с помощью кода).

2 Инициализировать в Awake

Если ваши объекты всегда инициализируются с определенным набором значений, инициализируйте их в 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++ сторона двигателя, и это двигатель, который владеет их временем жизни. Это де-факто ресурсы, которые вы запрашиваете и, возможно, выпускаете (как и другие ресурсы, такие как текстуры, сетки,...).

Другие вопросы по тегам