1

I have this script that get the properties by names from a shader : At the bottom I'm changing one of the properties values by giving the property name: "Vector1_570450D5"

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.PlayerLoop;

public class ChangeShaders : MonoBehaviour
{
    public Material material;
    public float duration = 1;

    private List<string> propertiesNames = new List<string>();

    private void Awake()
    {
        material = GetComponent<Renderer>().material;

        var propertiesCount = ShaderUtil.GetPropertyCount(material.shader);

        for(int i = 0; i < propertiesCount; i++)
        {
            propertiesNames.Add(ShaderUtil.GetPropertyName(material.shader, i));
        }    
    }

    void Update()
    {
        var currentValue = Mathf.Lerp(-1, 1, Mathf.PingPong(Time.time / duration, 1));
        material.SetFloat("Vector1_570450D5", currentValue);
    }
}

but instead typing manual the property name I want to create a class for each property name so I will be able to type inside the SetFloat something like :

material.SetFloat(myProperties.Vector1_570450D5, currentValue);

Properties

In this case there are 5 properties so I want to be able to do :

material.SetFloat(myProperties.Vector1_570450D5, currentValue);

Or

material.SetFloat(myProperties.Color_50147CDB, currentValue);

So I thought to make this script with the attribute executeallways to create a editor script only for getting the properties and then to use the properties in this mono script like in the examples I gave.

0

1 Answer 1

1

Just to your title: You have a List<string>, not an array ;)


Before filling it with values you would need to initialize it. You can also do that together with the field declaration:

public List<string> names = new List<string>();

Even simpler would then be a proper constructor and e.g. using

public class MyClass
{
    public List<string> names = new List<string>();

    public MyClass(List<string> initialNames)
    {
        // This creates a new List<string> copying all elements of initialNames
        names = new List<string>(initialNames);
    }
}

And then use it like

var myClass = new MyClass(names);

If I understand correct you are further looking for a property like e.g.

public string this[int index] => names[i];

which would allow you to access a specific entry directly via

myClass[i];

instead of

myClass.names[i];
Sign up to request clarification or add additional context in comments.

7 Comments

This is working fine. If I wanted to make something more complicated for example that I will type myClass.1 or myClass.2 where the number 1 and 2 extracted from the 'i' variable. i.ToString() is the names for example "1" "2" "3" so to create properties of the numbers if I type myClass it will show the numbers as properties like myClass.1 myClass.2 so I can use the numbers later in other scripts as int's or convert them to strings. I don't want to loop over the List myClass.names but to get directly access to the properties.
@bendivonim What about using a Dictionary<int, string> then? Or do you mean a property like public int this[int index] => names[i]; so you could use myClass[i] instead of myClass.names[i]; ?
The second public int this[int index] => names[i];
How do I use this in the for loop in the awake ? public string this[int index] => names[i]; getting errors.
Nope this would be a property of MyClass and you wouldn't use it in the loop actually ... Maybe I still didn't fully understand your entire use case / goal :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.