stride3d / stride

Stride Game Engine (formerly Xenko)
https://stride3d.net
MIT License
6.34k stars 920 forks source link

Allow for readonly field in the inspector #962

Open CodingMadness opened 3 years ago

CodingMadness commented 3 years ago

Is your feature request related to a problem? Please describe. The problem is more or less if u wanna just show custom readonly values as a better visual clarification so u can see tthem also in the inspector and have a better understanding what ur script exposes otherwise its harder sometimes to keep track of what ur script uses and what not so to say..

Describe the solution you'd like Its super useful to have the inspector serialize out public readonly fields (or in .net5.0 now also init fields) BUT to obviously grey out the textbox where they are shown so u cannot modify the values in them. But I also would rather allow it to be only like this via an attribute like [SerializeReadonlyField] maaybe not all developers want it that way but so u can ensure both in my opinion, since even in unity this was requested quiet heavily and ppl needed towrite ugly custom editorscripts for this kind of stuff.

Describe alternatives you've considered Alternative sadly is only doing it via custom scripts but this would be so awesome if allowed by default thru the engine and not the ugly unity way like u need to do it urself..

Additional context nope.

manio143 commented 3 years ago

Can you please go into more detail on the situations when you'd want to see a readonly field in the editor? I'm curious what is the motivating scenario here.

Note: in order for serialization to work correctly your script/component needs to have a parameterless constructor (importantly one that does not depend on the game running as the instances of the class may be constructed for asset management purposes), so the only readonly fields in that context should have static values assigned to them.

CodingMadness commented 3 years ago

What I would like to archieve with this actually is to allow the inspector to set a readonly field at editor-time, so u dont need to set it in code which makes for more robust and controlled code when u can even see readonly variables in the inspector and within code its still readonly behaviour so no further reassignments of values possible :)

manio143 commented 3 years ago

I see. This may be hard to achieve, because you would have to parse and modify the source file from the GameStudio on save. Moreover, readonly fields would be shared across component instances. This means properties for a given component would be collected from multiple assets (not just the scene but also the code asset). This is a pretty big change and likely not a very common scenario.

A suggestion would be to use a custom configuration (or a custom asset - see #30) for properties editable in the GameStudio that would be shared across multiple components. After reading the configuration you would assign it to a private variable and expose it in a readonly fashion via a get property.

CodingMadness commented 3 years ago

Moreover, readonly fields would be shared across component instances

Why is that? You mean ScriptComponents, right? So the readonly change would affect obviously, lets say, CharachterController-Script-Component

This means properties for a given component would be collected from multiple assets

This I dont understand tbh. What u mean from mulitple assets?

A suggestion would be to use a custom configuration (or a custom asset - see #30) for properties editable in the GameStudio that would be shared across multiple components. After reading the configuration you would assign it to a private variable and expose it in a readonly fashion via a get property.

This Idea tho I like alot, yea.

manio143 commented 3 years ago

Scripts aren't the only type of components you can create, that's why I use the more general wording here. Say you have a script component declared in MyScript.cs. This file represents a code asset for the editor. Whenever code changes, the editor recompiles your project and tries to update the instances of the component with new/modified fields/properties. Now you have a scene asset represented in Assets/MyScene.sdscene. When you open the scene in the editor it's processed into a graph of nodes (entities, components, properties) and the properties are displayed in the Property Grid when you select an entity or an asset. Right now I don't think there ever is a case when that graph is created for more than one asset. Also the graph is pretty much a tree, with some nodes being able to point at other nodes (e.g. when you reference another entity or asset), but those are only pointers and their contents aren't editable inline. Allowing modification of code assets via a property in a scene asset is rather tough. And when you modify that value it needs to get updated in all the graph nodes that reference it which may be many components across many scenes.

CodingMadness commented 3 years ago

Yea I see what u mean, But I think using the CustomAsset to keep track of those changes and then expose it as a getonly-Property would result in the same logic I want, right?

manio143 commented 3 years ago

Pretty much, yes. You can even do:

[DataMember]
private CustomAsset configuration;

public int Something => configuration.Something;

Which makes it possible to assign asset references in the GameStudio, but the access will be restricted in code.

CodingMadness commented 3 years ago

Nice, very nice :D

I only wonder how does this CustomAsset look insided the inspector tho, is it a seperate window? it behaves liek ScriptableObjects from unity3D, right?

CodingMadness commented 3 years ago

This is then also to beclosed right? i Have to test..

manio143 commented 3 years ago

If you read closely the discussion in the issue I linked to, custom assets aren't currently in the most comfortable spot yet, because there's not yet a way to reference them from GameStudio or AssetCompiler without your game taking a dependency on design time packages (which can be remedied with conditional compilation, but it's not a long term solution). I might at some point look into creating a proper quick custom asset, though it would be better to have it come from GameStudio extensibility, which is something heavily discussed on Discord (rewriting GS would take a lot of time and in the current form it's hard to extend it).

CodingMadness commented 3 years ago

Actually mate, we should think generally to implement a compelte ScriptableObject version of unity3D its such a super powerful took in a GameEngine u cant imagine.. (ofc u can but u get the idea:D) this must be done in an engine-based way.