#↕️┃editor-extensions
1 messages · Page 89 of 1
none of that uses GraphViewEditorWindows, they all just create an EditorWindow
I guess look at the source to see what it actually does? Maybe that will give yo a better idea of how/when to use it.
assigning my material to a custom inspector.
How do I show it's properties in the custom inpsector?
So, need some help with a blocking point:
Im working on a property drawer, specifically one that renders a List<T>
To add to that list, I am using AdvancedDropdown. In order to add to the list on item selected, I created a delegate that was publicly accessible.
I found that if I tried to add to the list by assigning an inline method to the delegate, it didnt work. It would run, and call debugs etc, but it would never add to the list. I think this is due to the nature of SerializableObjects (adding to the list is done by adding like this:
SerializedProperty newAction = prop.GetArrayElementAtIndex(prop.arraySize++);
So, I created a List<string> at class level in the PropertyDrawer, and added to it when an item was selected. Then, during every OnGUI, I add whatever items are in the class list to the property list, and clear it.
In my initial tests, i thought this was working fine, but now that I have two instances of the property in the inspector (the property drawer is for a list of lists...), whenever I add an item, its only adding it to the first property, not the one I want it to add to.
All relevant code here, mainly in SequenceEditor.cs https://github.com/DraconInteractive/SequenceSystem.git
ah, fixed it 🙂
Why can't get I get the initial opening of an editor window to dock to the desired type? It's only upon closing that window a new one opens that docks correctly
I'm using things like HasOpenInstances to make sure there isn't an instance opened up somewhere that has to be closed first
nvm, I saved in instance in my main script and used if (!mainEditorWindow.docked) mainEditorWindow.Close();
so basically having it to do the auto close for me... however, if I can get it to initialize properly would rather do that just for ease of mind
How are you opening the window? That changes a lot of how it works.
I also don't really get what you are trying to do, so if you want to share your code too I would be happy to see if I could help you with it 🙂
What I'm doing right now has been with a bunch of test windows, so didn't really thing about sharing, give me a min
Basically, I'm trying to remove using GUILayout.Toolbar as my way of changing between different editor extensions I setup and was looking at just having new things open up as docked tabs instead. However, struggling with finding a way to deal with ShowUtility still. FocusWindowIfItsOpen() almost solved some of my problems when used in Update(), but, it was causing the window to focus even when not in Unity.
So you just want a window to open as a tab of another window?
Yeah, basically
It worked the same as GetWindow was, it wasn't opening it docked
but if I closed window through the above method even with createwindow it would open backup as docked
What...? doing CreateWindow<MainEditorWindow>(typeof(MyEditorWindow)).Show(); didn't work?
I didn't do it as .show(). I just did CreateWindow<MainEditorWindow>(typeof(MyEditorWindow)); let me try
nvm don't need to do Show() since it already does it.
There has to be an instance of one of the provided types already open for it to dock to it.
That was something I was wondering. Is Update() going off before MyEditorWindow is even going? Guess I could do a debug.log to check. Maybe I should do this OnOpen();
or check if an instance exists of MyEditorWindow
void Update()
{
if (GetWindow<MyEditorWindow>(false, "MyEditorWindow", true))
{
if (!HasOpenInstances<MainEditorWindow>()) CreateWindow<MainEditorWindow>(typeof(MyEditorWindow));
}
}
worked
change the createwindow back to getwindow due to the extra functionality that comes with it.
Extra functionality?
Just GetWindow will check for an instance of the editorwindow first before creating a new window if one doesn't exist. So, just the extra, most likely unnecessary, check
@gloomy chasm just since you help me a lot figured I'd show you something for fun I've been doing. I wanted to have more control over my enums, so put this together to not only do that, but, to give me more learning of the unity editor fun things. Have this all done through scriptable objects now instead of actual enums
Nice. SOs are great!
This is obviously way easy to do without an editor, but, my goal was to prevent someone not familiar with scriptableobjects and the organization already in a project to be able to create and remove enums without having to actually look at the project hierachy
and doing it through SOs
SceneView.cameraDistance cannot be modified?
It says cameraDistance has no setter
And?
It won't let me modify or set the value
Oh, Rider says it has no setter, Unity's console says it's read only
Is there some way that I don't know to just ignore that fact and somehow set it anyways?
Reflection to get the backing field. But there is a reason that things are read only. I would look at the source code to see what is going on. I would imagine that it is set internally every frame, so setting it your self would be pointless.
I don't think I have access to the source code
How else would I go about adding zoom functionality?
I could move the pivot point back to "emulate" that but then I can't orbit a selected object
It is in the pinned messages in the channel.
Oh, well, I see.
That still doesn't really help though
How not?
well, I won't be able to use whatever I may find there anyways, and I'm not even advanced enough at programming to figure it out in the first place
What is it that you are trying to do in this case?
Set a custom zoom sensitivity and prevent it from zooming in too close
This is how fast it zooms, just if I so much as touch the scroll
Because my mouse does fine scrolling, eg, not line-per-line (which I assume unity expects), so every tiny little tap at it causes the zoom to go flying
Is there any other way whatsoever to modify the zoom on the camera?
@gloomy chasm I really hope I'm not bothering you by pinging, but you're the best at helping me
All good. I am looking a it now, but take a look at this as well.
https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/SceneView/SceneViewMotion.cs
@crimson estuary Checkout line 481 and down to 496
okay, lemme give that a look
well this looks like it does the zooming, and it will zoom to where the mouse is hovering, but that's all I can glean
I'm not sure what to tell you right now. There is sceneView.cameraSettings you could look in to.
I looked at that, it only contains things like fov or clipping
I need it to zoom towards center, as I want it to keep the pivot point locked to the focused object
Alright, maybe a macgyver solution is needed. Is there any way to emulate me pressing mouse buttons in script?
I suppose I could just use the scroll event and then send a fake one at a custom interval
Wait, so you just need it to zoom towards the center of the screen?
Yeah, I need it to zoom in and out to the focused object
Then that code is literally what you want.
The bit you linked?
That's !zoomTowardsCenter, I assume that's for if you're not focused on anything it'll zoom to where you've moused over
But that would also break the focused object pivot point
let me check out earlier parts of this
They would probably handle the centerpoint zooming
This code is actually not bad for what it is, and well structured making it easier to look through.
Is this the actual source code or is this decompiled?
much comment lack \s
It's actualy pretty clear
Well, I see how it gets a zoom delta, but not quite sure how it applies it. And if I could, none of this is accessible, unless I'm missing something?
So what I can figure is that view.size is the "zoom"
Yeah, I was just showing you this so that you could learn how to do it your self from it.
But all of this stuff is inaccessible, isn't it?
I see. Well, then I need to access view.size, which the Rome that all roads lead to
I'll see if that's accessible
Oh! There's SceneView.size
Can I ask not for technical help, but an opinion?
What's a reasonable cutoff distance for zooming closer? I currently am at 0.1 but that will clip me clear into a default cube. But I'm afraid if I make it too far like 1 or 0.5 it'll be too far for fine details that I (or whoever might want to use this) to use
Another opinion is if I should have separate behavior for orthographic mode. I don't know if it'll be necessary to orbit so much in that mode. I know 2D mode should not orbit at all, but should orthographic be the same?
hi i have this text in a txt file but when i preview it in unity it gets displayed weirdly. does anybody know of a way to display it normally or stop the weird resizing?
Looks like wordwrap
Try make the window a bit wider?
Oh wait, no
it's tab size not being consistent
Maybe use spaces instead of tabs?
Can you send me the file?
Well it shows properly in the chat lol
yeah lmao
Displays properly for me too
it displays properly in notepad but just not in unity editor
Breaks when I don't use a monospace font
aw okay
np, sorry I couldn't solve it
nws
Okay, my program works now almost 100%, but I realized an issue. Because I'm always overriding the orbit of the camera, it breaks my ability to click the 3D Compass gizmo. Is there any way to check if I'm moused over that gizmo?
I think I'm done! I fixed the issue, and I think the whole plugin is done and ready!
hey i know this might be a little bit offtopic for here, but i trust/love you guys here in editor extensions, when i'm reading in an assembly with mono.cecil like AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(asmFile); then i do some stuff and i want to write it back out
i can do some stuff, successfully, and stepping through with debugger shows cherries all the way through, but then i can't like, write it back out
write it back
the modification part (according to locals in debugger) is working fine, iterates through what i need to do... i just can't seem to save it back out and the errors are not helping me
i think i might need some kinda ____stream or somethign
i did it
Advanced question. Is there so way to read text from a IMGUI window? Or I guess read controls? Is there any way to hide certain controls?
(of course no access to the actual code)
Maybe look at the IMGUI debugger
Read might be a hard task, but you need to look at how does the debugger.
Hide is impossible, since you are reading it it is drawn already
Hi, I was hoping someone might be able to help me out here. I'm following this from the documentation to make a custom VisualElement to use with UIBuilder:
And it works fine when adding via UI Builder.
but if i try to add it using:
VisualElement veTest = new MyElement();
root.Add(veTest);
It spawns but without any of its children despite LOGGING a childcount
have a look at the UI Toolkit debugger, it's quite handy for that sort of thing
What is root in this case?
@waxen sandal @onyx harness Yeah, took a quick look at the Debugger last night and I may be able to get label names with it. Thanks!
It looks like it also gives you the Rects so while I can't hide them, maybe I can draw over them and do a fake 'grayed-out' which is second best.
A project for next weekend though.
Over drawing is what the debugger does already, but it's so far from hiding
I already feel you are wasting your time if your real purpose is to hide and not just learn about the mechanic under the hood
How come when I use VSCode or Visual Studio community 2019 intelisense (did i spell that right) wont work, ive switched editors and installed the C# VSCode extention but it still wont work
is this the right channel to ask?
I may very well be! But I have fun trying to find out the limits of what can be done 😛
It's not and it's because you didn't set them up properly. #💻┃code-beginner pins has guides
ok
A great wizard in the becoming 🧙♂️
Oh I had a fun imgui debugger issue today, the overlays weren't matching the actual clickable area 🤔
Or drawing area
Root is my ui window, but it can also be any VE.
I found my problem, when spawning it in code with constructor, i have to use the constructor in my derived class to add children. The example i linked and followed ONLY fires when adding ur element via the UI Builder apparently
I also found that constructor works fine for UI Builder, so unless im specifically trying to add attributes for use in uxml or UI Builder inline, i can ignore that example entirely
okay guys i think u heard this question 100 times, so i am sorry to bother u. my autocopletion in visual studio code is not working. How to fix that. the obvios problems do i already have fixed
@lilac thorn from Visual Studio you can try:
Build > Rebuild Solution
i use visual studio code, i dont even have the build option
if that fails, you can also try browsing to your project folder, deleting Library, obj, temp and any VS files like *.sln, .vs etc
delete everything but Assets, Packages, ProjectSettings
maybe keep User Settings too if you have that folder
seeing as you're in VSCode, i have one question
did Unity/VSCode autocompletion ever work for you on your current workstation?
you may need an extension, i recommend "Unity Code Snippets"
i installed unity yesterday, so no i didnt
okay, but i tryed a lot of these extensions and nothing worked
i recommend this one
that i work in 2d doesnt do anything right?
sorry if this is a terrible question, but other people who have had similar problems have made this mistake... you ARE opening VSCode by double-clicking on a script in Unity yeh? I've seen people try to open CSharp files from VSCode directly using "Open" etc
no xd. just doble click in unity on the file
algud...
hm i can only imagine it may just be that you need snippets extension....
oh.... VSCode doesnt give you any .NET warnings in the debugger by any chance?
no it doesnt
following these guidelines, you gotta have .Net core sdk installed etc
https://code.visualstudio.com/docs/other/unity
and i work for one word rn but then stoped again
oh...... thats even weirder :S
yes
okay every time i open vsc i works for one sec
shall i maybe call u so u can see it?
well... i may be out of ideas... my usual list of troubleshooting includes
- deleting trash files like Library, .sln, .vs, temp etc
- checking external tools is set right
- code snippets installed
- .net installed
ah i cant at the moment, ppl sleeping nearby, its ok i get what you're saying, but dont think im familiar with that particular issue :S
okay thank u anyways, i will write again if something changes
^^
do you happen to be on a network managed PC?
when im at work in the office, i get all kinds of issues with VS and VS Code cos of how managed our systems are by IT
no private pc at home
hrm
@stuck olive No memes/reaction gifs, please.
my bad, soz
Failed to load project file 'd:\Programmieren\Unity Projekte\Rimworld\Unity.InternalAPIEditorBridge.001.csproj'.
d:\Programmieren\Unity Projekte\Rimworld\Unity.InternalAPIEditorBridge.001.csproj
c:\Users\Morten.vscode\extensions\ms-dotnettools.csharp-1.23.12.omnisharp\1.37.10.msbuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(1216,5): Error: The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks
so thats a warning i get
and then 100 of this
Attempted to update project that is not loaded: d:\Programmieren\Unity Projekte\Rimworld\UnityEngine.TestRunner.csproj
ahaha xd. i just need a name
Error: The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version
this is pretty key ^
so i have seen people go through the motions and install .NetFramework and Core, but I've usually found success by giving it the version that it wants as well so you may need to install that specific version
the developer pack there may get you one step further
okay and were to safe that? does it matter?
doesnt matter where ya save it, when you run the installer it will go to the right place
maybe close unity and VSCode as you do this
once it finishes, reopen project, try open script again, pray for best
nope not realy
ah ok, well thats good news either way
but ty so much
sectionCompleted.boolValue = true;
EditorGUILayout.BeginHorizontal();
sectionCompleted.boolValue = EditorGUILayout.Toggle(sectionCompleted.boolValue, GUILayout.Width(10f));
EditorGUILayout.EndHorizontal();
serializedObject.ApplyModifiedProperties();
Question about seriealized properties!
How come that when I give a value to a seriealized property, then draw the toggle that uses this seriealized property, this value doesn't change when using the toggle?
It must come from how seriealized properties work, but i have no clew why it does this 🤷♂️
Because you are setting it each frame before drawing it.
oh so my value is indeed changed, but just overrided the next frame?
ohh all right i see
How can I check inside an EditorApplication.modifierKeysChanged or EditorApplication.Update if a given key is pressed down?
How can I smoothly blend between 2 animated ABC caches ?
I have 2 spheres deforming and I would like to run the first animation in loop, then transition to the second cache.
I have attached an ANIMATOR to the first cache and added the second cache as animation, but the playback is incorrect. How can I blend between 2 caches. Even if is not ABC is ok, but I have no idea what else to try
#🏃┃animation would be better suited for this question. This channel is for discussing creating extensions to the editor like new editor windows and custom inspectors.
But to answer your question, you can click on the transitions to set blending, and you set if an animation loops on the actual animation asset. Any further questions would be best asked in the #🏃┃animation channel. 🙂
okay, so I think I have this editor extension almost to a point I really like. However, I that randomly my unity window hangs like it is refetching all the data?
I know that it would be useful to see my code, but, it is kinda long, so was wondering if anything off the top of anyones head first to look at
I might be having to much happening at repeated intervals. Like, I have a setdirty, saveassets, refresh happening after every time one of these data values is added or removed
Use the profiler
oh yeah, thanks for reminding me
okay, it looks like the repaint() is what is causing the problem
at least if I am looking at this correctly
InspectorWindow.Repaint causing 77.4% of the spike when that happens
what confuses me though is that the inspector is already updated and can still do things for a couple of seconds before this hang?
oh, there is 3 spikes, the ones after that is RepaintAllProfilerWindows()
Hey, if I'm trying to replace a texture in a Sprite Renderer in the editor in C#, do I have to save the modified texture pixels to the image file and then somehow set the texture file to the sprite renderer or is there an easier way to do it?
This is what my "save textures" method looks like:
public void SaveTexture()
{
// Save the texture to the output file
canvas = new Texture2D((int)clippingRect.width, (int)clippingRect.height);
canvas.SetPixels32(imageCanvas);
canvas.Apply();
renderer.sprite = Sprite.Create(canvas, new Rect(clippingRect) { x = 0, y = 0 }, new Vector2(0.5f, 0.5f));
}
imageCanvas is the new image
Everytime I do this it just clears out the texture from the SpriteRenderer
no, if map is null it won't change between Layout and Repaint.
What do you do when the error appears?
the map became not null
how does that occur?
i modified the value of map via a toggle
Try adding a change check to the toggle and exiting GUI there perhaps
Wherever you change the state in this case is where you should exit the GUI. I don't know how odin works either
it's only relevant in OnGUI
if that's happening in the base.OnGUI, try wrapping that in a change check and exit if a change happens. It's probably not ideal, but if it works 🤷
): sorry, I can't be of more help
To describe the issue that's happening clearly:
OnGUI is broken up into a few passes, one Layout, one Repaint (and some extra)
When Layout occurs it allocates a stack of rects for use with Repaint.
When Repaint occurs it expects that stack to be allocated in the exact same way, when it isn't it will throw that exception.
If you're doing a structural change in the middle somewhere and calling ExitGUI that just throws an exception which ends the GUI frame and it then repaints again.
So if you have a list of items that changes between phases that you're drawing, then drawing a new one when the stack doesn't expect it requires you to exit the GUI. The error is totally harmless, but obviously should be avoided because it's annoying as all hell 😛
your words are helpful. thanks a lot 👍
I have not been paying any attention to the conversation. But if you have a harmless error than you can always use a try catch
😂 but it will be called per frame, doesn't it cause the low performance?
Not necessarily always because sometimes it's just a LogError and not an exception
(I have literally no context for what I am saying. I am basically just responding to the last sentence in vertx's last message 😛 )
😆
i solved it by checking the map manually.
it's so weird. the GUI.changed and BeginCheckChanged occurs at Repaint phase but it called later than below code.
@visual stag
maybe the changed check happened in next repaint phase
maybe, either way, glad you've got a fix 👍
thanks for your help.xD
How can I change the object that is being shown in an UnityEngine.UIElement.InspectorElement? Using .Bind(obj) only works the first time. What I am missing? Must I force a redraw or something? How?
I noticed that I destroy and create a new inspector, but that sounds expensive
From reading the docs it sounds like it only does it the once. If you are changing what object is bound, it doesn't know if it is the same, so it would need to recreate all of the elements anyway.
Ok, thought it also has an .Unbind method, but doesn't work 🤔
Has anyone figured out the "multi layered" dropdown that UnityEvent has?
Writing here cause there's no channel specifically for this... anyone knows how to make custom timeline tracks reset their value when deselecting the gameobject with the playableDirector they appear on?
I have the problem that my custom timeline tracks edit values in the scene during previeuw but those values dont get reset and in the end always get saved
I'm trying to make some editor settings that will assist in globally changing the mip bias of textures in my project.
I have an AssetPostprocessor with the OnPreprocessTexture event function so I can grab the textures importer and set the mip map bias based on my settings
private void OnPreprocessTexture()
{
TextureImporter textureImporter = (TextureImporter)assetImporter;
if (textureImporter != null && ShouldSetBias(textureImporter))
{
textureImporter.mipMapBias = MipSettings.GetOrCreateSettings().bias;
textureImporter.SaveAndReimport();
}
}
Then in my MipSettings gui, you can change the bias field and click an "Apply" button. I'd like the apply button to reimport all the textures in the project, which will indirectly cause the mip bias to be updated via the asset post processor mentioned above.
The problem I'm having, is that reimporting the assets doesn't trigger anything on my post processor. Unity just doesn't run it.
if (GUILayout.Button("Apply", GUILayout.Width(50)))
{
// find all texture guids
string[] guids = AssetDatabase.FindAssets($"t:{nameof(Texture2D)}");
foreach (var guid in guids)
{
// get the texture path
var path = AssetDatabase.GUIDToAssetPath(guid);
// and importer
TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
// if the asset has a texture importer, and the post processor should set the bias
if (importer != null && MipBiasPostProcessor.ShouldSetBias(importer))
{
// reimport the asset
Debug.Log("Reimporting " + path);
AssetDatabase.ImportAsset(guid, ImportAssetOptions.ForceUpdate);
}
}
// and refresh the asset database because that sounds
// like a thing I should do?
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
}
AssetDatabase.ImportAsset takes a path not a GUID
also you should definitely wrap that in a https://docs.unity3d.com/ScriptReference/AssetDatabase.StartAssetEditing.html (try, finally) https://docs.unity3d.com/ScriptReference/AssetDatabase.StopAssetEditing.html
or whatever way around that goes
oh my god thank you haha
ah that start/stopediting thing is perfect. i had a feeling that would be a problem!
otherwise when you click that button... you're gonna be waiting a while lol
I have had that regret
I set this up to add more to my custom enum editor I'm working on. I kinda wanted to try and get away from the ongui and stuff. I haven't tried setting up events in the editor scripts. I was having a difficult time figuring out how I wanted to initiate my enumdata script. Will this cause any potential problems down the road?
I am having an odd problem, from C# I can create ObjectField elements, but from UXML files I get the error "Unkown type: 'UnityEngine.UIElements.ObjectField'". 🤔. How can I fix that?
Is it possible to invert a FindAssets query? I don't see it mentioned anywhere online so I'm guessing not, but I'd like to get all sprites without a certain asset label so I can easily exclude assets from a bulk operation by simply adding a special label
I'm not sure if this is what you are exactly looking for, but, I use findassets by type all the time. For example, AssetDatabase.FindAssets("t:Sprite", new[] {"Assets/"} type searches
ohh nvm, That isn't what you asked. I wonder if you can do a ! somewhere with the label
I don't think so
You could do an AssetDatabase.FindAssets for sprites, then do a foreach on each of those and to not load that sprite if its of a certain label
Hey all 🙂
Writing a custom inspector for a class that has public List<T>. Im trying to make it only render a single element of that class, with some nav buttons to flip through the whole thing. The question is: do I have to spend a bunch of time making the output of the classes data manually, or is there a 'RenderDefaultDrawer' kind of function to allow me to render it as if it was standalone?
EditorGUI.PropertyField draws the drawer for something
Provided it is a serialized property on some other serialized object. If it's a full blown object on its own, I've had success with Editor.CreateEditor before, but it's a little bruteforce. https://docs.unity3d.com/ScriptReference/Editor.CreateEditor.html
Yeh my main thing is that im not sure if I can get the property for the object, I think I can only get it for the array as a whole. I will check out CreateEditor, thanks for the resource!
Yeah, IIRC, every item in a serializedproperty array is in itself a serializedproperty , but if you ask to "draw" the property for that, you just get the assignment field in the case of a Unity object, so it may or may not suffice for your use case.
Yes that's the default behaviour
You can iterate over a lists items just find by doing Next(true) or GEtArrayItemAtIndex
Doing CreateEditor is not a good idea to do in OnGUI, as you need to manage the life time properly. So it's a no go in propertydrawers
Not good idea.
@plucky nymph Take what Vertx and navi gave you.
PropertyField & FindRelative/GetArrayItem is enough
What causes my editorwindows to occasionally stop opening and having to do reset layout?
looks like there was a failure to destroy the window.
Because when you open a window, you usually call GetWindow() which will first look for an existing instance of the window
ya
And since there is one (even if corrupted), you won't see anything
okay, I haven't done anything yet with these catch functions, is that how you would suggest handling that, or just an if statement
gotcha, thanks again for the help!
okay, ty!
And this is m_Parent
Notice that you don't call Close() on the window.
You must destroy it.
I started using a singletoneditowindow script to pair with an instantiateonload atribute. Would it be best to put that oprhan method in the check in the singleton script?
I have no idea how is your singleton made
I call the orphan check every single time i open a window.
You have no choice, it must be done prior to open your window
Or you will see a silent bug
ya
I guess Close relies on the parent?
Never really had this issue so I didn't have to fix it :p
I would say kinda yes, as I am not sure of the code under, but since the parent is null, closing does not bubble up correctly.
While if you destroy, you destroy the GUIView the EditorWindow resides in, which embarks his buddy on the way
👍
Okay, so now that I hopefully have that working. I want to today try to better understand setdirty, saveassets, and refresh. I think these are what are causing me to have to repaint hangups
I know that I seem to need to refresh assets, at least for the project hierarchy to display new scripts I make in the editor window
but I don't feel like I need to setdirty and save assets after every change I do. The setdirty is confusing me a bit since I thought I needed to do that save changes to scriptable objects I do from code, but might be doing it excessively
How can I display a custom type in an UIElement? InspectorElement doesn't seem to support arbitrary types.
What do you mean?
How can I do for example?
[Serializable]
public class Alfa { public int a; public int b; }
Alfa alfa = new Alfa();
InspectorElement inspector = new InspectorElement(alfa);
That doesn't work
@gloomy chasm
You can't. IMGUI nor UIToolkit support doing something like that.
😢
If you don't want to specify the elements for each you will have to use SerializedObjects, and SerializedProperties, with PropertyFields.
I was playing around with [SerializedReference] but I guess I will have to use ScriptableObjects then, they are far easier 😆
Why? If you are using them with PropertyFields it is actually easier to use [SerialiseReference] I think.
What is it that you are doing that makes it more difficult to use the attribute?
I was using reflection. Didn't know that PropertyField did support SerializedReference
mm, I'll try using PropertyField then
It supports anything all serialized fields. It uses SerializedProperty so if you can get a SerializedProperty instance of it than you can use it with PropertyField.
PropertyField doesn't seem to work if I give to it a SerializedProperty which cames from a type that requires [SerializedReference] to be serializable
Well, at least I can fallback to ScriptableObjects
It should work just fine... code?
If I have:
public class Alfa : MonoBehaviour {
[SerializeReference]
private IMyInterface array;
}
// Editor
root.Add(new PropertyField(serializedObject.FindProperty("array")))
The field isn't shown
Because it is null. There is nothing to show.
Unlike normal serialized fields, ones that are serialized with [SerializeReference] can be null, and will be unless you set their value.
That is, unless you want to write your own editor for it, or use a drawer like mine https://github.com/vertxxyz/Vertx.Decorators
Oh, really? I thought I would get something like "null" in the screen instead
Does anybody have an idea how to work with PresetTypes? I'm using an ObjectField to Referenzen Presets and onChange I would like to evaluate the PresetType, but I can't figure out how to check, for example, if the PresetType is TextureImporter.
There is no static PresetType.TectureImporter and I wasn't able to use the PresetType Constructor so far.
@onyx harness Do you happen to know anything about this serializedproperty.unsafemode?
@waxen sandal not at all
seeing the code, I'm not sure how I would use it
Seems heavily related to Binding
which is purely UIT
An area I dislike 😄
Well it disables some checks, wondering if it actually makes it faster or if the check is neglectable
And how "unsafe" it actually is
We're doing a lot of validation with serializedproperties, so much that calling Next() is actually a real bottleneck
when I see that I can understand why on huge scale
I would say, if you are safe yourself, I would go into it 😄
Yeah I'll probably just enable it and compare some quick benchmarks
Keep me in the loop please, sounds interesting
Sure, I'll let you know
I don't think we get any exceptions while running our validator so it should be "safe"
Yeah exactly
so I was checking Debug.Log(serializedObject.hasModifiedProperties); and it returns false even after I add something through code not the scriptableobject. Do you not need to setdirty on a scriptableobject on everything on a scriptableobject?
It will only return true if the properties have been modified since ApplyModifiedProperties() was last called.
oh okay, I also just read about how values changed through defaultinspector don't need to be setdirty. Does that apply even through code?
I guess I could just restart unity and see
If you set value through SerializedObject/SerializedProperty you don't need to worry about SetDirty, or Undo/Redo.
so, I'm not setting through those, persea. I have my scriptableobject instance I'm adjust values on, but, the "get info" part doesn't rely necessarily on the scriptableobject to have that data. However, I want to make sure that data is saved to the scriptableobject so when I check to get the data, it won't go through the process involved if the data already exists
atm the default inspector updates correctly, but want to make sure it saves. I guess I'll just check haha, just enjoy the chat
did just get this error Importer(DefaultImporter) generated inconsistent result for asset(guid:9f8e9c9c30d734674a446d6bdab62eb9) "Assets/ScriptableObjects/Enums/Test" is this because of the fact I deleted the last Test I made, and then made a new one? I think I read somewhere about GUID data and other things aren't actually deleted after removing an asset till you restart unity?
okay, it seems whatever I am doesn't need to worry about setdirty. Maybe because of me doing a singleton there is only once instance of the data?
Well what are you doing. If you are editing an asset and not setting it dirty, and not using SerializedObject, it will not save the changes when you exit Unity.
So where I'm at atm is I have a scriptableobject singleton, have the asset of it. Then in editorwindow I have it getting and setting data from the scriptableobject through my singleton doing EnumData.Instance. I just created a new Enum that does .add to the lists on the scriptableobject and restarted unity and it seemed to have saved the data. Sorry, I know this isn't really a problem. Just trying to understand it more
now this most recent test didn't save, but kept the previous data wasn't saved either haha
I was told that I want a custom importer, but I want to interject between the point where the asset is turned into a Texture2D, And what I have right now is a button that is supposed to modify an image and its position. The problem is that the last step of replacing the asset doesn't work. I create a sprite and attach it to the sprite renderer and the image that was there that the button operated on disappears. I know everything else works because I tested it individually. The only problem is saving it to the asset database so that it has the modified data. I'm trying also to avoid modifying the original files that it imported or generate any other files
Unless I am missing a previous comment. This is not enough to do anything with. I am not even sure what it is you are trying to do, let alone how to help.
A clear description of what you are trying to do, what is going wrong, and what code you have. Without that, it will be hard to help you.
Okay, so, I moved on back to some InitiateOnLoad things and made me curious more about understanding scriptableObject instances, combined with the normal singleton pattern.
is a script I made
which worked when I put a setter in the singleton pattern to make the instance = this loadassetatpath
but without it, the debug for the instance is 0, for example. When I click on the EnumData scriptableobject it also would populate the EnumData.Instance, but, not before then?
Sorry MechWarrior99, Ok. So I have image files with a large amount of surrounding transparent space around each image. They're imported into a prefab where individual game objects represent each image which acts as a "layer" that can then be stacked on top of the image below it. This works because all of the images are the same size, and all of them are positioned at 0,0. But, it's wasteful and inefficient in terms of performance because each image could have several hundred empty pixel rows and columns around the actual image data.
So I've written a button that crops out those empty pixels leaving just the actual image in the center, and also calculates how the positioning should be adjusted so that the image is in the same place on the canvas as it was before (so that layering still works). The problem is that now that I've got all that working, I need to put the newly created Texture2D as a Sprite into the sprite renderer for the corresponding object.
I thought maybe I could just generate a sprite and assign it, but that just makes the image disappear from the canvas and when you go to the gameObject in the editor and check the sprite renderer component, "sprite" is blank.
Because this is built into the editor, I'm trying to abide by some rules: Don't create extraneous files in the assets directory, apply the graphic to the sprite renderer, and don't modify the files the image was imported from
Just put that in the getter for the instance.
There is no reason for it to be in update. If you wanted you could have it in a separate method that get calls and also have an initOnLoad attr on it.
I see, that makes much more sense! Maybe a silly question, but why not just edit the files to remove the empty space to start with? If they are really that much bigger you are potentially wasting a lot of storage space.
(Also will need to see the code you are using for setting and creating the sprites)
Because those are the original assets the user is working with presumably
That would still be a somewhat destructive change that would be hard to reverse if the user needed to
good point!
This is what I do for my own and I call it in the get; accessor for the singleton instance field.
[InitializeOnLoadMethod]
private static void SetInstance()
{
if (_instance != null)
return;
string[] guids = AssetDatabase.FindAssets($"t:{nameof(LibraryData)}");
if (guids.Length > 0)
{
_instance = AssetDatabase.LoadAssetAtPath<LibraryData>(AssetDatabase.GUIDToAssetPath(guids[0]));
}
else
{
_instance = CreateInstance<LibraryData>();
AssetDatabase.CreateAsset(_instance, LibraryConstants.RootPath + "/Asset Library.asset");
AssetDatabase.SaveAssets();
}
}
Yeah, appreciate it. I hate when I derp like this lol. Made an entire different script to do the initialize than put it in the singleton
like, went in a full circle when I didn't need to
lol
this scriptableobject enums is going to eventually build into other things. I just keep getting stuck wanting to perfect this base part lol
arrgh, that's ugly
Thank you! 😛
It is rather ugly, but truthfully I'm not exactly sure how to improved it.
What I see is an instance that will force load at init even though it might never be use.
Go for lazy loading like any common singleton pattern
If everybody was doing like that, reload might take precious seconds just for those
Oh that! Yeah this isn't my normal pattern. I normally use the Lazy<T> class. But for this particular one I did it this way. I had a good reason for doing it this way I think, but I can't remember now so I was planning on reverting it back.
The more I think about it I think it is just leftover this way from refactoring.
How can I store editor data that persists through domain reloads? Also is there a hook I can listen to, to know when a reload occurs?
@onyx harness @gloomy chasm hows this look?
also, is there a way to make this a singleton for everything? I've noticed online different singletons for every inheritance. Can't you just do a generic inheritance?
Firstly if there are not asset instances of T your GUIDToAssetPath line will give you an IndexOutOfRange exception because tGuids has no items in it.
If this is not for editor only then you need to wrap the code that is editor only in a #if UNITY_EDITOR or Unity can't built.
that confuses me, is that even possible? For this to be called doesn't there mean there is an asset?
Not at all, that is the point. The very first time you try to access it there will be no instance because you have not created one.
oh okay, so I should keep the system.linq resources also for if this ie being accessed outside the editor?
What?
my other check was _instance = Resources.FindObjectsOfTypeAll<T>().FirstOrDefault(); I should leave that outside of the #if UNITY_EDITOR so I still have some method if trying to access the instance at runtime
?
Not that I will. Just wondering
Yes.
btw the is no need to do
T t = AssetDatabase.LoadIns...;
_instance = t;
Just make that one line and directly assign the instance to _instance.
Also for CreateInstance, there is a generic version of it so you can just use that instead.
I didn't quite understand the create instance generic part. I thought that was what this already is hehe
also did add if (tGuids.Length > 0) forgot that in SS
Because presumably those are the original copies of the assets that the user is working with. Also that would be quite a destructive change and that's part of the goal is to avoid destructive changes and also make it easy to undo the changes which will be the next thing to solve but I can't solve that until I figure out exactly how those changes need to be made
Here's the code as it stands right now. The "return" at the end of the foreach loop in "ModifyAllImages" is so that it only processes the first image until I get the process correct.
TextureViewerWindow.ShowTextureViewer(sprite) is a custom window that shows the results of the cropping.
The cropping works, the realignment works. It's just applying those changes to the prefab in such a way that it can be undone, doesn't change the underlying files, but persists when saved and is included in the final build
I was told I need a custom importer, but I'm unsure from the documentation how to do that.
_instance = CreateInstance<T>();
There's some way to make this work? This is a struct array
Enable rich text
so, I've been tracking guids in some of my editor things for just in case I need them... when do I need to use Guids vs just a path? Would it be anywhere I don't know the default path, like different OS?
Anytime that an asset can be moved and you want to still keep a reference to it.
Basically if you want to reference an asset without loading it, there is almost no reason to use path instead of guid.
oh okay, so that might be something nice to actually use then just in case the user drags things from the default paths I have them at
Correct
That's a nice indentation visualization effect you've got there. Would you mind sharing the product/extension you're using for that? Sorry if you've already mentioned it before, I tried searching your messages in Discord but the search feature appears to be buggy and doesn't return anything.
Absolutely! Thanks for asking, always hope I can give back. I'm using extension indent-rainbow by oderwat
oderwat.indent-rainbow is extension identifier
Very nice, thanks a bunch. I've been using a simple line identation visualization for years in VS, but this is far nicer!
There's a similar VS extension here: https://marketplace.visualstudio.com/items?itemName=chingucoding.IndentRainbow. Haven't tried it yet
And there's the VSCode extension if anyone is interested https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow
haha thanks, was looking at how to get that
So I made a separate script to solve this, but, made me wonder. Is there a way to bypass compile errors? Like, create a method that does certain things, but, if the variables and stuff don't exist yet, to make the errors null?
No
okay, thanks!
hmm I guess I could just put the method in the class that doesn't exist yet with if UNITY_EDITOR conditions
oh dang, I'm noob enough with unity haha. I'll learn about DLL stuff soon
so I think I accomplished what I was wanting to do, though not exact, through the class itself and #if UNITY_Editor and OnEnable()
I guess I could just do awake instead though? or both?
Mech got me hooked into #if UNITY_EDITOR. I was trying to not use it outside of editor scripts directly, but, it has actually made my life easier to just include editor things in the scripts themself 😦
No! Bad! Don't do that. Put the editor stuff in it's own script and in the Editor folder.
Ugh, trying to track down all of the validation methods for the menu items in Assets/ menu is a pain.
Also comparing items to figure out what is missing from the menu.
(Trying to make the Assets/ menu customizable)
Using Menu I guess?
Sadly less than half of the items in the menu are added via [MenuItem] the rest are added in C++...
EditorGUIUtility.SerializeMainMenuToString() is not enough
I have not seen that before. What does it do?
Get all the top menus
But it is not looking at validation methods
just fetches all the menus
Ah, well it only returns "Assets" when I use it in the project browser. So unfortunately not that helpful in this case.
What I am doing right now is subscribing to the EditorApplication.projectWindowItemOnGUI event and catching the Event.current if it is a ContextClick, using it and calling my own menu.
I haven't tried figuring out how to replace the menu for the Add button yet. I'm thinking maybe using UITK to put an overlay over the button and catch the click event first. If there are better ways to do this I am more than interested.
Use that to generate the menu for a specific path:
https://ngtools.tech/uv/UnityEditor.Menu/ExtractSubmenus()/
Type : public sealed class UnityEditor.Menu
5.0.0f4 ⟩ 2021.2.0a20
Unity Doc
Method : internal static ExtractSubmenus()
2018.3.0f2 ⟩ 2021.2.0a20
GitHub Source
Also have a look at :
https://ngtools.tech/uv/UnityEditor.MenuUtils/
Type : internal class UnityEditor.MenuUtils
4.6.0f3 ⟩ 2021.2.0a20
I'm not even sure to understand where lies your issue
Those look promising, I will check them out thanks!
My issue is two fold. First, trying to get all the menu items for the "Assets/" menu.
Second is getting the validation methods for the menu items that have them.
First is solved.
2nd is partially possible as you discovered.
Ah, that ExtractSubmenues works perfectly, thank you! Saved me a lot of time. Now to just either track down or recreate all of the validation methods... yaaay........
You can't. Some are not present in C#
Yeah, I figured that was the case. I think I should be able to recreate them though. I hope.
Recreate them?
Except manually, I dont see how
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type type in asm.GetTypes())
{
foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
{
MenuItem[] attributes = method.GetCustomAttributes(typeof(MenuItem), false) as MenuItem[];
for (int i = 0, max = attributes.Length; i < max; ++i)
{
MenuItem menuItem = attributes[i];
if (menuItem.menuItem.StartsWith("CONTEXT/") ||
menuItem.menuItem.StartsWith("internal:"))
{
continue;
}
//if (menuItem.validate == false)
{
string label = menuItem.menuItem;
int n = menuItem.menuItem.LastIndexOf(" ");
if (n != -1)
{
if (menuItem.menuItem[n + 1] == '%' ||
menuItem.menuItem[n + 1] == '#' ||
menuItem.menuItem[n + 1] == '&' ||
menuItem.menuItem[n + 1] == '_')
{
label = menuItem.menuItem.Substring(0, n);
}
else
label = menuItem.menuItem;
}
else
label = menuItem.menuItem;
Debug.Log(menuItem.menuItem + " " + menuItem.priority + " " + menuItem.validate + " (" + label + ")");
//this.Build(root, menuItem, label);
}
}
}
}
}
This is to fetch the menus, I guess you did something similar
A lot are missing
You can use the TypeCache to get them which is nice. But as you said, a lot are not returned. So for those I need to either find the validation method in the C# code, or if they are not there, create my own validation method that that mimics the funcinality.
I dont like TypeCache, I mean not for now
Why is that?
Was not reliable enough when it first came out
Ah, I have not had any problems with it my self as of yet.
Was returning empty results on 2nd domain reload
It's to bad that ExtractSubmenus doesn't include the key bindings too.
At least you have the paths, which you can recover from
Yeah, for sure will still save me a lot of time. I guess I will use it along with getting the MenuItems to get what info I can. Then just do the rest manually.
In my method, I do call ExtractSubmenus to construct all the paths.
Then use the above code to recover bindings when available
OH! I wonder if I can use Menu.RemoveMenuItem and Menu.AddExistingMenuItem instead! Any idea what string existingMenuItemId is?
I just want to be able to customize the items in the Assets/Create/ menu.
hi, i need help on how to access an asset, so I downloaded Bolt, and imported it, I can see the files under the project tab, but idk how to access it
lol just that, Menu should suffice then
This is the first thing I suggested
This is probably not the channel you are looking for. #💻┃unity-talk wold be better suited. This is for talking about the creation of extensions to the editor, like new editor windows and custom inspectors. If that is what you mean, then you would use the AssetDatabase.LoadAssetAtPath. Otherwise ask in #💻┃unity-talk 🙂
Too be fair, that isn't exactly a descriptive suggestion 😛
ok thx, Im new and I just thought that assets were in the sub section of extensions, sry
No problem! It is a common thing people do! 🙂
Hey! It worked! This makes everything so much easier! I wish I could get priority of the items, but that's okay!
Thank you so much for the help! Saved me hours of work for sure!
It can? Besides with MenuItem?
Yeah, but that is like less than half of the items in the create menu sadly.
yep
And I never did figure out what string existingMenuItemId was, so just using AddMenuItem with an EditorApplication.ExecuteMenuItem
existingMenuItemId is just the path
Yeah that is what I thought too. But I tried it and it didn't seem to work.
Well this doesn't work. (Also tried it with removing it first)
What version is that on and do you remove the items first or anything?
When I did my first test on Menu in 2018.3, it was "working"
I was able to add, remove
And it was not super reliable
Maybe something changed between then and 2020.3. AddMenuItem works reliably and it isn't that much more annoying to use. So that's fine I guess.
Is ExtractSubmenus public in a different version?
Yeah I'm sure it is more reliable now, like TypeCache
https://ngtools.tech/uv/UnityEditor.Menu/ExtractSubmenus()/
It's always internal
guys is there a way to make my dropdown stay on the value selected in inspector like it would if it was an enum from monobehaviour?
Yes
How?
I see, I was under the impression that the screenshot was from your own stuff. I see where it is from in the source. My mistake for assuming things.
But strange, AddExistingMenuItem should work... I will take a look at the code I guess and see if I can find any differences.
By setting currentEffect
Me naming variable text4? You are insulting me right now🦉
You're right, I am very sorry!
...that is some pretty unholy code...
It comes from dnSpy, common naming I would say from disassemblers
Oh! Are you using that to look at newer version's source code since the repo is no longer being updated?
I almost never use the official repo
Oh really? Why is that?
I found jumping from a disassembler much efficient
I only use GitHub when I dont have dnSpy around
Also I can scan between multiple versions at once
Taking a look at it, it seems pretty nice. Is there anything you gotta do to use it with the editor? Also, is there a different repo to use now since the current one is archived? Or is it still good?
(I have never used something like it before)
You just need to drop DLLs in there and it will scan them
I don't think the official repo is abandonned, is it?
I was using ILSpy first, then discovered dnSpy which has a much better UX and dark theme
For API search I use my NG Unity Versioner, for implementation I use dnSpy
using dnSpy will have a part in my tutorials
Cool, I will check it out later.
Says it is readonly now, last update was 6 months ago.
When I check it out, if I can't figure something out would you be alright if I ask you, or would you prefer I not (totally get if not)?
figure what? How to use dnSpy?
You will see, it is rather simple to use it
Like a kid in a sandbox
Cool, that's good!
Alright, I think I've made some progress. I can change the texture data just simply by using renderer.sprite.texture.SetPixels32() and then renderer.sprite.texture.Apply()
But the problem is that the object is still the original height and width, even though the underlying texture is now much smaller so it puts it in the bottom left of the rect instead of just making it the same size. Is there a way to resize a game object with a sprite renderer without messing with the "scale"?
Even if it's in world coordinates that would be fantastic
Well if it has a sprite renderer it is on UI I assume so it has a RectTransform instead of a Transform component. So you edit that.
It does not, but I think I can add one?
You can. It will replace the Transform component.
Right I mean from the C#
and then I think there's an EditorUtility static method I need to call against it
What?
AH
Yeah, because otherwise it's an "override"
So if later the user creates a prefab variant, it comes with that RectTransform
Not that I can think of when they would, but I do think the user would expect that behavior
Thank God for C# Idioms:
if (!renderer.gameObject.TryGetComponent<RectTransform>(out var newTransform))
newTransform = renderer.gameObject.AddComponent<RectTransform>();
No that didn't quite work. I got a light gray block that was the full size of the original image. Not sure why.
Maybe I need to do the texture edit first and then the rect transform?
idk
Is there a way to change the size without a rect transform that I'm missing? like how does the importer set the size?
@onyx harness unsafeMode seems to save ~10%
Actually, more like 20% went from ~240s to 200s
(as you can imagine this is A LOT of iterating over serializedproperties)
Oh ho! :)
sorry quick q, in code does anyone know how to mark an image asset as normal map? nvm im daft and can't google well
https://forum.unity.com/threads/how-to-use-textureimporter-to-change-textures-format-and-re-import-again.86177/
I'm trying to create some editor scriptableobject assets with MenuItem attribute. It can only be used on methods, so, do I just make my method create an instance, then create asset?
CreateAssetMenu
tyty
errr whoops
I should have clarified
I don't want it under the asset menu is what I'm trying to achieve
I don't know
In that case, menuitem with your own creation
okay, cool
IIRC there's no magic way for that
Could check reference source and see what they do
Iirc they handle it on the C++ side.
there is just some things in the editor script I'm working on that I want to save data to essentially so that it doesn't have to be regotten every time, but not put it onto what I'm creating a custom editor for to keep the code separated for my own personal preference. I know editor already extends scriptableobject
so just was thinking about how to best approach the creation of it
without having it in the asset menu with regular assets
I don't necessarily like the route some people go where they do createassetmenu, create the SO, then comment it out lol
You can just do CreateAsset with a scriptableobject as item
Guess that's true. Could essentially put a section in the asset menu that is editor specific assets
I think I might go the route we were talking about earlier though, because I can put a check in the method to make sure only one of that scriptableobject exists
You could also just comment out the menu item once you've created an instance.
Yeah, I just don't like that route because it feels... uhhh how do I say this? Like a band-aid solution?
What you want to do is a little odd though right? You don't want to create assets through code, instead you want to create them via the UI.. but only for yourself, and then sometimes you don't want the menu option to be visible?
Unless I misunderstood
I want to create a scriptableobject that holds data for the custom type my editor script is for, for editor side of things so that the data it is storing doesn't have to be found basically every time I need access to it. I can do the if UNITY_EDITOR stuff and not do this at all, however, due to my own annoying way of preferring things it hurts my eyes and stuff to mix that into things that go into builds, so I have a menuitem for my editor things called editor, and thought hey, maybe I'll make a category in that for editor scriptableobjects
idk if that helps
You may want to use something like this: https://docs.unity3d.com/2020.1/Documentation/ScriptReference/ScriptableSingleton_1.html
For my asset I do something similar and Create it via code if it doesn't exist. I think it's a fairly common pattern that if anything requires the data, that class is responsible for creating the asset with appropriate defaults.
thanks, I already use those, but didn't think about extending those even further for exactly what you are talking about, so will definitely look into that more!
The most annoying part with those is (afaik) they require a static path. When making an asset where a user can freely move it around, you need to do more of the work yourself (but it isn't much).
yeah, the current thing I'm working with will work perfectly in adding to that haha. It's actually why I I'm trying to do this further, because I didn't want to store GUIDs and Paths and things on my build objects lol
Yeah but it's easy to put in projectsettings
This is true.. but I prefer my asset contents to all be contained within its own directory. So when it's deleted, it's all gone etc.
Is there a way to find out all the default attributes that exist for editors? I seem to only be able to find that attributes exist, and then the specific pages for attributes, like, filepathattribute.location when I need them
Wouldn't be surprised if Mikilo already had a reference page for them 🙂
I like that singleton you shared. Have switched things over to it now to basically a projectmanager script with all my different menu items and things
now, where it says
public void Log()
{
Debug.Log("MySingleton state: " + JsonUtility.ToJson(this, true));
}
Can I do an ondestroy? Haven't actually checked if things like ondestroy happen in editor scripts
on application quit rather
found it
and i guess you never need to unsubscribe from these type of events because the quitting unsubscribes? lol
ya haha
I did mine a little different. This should still work right? Guess I can just test
oh guess it needs to be static
Why do you need that?
did it
uhh, nothing specific yet. Just thought it would be something fun to setup after that link
Might be nice to have for a controlled area to put all my intializeonload and potential persistent data between unity sessions
I installed the vscode vibrancy extension
and when I start up vs, the background gets transparant for a second and then turns normal again
Wrong channel
if anyone was wondering, this worked perfect
I looked up a bit but couldn't find your past conversation. Would you be willing to enlighten me about what you are talking about here? Something that makes iterating SerializedProperties faster?
SerializedProperties have a unsafeMode, it's just a property on the serializedproperty, it disables some checks like whether it's going out of bounds
If you're using the API correctly you shouldn't hit these checks so it's "safe" to enable
Which makes it 20% faster on a large project
You shouldn't need a CreateAsset with a scriptablesingleton though?
didn't even think about that
err well
Oh really? Nice! Does the size of the project change the performance of iterating on serialized properties on a single object? Or do you mean iterating over the serialized properties of a large number of objects?
Large amount of objects
If you are on 2020+ there is a FileLocation attribute (Or something like that) that you can just give it a path and it will auto save the SO there.
for ease of seeing in inspector I would need to still create the scriptableobject?
It wouldn't surprise me if we do more than a million Next calls
FilePath
If you create it in Assets you should just be able to select it
It'll automatically create it for you
ohh cool. I'll look into that. Thanks guys
Nice! I actually have a use for this, so thanks!
Mind if I ask what it is that you are doing where you do a million Next calls...?
I feel so like blah. I finished making this scriptableobject enum data thing days ago, but, now I'm trying to perfect it. I want to share it also, so trying to optimize it the best I can first
Iterating over all fields in the project
To validate correct settings
Well that would do it I suppose.
😄
only a million? Get back to us when a million and 1. That's the real struggle
A million is a very low ball estimate
I wouldn't be surprised if it was more than a million
You have to accept that it's not goign to be perfect
haha I know. I just wanted to act cool and be a part of the convo
Get it working, get it working well and you're done
If it isn't too much code I could do a quick code review of it if you would like.
I'll try to get back to you soon on that! I broke up a lot of code before I went to bed last night, so putting it back together right now with some of this new info
Admittedly I need to get better at version control
because I keep breaking working things
is this the correct way of accessing both editor and scriptablesingleton<T>
Guess I can just use filepath without inheriting from scriptablesingleton?
Probably nit
I have just discovered the DrawGizmos attribute which should let me draw gizmos from an editor instead of from within a component, yay. The problem I'm running into is that Handles don't seem to be interactable from within the event, presumably because the Gizmos and Handles API are distinct 😫. I would just write the handle logic in MyCoolComponentEditor.OnSceneGUI, but I need them to be visible in the scene even when the object is not selected. I tried hooking into the SceneView.duringSceneGui delegate from the editor's OnEnable event function, but that requires you first select the object before the handles are always drawn. The key point here is that I need to use the Handles API, I need them to be interactable, and I need them to always draw. It's easy to draw gizmos always, but I cannot find a way to do it with handles 👍
Hey, anyone!
Is there a way to toggle Cloud Diagnostic through script?
I want to query the players before allowing crash reports and such to be sent automatically.
But I don't find anything in the API or on the web
You should be able to load the settings file in projectsettings as Object (or the right type if you can find it) then change it using serializedproperties
Can't you register to that event in InitializeOnLoad and then draw your handles?
i believe that function would have to be static, so i wouldn't have access to any instance with which to draw handles for
could FindObjectsOfType, but that would only give me the objects that exist in the scene when the assembly reloads
not sure if i wanna FindObjectsOfType every tick just to make sure all available components are having their handles drawn tbh 😦
since gizmos have the ability to be drawn even when the object is not selected, I was hoping I was missing something simple that would allow the same for interactable handles, but if that's not in the cards I'll move on
@gloomy chasm @opaque zenith At least 40000 files, around ~200 scenes, 8000 complex scriptableobjects that have probably more than 300 valid serializedproperties and then all other assets and prefabs (which likely contain a similar amount)
I also lied yesterday, it's more like 27% with unsafeMode @onyx harness @gloomy chasm
Now that I have more insight of what you are doing, may I suggest you to implement a check by text?
You mean open the assets as text?
SO is supposed to be the easier and quicker way.
But, maybe if done cleverly, loading an asset as text (when available of course) and deferring it in a job/thread might multiply your workforce and then only load the asset in a SO when required in the main thread.
Yeah I thought about that but it would mean a lot of rewriting and some things might not be as trivial to do
Trickier yes it is, less straight, but might be more powerful because of multithread
This validation code has existed since before I joined, if I were to redo it I would probably do it byt ext
Then again, I don't know what kind of check you do
A lot 😛
SO is not a bad way, but since you hit in the millions, others might more interesting depending on the hardware available
Checking whether references are valid, whether we're not accidentally referencing a texture that should be in a spritesheet, whether the prefab is disconnected, and probably more
Then we also have a bunch of things for specific components, asset bundles, attributes that denote whether a property is required etc...
OK I see, well my conclusion is by text is potentially better
Oh, giving good errors is probably harder by text as well since you'll have to figure out what object it belongs too etc...
Either way, by text is probably faster but harder to maintain
NG Missing Script Recovery checks for broken references, I do handle thousands of assets.
I did not implemented multithreaded algorithm, but I know it's a way if I want to scale up
Yaml is not hard to stupidly parse
You can easily find the 'path'
But it is not out of the box obviously
But hey, you did it already and it works
If it works, it works! Gj
Exactly why I'm not in a hurry to rewrite it
Oh wow! haha. I can't wait to get there one day. I have a project that I do a lot of learning in and is open world and a place where basically I try to implement everything I do in for fun. NO WHERE even close to that amount yet haha
can you make a method that is a customtype instead of the class itself? Or is there a way to access an inspectorsGUI from other scripts?
Like, I know how to make custom editors automatically themself, but, have been wondering this
What
exactly, I did not understand a single statement as well 🙂
Sorry! When I use [CustomEditor(typeof())] is it possible to use this attribute on a method instead of the class?
no
You can make your own attributes though if you meant that
I need to learn that. You guys keep giving me more on the todo list haha
Anyone know a working way to rotate an image in the GUI other than the broken https://docs.unity3d.com/ScriptReference/GUIUtility.RotateAroundPivot.html
the image gets rotated but half of it gets cut off
That is how you are meant to do it. If it is not working it is most likely be cause you are not doing something quite right. If not than it is a bug that should be reported. Can you show a screenshot of what is happening and show your code.
It's a known bug since 2007 *Edit: it may be since 2013 and I got my dates wrong but let me double check
I'm just not sure if there's a "known" way to get around it
Quick googling let me to find what you are talking about.
thank you for looking at this, those two links describe the problem -- if you rotate using the rotatearoundpivot it is clipping to the original rect (which obviously cuts off part of the image if it's not a square)
I think the way to "fix" it would probably just be to draw it to a new texture and then try and rotate that before drawing it, but it's just a pain. No worries if you don't find anything thanks for checking!
There is an internal class called GUIClip and it has .Clip(...) and .Unclicp(...) methods. This is just a guess, but you maybe could try calling one of those before/after your 'draw' methods(s)?
That's new to me I'll check it out thanks!
Sure! Again it is internal so you would need to use some reflection to get it. https://github.com/Unity-Technologies/UnityCsReference/blob/master/Modules/IMGUI/GUIUtility.cs#L351
@gleaming adder And just because I had it up. This is the code for the RotAndPivot if that helps.
// Helper function to rotate the GUI around a point.
public static void RotateAroundPivot(float angle, Vector2 pivotPoint)
{
Matrix4x4 mat = GUI.matrix;
GUI.matrix = Matrix4x4.identity;
Vector2 point = GUIClip.Unclip(pivotPoint);
Matrix4x4 newMat = Matrix4x4.TRS(point, Quaternion.Euler(0, 0, angle), Vector3.one) * Matrix4x4.TRS(-point, Quaternion.identity, Vector3.one);
GUI.matrix = newMat * mat;
}
Thanks!
okay, I fixed my problem by just copying the ScriptableSingleton over and changing its : ScriptableObject where T : ScriptableObject to : Editor where T : Editor
Why do you need a singleton of an Editor...?
editor extends scriptableobject already and allows me to maintain the customtype of the scriptableobject in build
Yes I know that it extends it already. But why do you need a singleton instance of an Editor?
Because he is not aware of CreateCachedEditor()
ya that
Or he has something malicious in mind
I feel like whatever it is that you are doing, you either shouldn't be or you are going about it in a bad way.
I'm not sure if malicious, but, I was using it to create scriptableobject data that was saved and loaded on recompiles and also take advantage of this filepathattribute you guys were talking about
but still learning this editor stuff didn't know about things like this createcachededitor
You should not be doing that with Editor class. If memory serves, they already should persist on domain reload.
Hmm I'm not sure. It's old Unity info, but I read that people already use scriptableobjects to save editor data, so, I was trying to remove the middleman and just make the editor script the scriptableobject already. I mean, it works, but, if it's doing something bad I'd like to know more
They are recreated when the code recompiles and properties are reapplied
But they won't persist between sessions
Nor if it's destroyed by e.g. deselecting
yeah, so doing it this way I don't need an extra SO and instead just save this editor as the SO and maintain the customtype on it also
when I load back in the donkey kong remains
between sessions
but again, IDK if that is malicious?
Nah
okay, cool! Thanks guys! Enjoy the daily convo and help
In UITK I have an container with flex direction row. It has three children, the first two have set width while the last is a text field set to flex grow.
It seems the field is growing the the full width of the parent container, and completely ignoring that some of the width is taken up by the other two elements, so it goes offer screen. Any ideas why it does this, and more importantly how to fix it?
I'm not familiar with uitk elements yet, but, I'm confused by the wording what you have set to prevent the textfield from doing that? For example, you might want to make another parent for the textfield itself
then you can specifically constrain the textfield without anything happening to the other 2 elements
It should automatically not go beyond the bounds of it's parent unless the position or margin is explicitly changed so that it does. I think it is just a matter of finding the right combination of styles.
It makes sense once you are familiar with UITK.
Flex grow should just grow it to take up the the available space in it's parent, but for some reason it is not registering that the other two fields are in-fact taking some of that space up.
I've only messed with UI so much to the point I know it required more depth studying of it lol
UITK is a lot like web dev with XML+CSS if you are familiar with those.
I am not. I shouldn't even really be working this deep into Editor stuff yet, but I find it so enjoyable
Yeah, it is really fun sometimes. Other times, like right now, I am in the 5th circle of hell...
I DID IT! Thanks for all of your help guys!
280 lines of code, and I have a button that reimports textures in the correct format, crops out the extra transparent borders, and repositions it to be in the same place as before the cropping. All without modifying the original asset file (png or whatever format)
Yay! Nice job!
Does anyone know how can I draw a custom inspector for a custom class which is not derived from mono behavior?I want to make this int field visible if allow sell is checked
You inherit from PropertyDrawer instead of Editor and add the [CustomPropertyDrwer(typeof(MyNonMonoType))] attribute to the class.
IDK if any of you are like me, but, tfw you wake up in the morning and close a 100 tabs in browser because of opening a new tab for everything you search for Unity
In UITK, I have a PropertyDrawer for a collection type. But I can't figure out how to update the elements in it on Undo/Redo. Any ideas?
the last comment I think
Nope, that doesn't handle undo/redo or serialized properties. But thanks.
oh okay. Trying to see if I can find anything
how about https://forum.unity.com/threads/propertydrawer-with-uielements-changes-in-array-dont-refresh-inspector.747467/
It talks about convoluted routes though
PropertyField needs to be bound to a SerializedObject to show something. When creating a visualTree from CreateinspectorGUI(), the editor automatically binds the created tree to the inspected serializedObject. Any element added afterwards will need to be bound manually by calling Bind(serializedObject)
Yeah, I just found that my self too.
oh okay cool
I'm just trying to help because i know there is sooo much info out there for things that google searches don't always give the desired results. I'm all about more eyes on something can help find things haha
Yeah, I appreciate it! It seems like there is some sort of behind the scenes stuff with IBinding and INotifyValueChanged where together they can listen for changes to both the property and the UI field.
Hey so does anyone know where the xbox live configuration wizard is in unity 2021.3.11f1 personal?
Does anyone know how to use sprite sheet as custom font in Unity? I have this sprite sheet and I want a text object in Unity to use this sprite sheet as the font.
TextMeshPro
There are plugins as well that you can download from the asset store, but TextMeshPro is included
Is it possible to start an editor coroutine that persists domain reload? I'm a noob when it comes to build pipelines, but we're trying to make a routine that runs our build operation. The issue I'm running into is I think the coroutine is getting wiped when unity recompiles for a new build target and the domain is reloaded. This seems like something most build pipeline ppl probably have to work around, does unity provide anything to help in this matter? Or does the build operation need to get chunked up into distinct pre-build, post-build logic?
tldr: can I use an editor coroutine to author my build pipeline flow without the domain reload associated with recompiling for different platforms killing it?
You can't.
That was my fear, thank you for confirming. Do you have any advice or references on how to author a build pipeline knowing that your code will get wiped by domain reload?
Use EditorPrefs ou SessionState
Write a kind of serializable coroutine
Serialize it in the SessionState.
When it reloads, check SS if anything is available, boom deserialize then proceed
Easier said than done
thank you, that makes sense 👍
I have started to make my own coroutine a long time ago
I already planned on making it serializable
I never finished it
I don't know if it solves your issue
sounds like a tough problem to solve in a generic way, but I'd be your first customer 😉
as always I appreciate you sharing your expertise, I'll check out the link!
My pleasure
Several publishers use it for their publishing process
Well it seems the replacement is RockTomate :
https://forum.unity.com/threads/released-rocktomate-automate-repetitive-tasks-in-unity.814203/
Re-asking my question from yesterday. Any ideas why a UITK element set to flex grow would ignore the width(defined in uss) of it's siblings and grow to take up the whole space of it's parent instead of whatever space is remaining?
Is the element itself the container?
in HTML/CSS we often use nested containers to manage that sort of stuff
Though admittedly, it's been a long time since I've done HTML/CSS stuff
And I know I've seen some interesting behavior from HTML/CSS
The problem was that for some reason all of the elements had their flex shrink set to 0.
That... does seem bizarre.
I made an editor script, am I allowed to show some screenshots in here or nah? 🤔
Yup, sure are! I for one love seeing cool things done in the editor!
nice 🙂 I'm not done yet but basic features work, will post a short mp4 when I'm done (maybe this weekend)
I'm working on an editor tool called Rainers 3D Text Mesh Builder.
You can create and modify 3D text in scene view and at runtime.
https://cdn.discordapp.com/attachments/712708247290642523/854923908439343134/unknown.png
https://cdn.discordapp.com/attachments/712708247290642523/854905599674548264/unknown.png
(lol yes the inspector image was taken later again, that's why the text isnt green 🙈 )
Is there a way to set the thumbnail of a .asset file from Unity's C#?
Yes
Is there a way to edit an array of a class (which is serialized) in a custom EditorWindow
Yes
SerializedObject
I've tried
How hard?
Show me
wavesProp is null, right?
yeah
waves is private and not serialized
Well, make it non null 🙂
okay thanks I didn't know the field had to be Serialized like in the normal Inspector
It works now thanks guys
Dont think the serializer orbits around Inspector.
The serializer is the ground for everything
xD
Ok... Uhhhh How?
Do you know how to do it without code?
No. nor with code. I found "AssetPreview.GetMiniThumbnail" and thought maybe I could use that to get the Texture2D and then use SetPixel32 to change the image to a proper thumbnail, and then use Apply, but the problem is that I don't know if there's an easier way nor if that method will give me the reference to the Texture2D or a copy
An asset is based on a script.
The icon comes from this script.
If you set an icon on this script.
The asset will reflect it.
Hmmm. Well, I suspect that the original script doesn't implement that. Is it a magic method or a magic property/field?
No magic
If you just want all of the SOs to have the same icon then just set the icon of the script. Otherwise if memory serves it is just a internal/private m_Icon field for each SO.
I don't think it's an SO
If it is a .asset it is a ScriptableObject
It's a game object saved as a .asset file and then a bunch of GOs added to it.
ahhh
But it derives from MonoBehavior? I don't have much experience with SOs
Nope, ScriptableObject derives from UnityEngine.Object
No, I'm saying the script at root game object is a script that derives from MonoBehaviour
I am honestly not sure what you are talking about now.
Create a game object, save it as an asset, then open the asset and add game objects to it. Assign a monobehaviour script to the root game object, and you have what I have
Alright, that is called a prefab.
Anyways there's still a m_Icon you can set
Is the ObjectPreview the thumbnail?
Here is what each one gets you.
Pick what gets the result you want.
I guess the MiniThumbnail, but if I use that method to get it, can I change it?
like if I overwrite the pixels, and then apply, will that change the icon?
or would I want the cached icon?
probably cant on most
Yeah, and even if you can, I feel like that isn't a good thing to do. Using reflection to set m_Icon is probably what you want to do.
So, as far as reflecting, is that in "GameObject" or "MonoBehaviour" or "Object"?
Also, what type is m_Icon?
Wait... is m_Icon part of SerializedObject?
@gloomy chasm
hey guys, is there a way to draw a debug label in world coordinates, without adding any object to the actual scene? I'm trying Handles.Label but it seems to be only in regards to the camera?
You can convert world point to screen/viewport point
think I am using nameof(T) wrong? It was working at one point, but, now it is just returning the character T on valid methods instead of the name anymore
MechWarrior99: I'm having trouble finding m_Icon. I'm not sure if it's part of SerializedObject/SerializedProperty, or Object, or MonoBehaviour, or what it's part of. Do you know where it is that I'm looking for it?
SerializedObject/SerializedProperty only let you access data that is serialized, so it wouldn't be there.
It is a member of Object if memory serves. You should be able to access it via reflection or from the serializedobject.
That is the expected behavior. nameof(...) basically just converts whatever text is between the parenthesizes to a string. What you want instead is T.GetType().Name
tyty
I want to see the labels from the scene view not game view, any possible way to do this?
What is it that is the problem...? I gave you the solution I thought... you use the sceneview camera to convert from a worldspace point to a screen space point and use that for the position of the Handles.Label.
that literally fixed all my problems I have bee having for days after I realized T kept returning instead of the proper things this morning...
You've now become a greater programmer thanks to the great wizard MechWarrior99 🧙♂️
yeah, I tried using
SceneView.currentDrawingSceneView.camera
and unity crashed
haha and because of you and other people in this channel, you guys always so helpful
Aw thanks!
Naaah, I stopped helping people, I just drop one word or two once in a while
LOL, I can understand why. I appreciate your one or two words of help when you give them, generally they solve/help solve a difficult problem I was having!
You've helped me. The basis of my singletons right now derive from your help
Oh btw, I figured out how to search for and hide fields in the inspector based on their label. However I decided to put it on the "Maybe I will come back to this at some point" burner because the only way to do it is to set the target for the IMGUI Debugger, than get the draw/other commands.
But I also crashed unity 3 times while doing, and it seems rather unstable... Also of course doesn't work with UITK so would need another system for that.
My bad, I meant that for @onyx harness...
hey, I still enjoy knowing haha
I've been debating using more labels speaking of that
Too may replys in one spot for my brain 😛
seems that using things like findassets with labels is the most superior way to findassets for example
Why do you say that? I think it is just an O(n) search regardless. I could be be wrong though.
I should have been more specific. If dealing with multiple assets with the same name, same type, etc... It is just another way to distinguish results. So been debating creating them for extra precautions when using things that can potentially have multiple of the same values
Doing so in pure UIT is much easier, as you can pick the container and hide it
Yeah! Only difficult part would be having to backtrack from the label to find the actual control to hide/show.
Looking at playing around with LockReloadAssemblies if I'm creating and removing assets, is the creating of changing of a script the only time I need to actually have an assembly reloaded?
Or deleting or moving
But it won't trigger so no need to lock them yourself unless you're doing something with code gen or something
I keep getting scared to ask things like this. This works, but, is this a good way of writing something like this?
other parts if relevant to my question
I value you guys as really smart and things like this as a waste of your time, but, also you guys are the only people I feel like I can easily ask silly questions like this to
Firstly thing, why are you getting the script asset?
just to keep track of it. Basically I'm creating this Enums default folder in assets, but, if the user moves things around and changes things, including the GUID, to be able to essentially refind it all
Also, there is no reason to store the path in a serialized field if you have the GUID. If you want you can just cache it in a none serialized field. The GUID will never change for any asset, and getting the path from a guid is quite fast.
In two of the if statements you get and return the guid but don't save it so you will have to get it each time.
The only reason I can think of a guid changes is if a user manually opened the YAML file in a text editor and changed it. Needless to say they should most definitely not be doing that and they get what they deserve if something breaks 😛
yeah, I'm going to setdirty the SO I have it saved to. I just haven't put that in. Also, I saved the path for cross referencing since I assumed if for some reason, and I know that is a large if, the path exists is valid, but the GUID isn't, it would be faster to get the GUID from the path than other methods?
No, I mean you are never setting the data to begin with.
Also, the only reason the GUID would not be valid is if the asset was deleted or manually edited like I said before.
I agree. I just wanted to make sure basically lol
oh, ya, I have it so if the that SO doesn't exist it will create it and set the GUID. I didn't share that part
whoops
I would get rid of it. It makes the code more complex, it is easy enough to just find the asset again if the guid is invalid. Especially since if the GUID is invalid it is most likely that the path will be too, and it will only happen rarely.
true, okay!
Cool, but that is still not what I mean.
....
if (IsValidPath(enumDataScriptPath))
return AssetDatabase.AssetPathToGUID(enumDataScriptPath); // you just return, you never set enumDataScriptGUID so you will have to get it every time if the path is valid.
...
I mean it doesn't matter now since you are removing the path stuff, but still.
yeah, I just realized that now. Thanks for points that out, forgot to edit that
The in in your foreach loop is redundant. You are already only searching for assets with the EnumData name. Unless I am missing something.
it works because the path was valid in my testing haha
no, when you search by name in this way, it's a contains, not equals, so if there is any other monoscript in this way named lets say something like EnumDataP or something, it will also showup in the search.
Ah yeah, I realized that after I sent the message.
I also did it this way instead of one of our previous ways we talked about on the check for the guid length because of the errors unity throws having mulitple classes with the same name I knew if I could just get exactly "EnumData" it would have to be the right script, though, after talking to you about this I haven't added any checks for namespaces
No one will actually delve this deep into this for a lot of these things to be a problem, however, I have fun thinking about what if and seeing if I can solve it haha
Show the code.
Tried this:
if (sProperty is null)
{
sProperty = property;
var iconProperty = sProperty.FindPropertyRelative("m_Icon");
Debug.Log($"Type of Icon: {iconProperty.serializedObject.targetObject.GetType()}");
}
if (sProperty is null)
{
sProperty = property;
var iconProperty = sProperty.serializedObject.FindProperty("m_Icon");
Debug.Log($"Type of Icon: {iconProperty.type}");
}
if (sProperty is null)
{
sProperty = property;
var iconProperty = sProperty.FindPropertyRelative("m_Icon");
Debug.Log($"Type of Icon: {iconProperty.serializedObject.targetObject.GetType()}");
}
and this:
Texture2D Icon
{
get => (Texture2D)IconFieldInfo.GetValue(rootObject);
set => IconFieldInfo.SetValue(rootObject, value);
}
public LayerShrinker()
{
var goType = typeof(UnityEngine.Object);
var goTypeInfo = goType.GetTypeInfo();
IconFieldInfo = goTypeInfo.GetField("m_icon");
Debug.Log($"m_icon is a {IconFieldInfo.Name}");
}
I tried in place of UnityEngine.Object GameObject and MonoBehaviour
IconFieldInfo is readonly FieldInfo IconFieldInfo
I also tried the other way of getting the icon from PrefabUtility and modifying the resultant Texture2D and it's not "readable"
What is sProperty?
sProperty is SerializedProperty sProperty and is assigned first with the property from OnGUI or GetPropertyHeight
Whichever is run first
basically both check if the value is null, and if so, sets it to the property passed to either method
You can't get fields like that from UnityEngine.Objects. You need to create a SerializedObject of the value and then get the m_Icon property from that
That's what I tried in the first three snippets isn't it? or....
Nope, it isn't.
What value type is sProperty?
... oh you mean of sProperty.SerializedObject.targetObject?
No, I mean the sProperty it self
I have no idea
What....
I can tell you that sProperty.SerializedObject.targetObject is LayeredCharacterBehaviour
Then how are you expecting to get a field that is only on UnityObjects from it...?
You are in affect trying to get a Texture2D field from a float field. It is not possible at all.
Ok. That makes sense, I need a SerializedObject for the root game object right?
It is like doing
float foo = 2.5f;
foo.m_Icon = new Texture2D();
Ok
So how do I get the SerializedProperty or SerializedObject of the right type
sProperty is property in public void OnGUI(Rect position, SerializedProperty property, GUIContent label)
Just try getting the field from the serialized object since that is a serialized representation of a UnityEngine.Object
I did that in snippet 2
if (sProperty is null)
{
sProperty = property;
var iconProperty = sProperty.serializedObject.FindProperty("m_Icon");
Debug.Log($"Type of Icon: {iconProperty.type}");
}
What is the serializedObject of in this case?
But if I'm understanding you correctly, that's not right because that's the serializedObject for LayeredCharacterBehaviour which is a script attached to the root game object of the prefab
serializedObject is the serializedObject of the serializedProperty of the LayeredCharacterBehaviour class which derives from MonoBehaviour and is the attached script of the root game object of the prefab
Looks like MonoBehaviors don't have it. I just tested it with prefabs and ScriptableObjects and it worked fine.
Is there a way to get the SerializedObject of the prefab rather than the MonoBehaviour?
If all you have is the latter?
var comonent = (MonoBehavior)sProperty.serializedObject.target;
using (var prefabSerializedObject = new SerializedObject(comonent.gameObject)
{
var iconProperty =prefabSerializedObject.FindProperty("m_Icon);
}
There you go @ivory fulcrum
Alright, I'll try that.
Thank you
Oh. One last question. m_Icon, is that a Texture2D or something else?
yup
yeah
iconProperty.serializedObject.targetObject = (UnityEngine.Object)rtex.ToTexture2D(); the object is read only?
rtex is a render texture
is this what I want?
iconProperty.SetGenericValue(rtex.ToTexture2D());
n/m that's Naninovel specific
And it's only for generics
you can't assign to targetObject because it's readonly
And it's null
Yeah of course. Why are you trying to set the target of the serialized object?
https://docs.unity3d.com/ScriptReference/SerializedObject.html
Show me your code please.