使用 ScriptableObject.CreateInstance 实例化

Ril*_*n42 3 unity-game-engine

我试图创建一个按钮和多个滑块,它们根据彼此的值进行更新。由于每个按钮和滑块集都高度相关,因此我尝试调用一个可以更新该集的方法,因此我为 调用一个 Update 方法GenerateItem,而不是对每个对象调用 Update 并使它们相互引用。

为什么我会收到上述错误,解决此问题的“Unity”方法是什么?我的程序可能会有很多这样的滑块和按钮,所以我宁愿不手工编码它们。

必须使用 ScriptableObject.CreateInstance 方法而不是新的GenerateItem 实例化GenerateItem

void Start () {

    Button a = ((GameObject)Instantiate(prefabButton)).GetComponent<Button>();
    Slider b = ((GameObject)Instantiate(prefabCreationSlider)).GetComponent<Slider>();
    Slider c = ((GameObject)Instantiate(prefabCapacitySlider)).GetComponent<Slider>();
    Text d = ((GameObject)Instantiate(prefabText)).GetComponent<Text>();
    items.Add(new GenerateItem("OxyGen", 0.5f, 50f,a,c,b,d));
}

// Update is called once per frame
void Update () {
    items.ForEach(a => a.BtnUpdate());
}
Run Code Online (Sandbox Code Playgroud)

我试过:

GenerateItem o= ScriptableObject.CreateInstance(GenerateItem);
Run Code Online (Sandbox Code Playgroud)

但无法弄清楚如何设置对象的属性。

der*_*ugo 7

我没有看到 ScriptableObjects 的代码。

但是您要么必须使用CreateInstance(Type)which 返回 aScriptableObject并将创建的实例强制转换为您的类型:

GenerateItem o = (GenerateItem) ScriptableObject.CreateInstance(typeof(GenerateItem));
Run Code Online (Sandbox Code Playgroud)

ScriptableObject.CreateInstance<Type>()或者简单地使用返回 a 的类型化版本Type,因此不需要类型转换(我更喜欢这个)

GenerateItem o = ScriptableObject.CreateInstace<GenerateItem>();
Run Code Online (Sandbox Code Playgroud)

您可以照常设置属性

 o.<some property> = <some value>;
Run Code Online (Sandbox Code Playgroud)

请注意,对于此解决方案,属性/字段当然必须是公开的。


或者有某种

public void SetValues(string name, float value1, float value2, Button button, Slider slider1, Slider slider2, Text text)
{
    // Apply values

    <some property> = <some value>
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

ScriptableObjects 内部的方法,因此您可以简单地调用

o.SetValues("OxyGen", 0.5f, 50f, a, c, b, d);
Run Code Online (Sandbox Code Playgroud)

另一种选择(我个人最喜欢这个)——工厂模式

仅允许在实例化时设置值并保护它们免受以后的直接更改。有一个方法GenerationItem可以完全处理实例化和设置值

public static GenerateItem CreateInstance(string name, float value1, float value2, Button button, Slider slider1, Slider slider2, Text text)
{
    // Let the method itself take care of the Instantiated
    // You don't need "ScriptableObject." since this class inherits from it
    GenerateItem o = CreateInstance<GenerateItem>();

    // Then directly set the values
    o.<some property> = <some value>;

    /* .... */

    return o;
}
Run Code Online (Sandbox Code Playgroud)

所以稍后在你的课堂上你只需要打电话

var o = GenerateItem.CreateInstance("OxyGen", 0.5f, 50f, a, c, b, d);
Run Code Online (Sandbox Code Playgroud)

这确保了之后不能轻易更改值。取决于您的需求。