添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Im trying to create a button and multiple Sliders that update based each others values. Since every button and set of sliders is highly related I tried to call one method that would update the set, therefore I call one Update method for GenerateItem , rather than calling Update on each Object and making them reference each other.

Why am I getting the error above, and what is the "Unity" way to solve this? My program will likely have a lot of these sliders and Buttons so I would rather not code them all by hand.

GenerateItem must be instantiated using the ScriptableObject.CreateInstance method instead of new 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());

I tried:

GenerateItem o= ScriptableObject.CreateInstance(GenerateItem);

but couldn't figure out how to set the properties of the object.

I don't see the code of the ScriptableObjects.

But you either have to use CreateInstance(Type) which returns a ScriptableObject and cast the created instance to your type:

GenerateItem o = (GenerateItem) ScriptableObject.CreateInstance(typeof(GenerateItem));

Or simply use the typed version ScriptableObject.CreateInstance<Type>() which returns a Type and therefore doesn't require the typecast (I prefer this one)

GenerateItem o = ScriptableObject.CreateInstace<GenerateItem>();

Than you can set the properties as usual

 o.<some property> = <some value>;

Note that the properties/fields ofcourse have to be public for this solution.

Alternatively have some kind of

public void SetValues(string name, float value1, float value2, Button button, Slider slider1, Slider slider2, Text text)
    // Apply values
    <some property> = <some value>
    /* ... */

method inside of the ScriptableObjects so you can simply call

o.SetValues("OxyGen", 0.5f, 50f, a, c, b, d);

Another alternative (and I personaly like this one most) - Factory pattern

Only allow setting of the values on instantiation and protect them against later direct changes. Have a method in GenerationItem that takes completely care of the instantiation and setting the values

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;

So later in your class you just have to call

var o = GenerateItem.CreateInstance("OxyGen", 0.5f, 50f, a, c, b, d);

This makes sure values cannot be changed afterwards that easy. Depends on your needs.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.