ruccho / UniTyped

UniTyped is a source generator that allows typed access to data such as SerializedObjects, material parameters, tags and layers.
MIT License
167 stars 5 forks source link

Access array elements? #5

Closed whynames closed 11 months ago

whynames commented 11 months ago

I have an array of gameobjects, with the generator, can I access objects by their name?

Like I have GameObject[] gameobjects; in some code

Lets say there is a gameobject called "lion" in this array.

And I access this object with gameobjects.lion ?

ruccho commented 11 months ago

Lists and arrays can be accessed with IEnumerable. They can be enumerated with foreach and LINQ. First() and FirstOrDefault() can be used to query GameObjects by name.

using System.Linq;
using UnityEngine;
using UniTyped;

#if UNITY_EDITOR
using UniTyped.Editor;
#endif

[UniTyped]
public class SomeObject : MonoBehaviour
{
    public GameObject[] gameObjects;

#if UNITY_EDITOR
    private void M()
    {
        var view = new UniTyped.Generated.SomeObjectView();

        SerializedPropertyViewObjectReference<GameObject> lionElement =
            view.gameObjects.FirstOrDefault(element => element.Value.name == "lion");
        GameObject lion = lionElement.Value;
    }
#endif
}
whynames commented 11 months ago

I meant can I access it without using strings? Like accessing a property without findproperty, directly with a typed value. Maybe with some additional code to make it possible. Like gameobjects.lion or gameobjects.bird

ruccho commented 11 months ago

Source generators basically run with script compilation so they shouldn't depend on dynamic change of data. It is difficult to determine statically the names of GameObjects present in the array, and different instances of the target type could have differently named GameObjects.

Syntaxes such as gameObjects.lion may be able to be executed with C#'s dynamic feature, but it provides no typed access and is essentially no different than using LINQ. (rather there is the cost of dynamic code generation)

whynames commented 11 months ago

Array won't change during runtime, I wanna generate this during compile time

ruccho commented 11 months ago

Roslyn source generators must be able to run without an instance of the Unity editor because IDEs also run these generators separately. Since they must read Unity serialized data without any Unity editor APIs, the only way to do that is to parse serialized YAMLs through the file system. The source generator would have to read all the serialized files related to the project to find serialized data. They can be stored in scene files, scriptable objects, and even in AssetBundles. Multiple assets may have different content of same serializable types and we must somehow determine which data to use to generate the code. I think there are many problems to provide consistent ways to do that.

It is more appropriate to run self-implemented source generators on Unity with APIs such as AssetModificationProcessor. UniTyped is not appropriate because it is based on the roslyn source generator API.

whynames commented 11 months ago

Thank you very much. Finally, do you know any article or post that I can learn about it

ruccho commented 11 months ago

This seems good example of code generation with AssetModificationProcessor.

Auto compile-time support for Unity Animation Parameters by Paul Marsh https://pauliom.medium.com/auto-compile-time-support-for-unity-animation-parameters-e5edd0a6016e