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