#↕️┃editor-extensions
1 messages · Page 32 of 1
there is. check the doc page for Gizmos. Handles also has some extra stuff
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Gizmos.html
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Handles.html
I presume you have one already and it only runs in the editor anyway.
You can use #if UNITY_EDITOR too
is there something to make the inspector for LocalizedString suck less? 🥲
Make your own? 😂
FYI there's also this https://docs.unity3d.com/6000.0/Documentation/ScriptReference/IMGUI.Controls.BoxBoundsHandle.html
If you want to modify them in the scene view (and don't want to use the default box collider editor).
That is very cool, not exactly what I need right now but it might come in handy in the future. thanks
Anyone else having issues with Unity Version Control lately? Getting the error: "Not connected. Trying to re-connect..." ...and when I click "Try now" nothing happens.
I'm working on a wizard that's adding a component to a prefab prefab, however if I look at a prefab variant of said prefab, the added component appears as removed
How can I fix this? Do I just add the components to the variants as well?
Or do I need to use something in Prefab utility?
Or you need to use PrefabUtility.RecordPrefabInstancePropertyModifications() for the changes made in code to be save-able.
got it, thx
No I don't think so. That is for property modifications. Adding/Removing components and gameobjects are handled differently.
mb i thought that was to apply it to the actual prefab vs an instance
i usually edit prefabs with prefab utility by opening, do my changes, then save and its usually good
IMGUI or UIToolkit?
I mean are you using IMGUI (Stuff like GUILayout.Button() or UIToolkit (stuff like new VisualElement())
The Inspector is UIToolkit in modern versions of Unity
Ah, I'm using IMGUI.
You should be able to use the...inspector(?) to look at how it works
(i forget the exact name)
ah, okay, not relevant then
I think fields should do it automatically when using IMGUI
It's just cause there are cases when i try to make my own custom ones.
I want to try a hand on a serializable nullable and just slapping a tickbox next to the field.
Some useful links
Though if you are on 2022 I would recommend just using UIToolkit instead. It is normally easier and is more modern
Aight thanks.
Later. 
IMGUI is effectively obsolete in Unity 6. By that I mean, everything new is being made with UITK and a lot of the thing that were made with IMGUI have been replaced with UITK implementations.
Is there some dated tutorials for UITK?
Yeah some tutorials are a bit dated. But most should still work.
How to check if a game object is being edited from prefab menu?
PrefabUtility.GetPrefabAssetType and PrefabUtility.GetPrefabInstanceStatus just says it's not a prefab.
I guess that's true.
PrefabStage ?
If someone knows off the top, how can i move it location in the order?
Seems it might not be natively supported.
How can i check if an unityengine.object is a built in resource?
Maybe by doing asset database guid to asset path? If it starts with Assets/ then that should work.
I presume "built in" stuff is either going to have a weird/empty path or be in a package
yeah, the one i'm testing with (the quad) starts with Library
Is there any way for me to get the currently used camera in the gameview in an editor tool?
my editor isnt working, theres no autocomplete happening, how do I fix this?
Might have to use Camera.allCameras
Hello everyone, I have strange one problem with the Apple.Core package.
Plugin: https://github.com/apple/unityplugins
Available platform on my Mac:
• AppleTVOS.platform
• AppleTVSimulator.platform
• DriverKit.platform
• MacOSX.platform
• WatchOS.platform
• WatchSimulator.platform
• XROS.platform
• XRSimulator.platform
• iPhoneOS.platform
Command: python3 build.py -m simulators macOS
As you can see there isn’t visionOS listed, even though I’m not trying to build with that flag.
However when I use “add package from tarball” it doesn’t work properly.
I can’t change my Unity’s project version: 2021.3.45f1, but I know that this version doesn’t support visionOS. How can I create .tgz files with Apple.Core without visionOS?
Hi. I'm changing some stuff from an asset, so this is not my code
I wanna change the box rect size when he does Handles.Label
There's GUIStyle.fontSize
But what can i do to change the box rect size itself?
Are you using a version below unity 6?
yes, 2021.3.45f1
VisionOS was introduced in unity 6 I believe, so you’d need to switch to that version
But I can't switch my currently project to Unity 6, it's too risky and i'm not owner of this one. Everything what I need is create a .tgz files without checked "visionOS" as one of default option.
Well how big is the project? How much time was put into it?
The worst case, I'll implement the package manually and throw "visionOs" out in the source file but I'd rather to avoid that.
well, about 2 years :D?
Yeah that is pretty risky. I believe there is a workaround although it isn’t 100% guaranteed. You could try adding an AR framework to your Xcode and enabling it in unity’s XR plugin management. Might not give you 100% of the benefits though and may be quite tricky
just open the archive using 7z or nanazip or winrar and modify it to your needs
but a project in 2021 is gonna suffer more moving forward
I tried, but after this operation I mean "compress" again file to tgz. import to the Unity doesnt' work ;x
packages can be used if you extract and put them in the Packages/ folder btw
7z and other programs can make a tar archive again anyway
but it doesnt' work properly because of metadata inside of .tgz
or maybe I used to use wrong program to archive
I will check it
a .tgz is just a compressed .tar archive its not anything special to unity.
If you really are struggling then use tar to archive again on a mac/linux/wsl
I will say i find it very weird that apple cant just have ready made packages to download why make the user run a py script.
Or hell why cant they make the repo a valid package to begin 😐
Yes! This is really annyoing
Tenjin is also bad they include the code they use to make the unity package IN the sdk 😐
@surreal girder hahaha, I just found the resolution
I didn't know before that a tgz is just a regular archive, so I tried to pack it again and now I noticed that when packing, it was getting packed like this: packageName/packageName/content, and that's why it wasn't working for me.
thank you a lot!
I have a set of "setup" components that I've been using for VRChat worlds. I believe that VRChat completely strips out non-allowed components during the build process, so I haven't had to think about that.
I want to start using these components in other projects. I'd rather not leave a ton of components scattered all over the built game that do nothing.
How straightforward is it to strip components from a scene during the build process?
I see that I can implement IProcessSceneWithReport to run code during the build process
(these components do things like placing prefabs and resizing reflection probes -- they are editor-only)
I guess I'll just make them self-destruct upon entering play mode for now (or just ignore them completely)
using #ifdef wont work for this, I assume? Was thinking it could have either the editor-only component code, or something to remove itself from the GO on load, depending on UNITY_EDITOR or somthin similar/custom.
This would be to prevent the component from existing at all
I already use a ton of #if preprocessor directives
because otherwise the build explodes due to all the UnityEditor references
And yeah, I can just make it destroy itself during Awake
The hide flag should apply to components as far as I know https://docs.unity3d.com/6000.0/Documentation/ScriptReference/HideFlags.DontSaveInBuild.html
nice! TIL (looks like it's for objects, not components but perhaps he can make that work!)
Components are objects. Anything that inherits from UnityEngine.Object counts as an object.
I am just not 100% sure if each component is processed when building. I think they are.
Should work for assets as well.
Though no clue why you would use it on an asset
ahh.. hideFlags is indeed a member of UnityEngine.Object.. so think your on the money!
I'll give that a try!
anyone knows where is the code responsible for the "Preview" button in the animation editor window ?
trying to figure out a way how to make a shortcut for this
i think i found it -> Editor/Mono/Animation/AnimationWindow/AnimEditor.cs#L1012 👀
dependency hell in Editor/Mono/Animation/AnimationWindow/AnimationWindowControl.cs#L361 💀
is it possible to make an editor extension for Unity that allows painting vertices kind of like vertex weight painting in Blender? The data you would paint can be anything
e.g paint 1 into uv3.x for the vertices you paint over
it'd be useful
Yes it is very much possible. You can get pretty far with the Mesh APIs and possibly compute shaders (especally if you want to paint textures)
That reminds me of my "poor man's substance painter" unity project that I should continue working on...
It supports 2D/3D painting, map baking (normals, position etc), and photoshop-style layers and paint layers with undo/redo
Do you need to paint vertices only or also textures?
There is most likely a free package on github and or the asset store that does it. I know the old ProBrush package or whatever it was called could do it. Though it is really old and clunky at this point.
Polybrush?
oh yea it has vertex painting stuff, have a look if ths fits your needs @young anchor
https://unity.com/features/polybrush
hopefully it still works 😐
for some reason, both Probuilder and Polybrush had enormous problems on my mac
the latter flickered like mad in the scene view
Probuilder also flickered a ton (and also had very weird undo problems)
I should look at that again in 6
(this was a while ago)
is there a way to make a popup with a search bar?
In IMGUI I have used AdvancedDropdown
It's pretty smooth IMO
I think there's something different for UITK if you are using that
advanced dropdown is what i needed, thank you!
is there like a builtin unity gui element thats like an angle selector?
Nope, but are pretty easy to make
for editor windows? how would you around doing it?
Using UITK or IMGUI?
IMGUI
its just something i plan on having on a scriptable object
to indicate a direction using a normalized vector
Well I guess either way is the same. You just get the angle from the center of the circle to the mouse's position.
but how would you like visualise that vector with an arrow
Make an arrow and draw it? Or you can use GL to draw lines.
I think you can rotate textures in IMGUI... now I'm not sure though actually...
i think im just gonna stick with a vector 2 for now then lol
Yeah you can set GUI.matrix to whatever you like
Ahh right, I was sure you could but couldn't for the life of me remember how. Thanks!
@dusk dome Found my old code for drawing a smiliar widget
https://paste.ofcode.org/mUB25mDTWZfDtLdnUDGabn
It returns a float angle though but could be easily modified to return diff instead if you want a Vector2
(maybe normalize it first)
looks great, thank you! where would i put this, though? would it go in an editor script or like OnInspectorGUI or
You can put it anywhere 🤷♂️ Maybe a utility class
You call it from OnInspectorGUI or similiar though, yes
okay cool, thank you!
it looks really good.
Is it possible to make an exact replica of Polybrush using UnityEditor and UnityEngine? Or because it’s a Unity official package, does it mean they might use features that normal developers don’t have access to?
cuz I was told this is going to be hard to build, I'm wondering if I need to use something like UnityEditorInternal, with like 0 documentation
i'd like to build it myself. even if polybrush fits my needs.
No it is just using the mesh API and standard scene view handles and input. Originally it was actually an asset that Unity bought along with ProBuilder (same devs originally)
It is fairly easy to make, but a bit harder to make efficiently.
As a high level overview. The way I would do it is start by making a EditorTool for your brush.
Then when activated you get the mesh from the GameObject and sort all of its vertices in to some sort of spatial partition (like a KDTree, or Octree). Then when you paint you query the spatial partition you made to find which vertices should be painted, modify their data, and then save the data to a new instance of the mesh.
Hi all. I'm doing this in SceneView.duringSceneGui
Handles.BeginGUI();
Handles.Label();
Handles.EndGUI();
This draws a box with content, text in the scene view
But how can i control the size of the box?
Why not use GUI/EditorGUI?
I'm getting some mixed results so far. If I set a MonoBehaviour's object hide flag property to 2, it disappears from the inspector when in a prefab stage, but it's still visible on instances of the prefab in my scene
2 is HideFlags.HideInInspector
When/where are you setting the hide flag?
I was doing that in Reset(), to make it easy to run
To be clear, hide flags should always work. I was refering to the fact I wasn't sure if during build components are processed, so not sure if the DontSaveInBuild would apply.
I've also just directly edited the property in the prefab asset though
Yeah, I'm just getting some weird results before I even get to trying DontSaveInBuild
That could be screwing stuff up due to the way reset works
Also, standard dirtying/saving rules apply
Oh
I was using the wrong component lmao
PlaceLinearLightProbes is not PlaceLinearPrefabs
that explains the lack of functionality of Reset, at least..
Is this insufficient to get Unity to look for changes on a prefab?
[ContextMenu("Test")]
void Test()
{
this.hideFlags = HideFlags.NotEditable;
UnityEditor.EditorUtility.SetDirty(this);
}
This works in the prefab view, but it doesn't prompt me to save the prefab, and the changes aren't persisted
either way, the flags don't stick to prefab instances, interestingly
I think a prefab stage is a scene technically but im not sure how you make it be dirty correctly
perhaps you can grab the current prefab stage and the stage scene as dirty
oh wait, this is for sub-assets of prefab assets
also interesting: setting the m_ObjectHideFlags property doesn't do anything persistent, but m_EditorHideFlags does modify the prefab asset
I'm just editing an asset
But got it figured out
Using HandleUtility.GetHandleSize, and GUIStyle.fontSize also determines the box size
Hi, is there a way to optimize pro-builder's work? It lags really hard (sometimes freezes for like second or two) on some meshes when selecting vert/face/edge and doing anything with them, even thought the mesh has only 370 triangles! Somehow it sometimes works just fine on a lot heavier meshes though...
Perhaps use the profiler to see what it's doing first
yeah, I think this is the first thing that should come into mind 😅
Okay, so the thing is you shouldn't use not unpacked prefabs if you are working with them using pro builder...
Just found out about https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Display.html
I can do:
var display = Display.activeEditorGameViewTarget;
target = Camera.allCameras.Where(a => (a.cullingMask & (RenderInLayers)) != 0 && a.isActiveAndEnabled).FirstOrDefault(a => a.targetDisplay.Equals(display));
I wish you could install an editor asset to a Unity version rather than having to add it to every single project.
Hi. I changed a field from an enum TileRuleMaskRotation _neighborShapeFilter, to TileRuleMaskRotation[] array
How do i update this code?
for (int c = 0; c < 4; c++)
{
TileRuleMaskRotation rot = (TileRuleMaskRotation)c;
var neighborShapeFilterField = UI.createEnumFlagsField(typeof(NeighborShape), "_neighborShapeFilter", serializedObject, rot.ToString(), $"NeighborShape {rot}.", toolbar);
neighborShapeFilterField.RegisterValueChangedCallback(p =>
{
applyNeighborShapeFilters();
populatePrefabViews();
});
neighborShapeFilterField.style.maxWidth = 100.0f;
}```
I try _neighborShapeFilter.Array.data[0]
But nullrefs
if i found two folder assets with something like AssetDatabase.LoadAssetAtPath (path, typeof (DefaultAsset))
how can I know if one is inside the other? 🤔
Do I have to manually crawl them and see if they contain each other? 🥲
Can I crawl up? (instead of "get children" something like "get parent"? 🤔 )
If they are folders you can just compare the paths. Like boo isPathAParentOfB = pathB.StartsWith(pathA);
🤔 that should work!
thanks ❤️
Hi everyone,
I’m working on a custom editor script to create a conversation timeline for my Unity project. I’m using Unity version 2022.3.41f1, and I’ve been following the documentation for EventType here: https://docs.unity3d.com/2022.3/Documentation/ScriptReference/EventType.html.
But like i get an EventType error for events like MouseDown, MouseDrag, and MouseUp.
Assets/Editor/ConversationTimelineEditor.cs(149,33): error CS0117: 'EventType' does not contain a definition for 'MouseDown'
Assets/Editor/ConversationTimelineEditor.cs(156,38): error CS0117: 'EventType' does not contain a definition for 'MouseDrag'
Assets/Editor/ConversationTimelineEditor.cs(162,38): error CS0117: 'EventType' does not contain a definition for 'MouseUp'
I'm really not sure whats going on but maybe im missing a namespace or im looking at the wrong section of documentation like the wrong version
heres the section im refering to and a pastebin of the full code: https://paste.mod.gg/ipjhtliiejvg/0
private void HandleEventDragging(Event e, Rect timelineArea)
{
if (e.type == EventType.MouseDown && timelineArea.Contains(e.mousePosition))
{
// Start dragging
isDragging = true;
draggedEventRect = new Rect(e.mousePosition.x, e.mousePosition.y, 100, 20);
draggedEventName = "New Event";
}
else if (e.type == EventType.MouseDrag && isDragging)
{
// Update position
draggedEventRect.position = e.mousePosition - new Vector2(50, 10);
Repaint();
}
else if (e.type == EventType.MouseUp && isDragging)
{
// Drop event
isDragging = false;
PlaceEventInTimeline(draggedEventRect, timelineArea);
}
}
as far as what ive done to resolve it, not much beyond research. i havent edited the code too much because idk whats wrong at all.
also this method gets called in another method which is called in OnGUI (for more see the full code)
and thank you in advance to all/any who help 🙏
A tool for sharing your source code with the world!
If you hover over EventType your IDE should tell you the full namesapce for it in a popup. That will give you your answer. My first guess would be the using UnityEditor.UIElements; at the top though.
Thank you for the suggestion, I think I’m already using that name space but I’ll try the hovering trick when I’m back at my dorm 🙏
I mean that you shouldn't be using that namespace 😛
But would that be causing an error though? Like will removing that really do anything? Just curious cus I don’t normally fix an error that way. Removing an unnecessary namespace. I’ll try it as soon as I can though
It would if the namespace also has a type called EventType (though I don't remember if it does).
it doesn't, ive just commented it out but the error persists. good point though. i thinkt the name space is just for ui elements like colors and buttons though i used it in an earlier script that i based this none off of and in that earlier one i had used different colors so thats why its there. i dont think i use it in this one but its not harming anything. Ill leave it out though since removing it didnt add or remove any errors
The errors seem to suggest that the Enum EventType doesn’t have values for MouseDown, MouseDrag and MouseUp
Similar to what mech warrior suggested above, could it be that your script is not referencing the correct EventType Enum?
EventType is such a vague name that I can imagine multiple exist
I FIGURED IT OUT, maybe... i think its a syntax error 😭 im pretty sure its mouseUp and not MouseUp and mouseDown and not MouseDown.
i added the line
Debug.Log(Event.current.type); that revealed this 🤦♂️
no i don think so i think its just poorly named (i mean i also have things with the word "event" used throughout the project unrelated to this so i cant blame them) im aware of what the problem seems to be i think the documentation is just wrong? or i looked at the wrong documentation? the debugging reveals a different syntax so imma just plug that in and see
... you're ide should show you all the available options when you do EventType.
If not then your IDE is not setup correctly
it shows up in the IDE, but when i do EventType. nothing special happens theres no drop down with options... the documentation features code that looks like what i originally wrote and when i debug to see the current event's type it returns mouseUp mouseDown``mouseDrag and so on but even after chaning M to m it doesnt work 😭 i wasnt really onto anything i guess also idk if my IDE isnt setup properly i mean i think it is but idk cus i only do things as problems arise i didnt really set it up i just downloaded things as i got errors that they were missing...
If you get no Intellisense drop-down when you type the Enum name then . then something isn’t set up correctly or you’re using an IDE with no Intellisense-like assistance
If your IDE is not autocompleting code
or underlining errors, please configure it.
Select one:
•
Visual Studio (Installed via Unity Hub)
•
Visual Studio (Installed manually)
•
VS Code
•
JetBrains Rider
• :question: Other/None
alr thx for ur help thus far 🙏 ill work on configuring the IDE and get back to yall when that's done. unfortunately i gotta call it quits for today cus ive got work to do but really thank you for your help on this. im def learning alot
okay I feel stupid
I can't figure out how to properly detect whether a user is holding the camera movement button in the scene view
the right click wasd movement?
theoretically it would be Tools.viewToolActive but it's false while holding alt for the orbit camera, it only kicks in and is true once you press LMB/RMB/etc
not sure if it's the same issue with the RMB first person camera, but I suspect it's got something to do with execution order
basically I need to override selection in my OnToolGUI, but I don't want to override camera movement
and for whatever reason I can't get it to cooperate, either the scene view selection is captured, and I don't intercept it at all, or, my script does intercept selection, but then the scene view is in a weird state where I can't give control back to the scene view camera anymore, so I can't turn the camera
I could probably solve it with an if event modifiers HasFlag(Alt) thing, but that kinda feels like a hack in case people have rebound it
okay yeah that pretty much solves it
bool IsUsingCamera => Tools.viewToolActive || Event.current.modifiers.HasFlag( EventModifiers.Alt );
but it feels a little gross
Is this to ignore a left/right click so it doesnt "select" a thing? (im guessing this is for your mesh editor thingy)
yeah! it's for my spline plugin in this case
but same thing
(basically I need to make a custom box selection)
but also, I just looked at the keyboard shortcuts rebind menu, and I don't think it's actually possible to rebind the camera alt key, so that indirectly solves the problem ahah
Pro builder appears to react to a left click visually if i hold ALT but not actually do a selection so there is some weirdness it seems 🤔
half-edge (my 3D modeling tool) is standalone now so I don't have to deal with scene view conflicts 
ah wait no hold on something is wonky still, this doesn't solve it entirely
or, uh, no, it does work, but sometimes something goes a little wonky
might've been me forgetting to check which mouse button was pressed/released
thanks for the rubber ducking y'all!!
💦
🦆
Hey, I'm working on an editor tool to create an "Ingredient" prefab for a project I'm working on, every ingredient is identified by it's own C# script which inherits from the Ingredient class, so when I'm creating a new prefab I also need to create that script.
as of right now it is successfully creating the script and the prefab but when creating the prefab it doesn't wait for the scripts to compile and adding the Ingredient class instead of it's newly created derived type.
Is this a consequence of it not waiting?
if so how do I make sure the editor script waits for the scripts to recompile?
when code recompiles the current managed state is lost as its all reloaded so your code needs to react to the code compile complete event to continue anything
That makes sense
I searched it up so you mean to make a function with the
[UnityEditor.Callbacks.DidReloadScripts] attribute?
Yea. your code is going to fully execute and then the editor will do the recompile and reload. Then you should get the call back. You will have to store some info somewhere persistent to react post reload
In my editor scripts, I am moving away from modifying C# objects and towards using SerializedObject/SerializedProperty to make all modifications.
Is there any reason to avoid reading C# objects? Assume that nobody else has been modifying the objects, since that'd obviously mean that the C# data doesn't match the serialized data anymore.
for example, I am writing a script that removes badly-placed light probes
I am getting the serialized property for the probe positions and updating it properly
But I'm currently just grabbing LightProbeGroup.probePositions instead of reading from the serialized property
It is technically fine to do. Just know that if you do serializedObject.FindProperty("MyFloat").floatValue = 5;
And then do myObjet.MyFloat, it will not be 5 until after you apply changes.
Right.
For consistency though, and to avoid any potential bugs I generally always do my reading and writing via SerializedProperty
I guess you might as well go all the way
so that you get used to interacting entirely through SerializedProperty
Yeah, I think it would also make the code easier to read
...maybe :p
Vector3[] positions = new Vector3[prop.arraySize];
for (int i = 0; i < prop.arraySize; ++i)
{
positions[i] = prop.GetArrayElementAtIndex(i).vector3Value;
}
not the worst
I do have the lingering fear that I'm using SerializedObject/Property totally wrongly
- Construct an SO out of the target object
- Get properties and modify their values
- Call ApplyModifiedProperties
That seems to be the Right Thing
On larger projects I generally have a wrapper class that is something like
class SerializedPropertyArray<T>
{
SerializedProperty _array;
public T this[int index]
{
get{ return _array.GetArrayElementAtIndex(i).ExtensionToGetValue<T>(); }
}
public SerializedPropertyArray(SerializedProperty array) { _array = array; }
}
(It also implements things like IList<T> and what not for easy access)
Yup, exactly right.
SerializedProperty is sadly very old (close 20 years?) and clunky to use. So we kind just gotta deal with it :/
i never use it i just use the c# object. for prefabs i use prefab utility to load it. as long as its set as dirty it should be good
You won't get property overrides unless you make the changes with SerialzedProperty. Unless they changed someone I am not aware of.
Also, if you don't use SerializedProperty you have to manually record undos, and dirty.
if you use PrefabUtility.RecordPrefabInstanceModifications() it should pick up such changes
to my memory i havent had many issues yet doing it this way
it feels a lot more...murky that way
you have to cast a bunch of magic incantations or it explodes
i much prefer it to needing to grab the serialized property for anything i wish to modify. For what i usually automate in terms of scene or asset modifications its been fine so far
Yeah for doing automated processing it makes sense to do it manually normally I find. Though that is more of an exception than a rule for me.
really weird, so for some reason the wwise integration isn't working with unity 2021 (the label on Wwise.Event properties doesn't show up (if you know a fix for that lmk)) and not finding anything else i am debugging the editor code, and it seems the label is fine when it enters the function but the GetPropertyHeight Method sets its text to null. If I remove this line of code then it works, but the height is wrong. Whats going on here???
is this just a straight up bug
Does that property drawer or a property drawer it inherits from override the GetPropertyHeight method?
Sounds like a bug
Yeah it is a bug, but not sure if it is Unity or WWise
its a static method
wait
theres this with 0 references
so odd
There is a virtual method that is a memeber PropertyDrawer by the same name
i guess its a unity bug
Yeah seems fine, my guess is a Unity bug. But surprising.
You sure that objectreferencevalue is not null?
Sometimes those things can break during updates etc
well the method isn't being called
as far as I can tell
unless?
unity calls that?
There is the null check above it.
Also, they are not disposing of the SerializedObject, tsk tsk tsk.
idk how any of this would modify the contents of the label
I mean if it's null, it'll barely show anything
Ahh good point
Is that really needed? I searched my project and none of the packages are doing it, the docs don't mention it, and apparently SerializedObject's destructor calls Dispose:
https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/SerializedObject.bindings.cs#L50
Is it to put less strain on the GC or something
Huh, I could have sworn that I used to get an exception/error when the destructor disposed of it... could be fault memory. Though generally it is just good practice to manually call Dispose on things that implement IDisposable.
I'm unclear how important it is to immediately dispose of the SO
If that also applied modified properties, that'd be kinda handy
using var obj = new SerializedObject(...);
I might start doing this kind of thing.
!collab
:loudspeaker: Collaborating and Job Posting
We do not accept job or collab posts on Discord.
Please, use Discussions to promote yourself as job-seeking, advertise commercial job offers, or look for non-commercial projects to participate in:
• Collaboration & Jobs
Hi all. I have a struct[] in an SO that doesn't survive editor close open
public struct NeighborShape : IEquatable<NeighborShape>
{
// store as edges
[SerializeField]
public List<int> edgeHashesList;
}```
The SO
public class TileRulePrefab : ScriptableObject, IUIItemStateProvider
{
[SerializeField]
private NeighborShape[] _neighborShapes = new NeighborShape[4];
}```
The weird thing is, when i populate this within a unity session, when inspected, each of these lists are empty, even tho in code/debug log, they're not empty
what does debug mode for inspector show?
Oh wait, is struct not serializable?
No structs are serializable.
Same. Empty list
edit it only with the debug inspector, manual save and re open and see?
I mean it looks fine. Yeah do what Rob said, it might be Odin.
Yea may be the cause, if you edit it with odin and the file fails to change then you know
What do u mean by edit with odin?
that looks like odin inspector and not the generic unity inspector ui
TileRulePrefab are generated when i add some prefabs to this asset's own prefab library. I added custom stuff upon the creation to init the NeighborShape[], and the edgeHashesList in each of them. They're added properly, and the system that uses it are using it just fine
So, no i don't edit the list/the structs from odin inspector
if editor code, make sure to set the asset as dirty so it can be saved.
Check the asset to see if the changes appear at any point or vanish at any point
define "added properly" (:
It's easy to create data that doesn't survive a reload
even though it appears in the inspector
indeed. If it doesnt know its dirty or you dont save it manually it will just go poof
I had a great time generating animator controllers through code
If you don't make sure every single object winds up saved somewhere, it won't get saved to disk
e.g. blend trees
was that with importers? i've had issue making them save shit before
ah, no, not with an importer
the most I've done with model importers is rewriting mesh data
how to create search window ?
You can do most stuff via search service
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Search.SearchService.html
i want to select Type
t: & type: dint get any result
are you doing it in code or just trying to use the search UI? the type filtering by typing t: blah works just fine
didnt get what is that, but just like select type window
yah in code
from my experience what you can do with the search service in code is basically only do custom searches. you cant do much else like show other bits like this
go read the docs
cant i just summon select type window
its hard , tried but cant find any relevant stuff
i dont know, read the doc page and if its not a thing there then probably cannot be done 🤷♂️
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Search.SearchService.html
does ui toolkiy using same search srvices?
private static IEnumerable<SearchItem> FetchItems(SearchContext context, SearchProvider provider)
{
if (context.empty)
yield break;
var types = Assembly.GetExecutingAssembly().GetTypes();
Debug.Log("-------------------" + types.Length);
Debug.Log($"Total types found: {types.Length}");
foreach (var type in types.Where(t =>
t.Name.IndexOf(context.searchQuery, StringComparison.OrdinalIgnoreCase) >= 0 &&
typeof(ScriptableObject).IsAssignableFrom(t)))
{
Debug.Log($"Yielding type: {type.FullName}");
yield return provider.CreateItem(context, type.FullName, null, null, null, null);
}
}
did u know how to fetch all type of user defined object under UnityEngine.Object?or only UnityEngine.Object?
looks like you are half there already? if the type is assignable to MonoBehaviour then its made by us?
ofc you need to look in the correct assemblies and not an editor only one
yah half but only getting type that are not child of unitystuff ot just blank classes
You can just do
var types = TypeCache.GetDerivedTypes<UnityEngine.Object>();
var unityAssembly = typeof(UnityEngine.Object).Assembly;
var nonUnityTypes = type.Select(t => t.Assembly != unityAssembly);
Anyone know a way to check if a prefab is of an asset that is being edited? Or is the only option to check against the prefab stage content?
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
var typeProperty = property.FindPropertyRelative("type");
typeProperty.enumValueIndex = EditorGUILayout.Popup(typeProperty.enumValueIndex,typeProperty.enumDisplayNames); //error here
}
ok so im a bit out of practice and this line in a property drawer is causing
ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint
anybody know why this might be?
I saw a thing that said EditorGuiLayout isn't allowed in property drawers but I am using it just fine in another class
you shouldn't be using it in any drawer.
It'll always draw after every other property if you used it, which is incorrect behaviour
Why are you using IMGUI?
but then I have to learn that 😵💫
do you have any resources that would cover property drawers
Sure, though I don't really know why you would need to use it unless you were building something really complicated and weren't comfortable with code or UXML
I presume your code above would just be
public override VisualElement CreatePropertyGUI(SerializedProperty property) => new PropertyField(property.FindPropertyRelative("type"));
the code above is like
just the very first part of it
there will be a lot more
yeah there's style sheets and such
Sure, well you can do things via UXML or the UI Builder (which produces UXML) and then reference and clone the UXML, and bind to that
and reference style sheets in your UXML
Or you can do it all via code
with Property Field there's very little reason to write large editors unless they're totally custom setups that are tailored to a single UX like Timeline or Sprite atlas editors
i should probably note im using unity 2021
its reccomended for 2021 to use imgui? I wonder why
Mmmm, UITK is definitely more consistent in later versions. But I've been using it in the editor for a very long time
It's hard to give good recommendations for a version I've long forgotten 😄
I can't remember if it used UITK as the default Editor in that version
If you use IMGUI or UITK you should be amply using PropertyField, both have different versions of it
do you know how id make a popup with categories in UITK
i know that sounds weird but hold on
nvmd I can't find examples
Didn't find anything interesting in the PrefabUtility documentation, so the answer is probably your second option.
anyone ever started recording through OBS from a unity script?
For a research project we kinda need to automatize and synchronize events in the trial with the recording, which would be done best through a trigger in code
is there a way to prevent adding / hiding a third party behaviour?
I am using a plugin that includes a behaviour that confuses designers and they end up adding it where they shouldn't.
Can I hack something to hide it from the add component list or something? (without editing the plugin, if possible 🤞 )
I would begin by looking at the code that populates the component list:
https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Inspector/Core/AddComponent/AddComponentDataSource.cs
The source list appears to come from Unsupported.GetSubmenus("Component"), a native binding, so no luck there. But from there, there is some filtering performed. Most notably:
if (!hasFilterOverride || ModeService.Execute("inspector_filter_component", targets, menuPath))
I have no idea what ModeService is or what it's for. It is public, but not documented. It seems to be a service for managing different mode the editor can be in and I guess some components can be filtered in different modes.
If you're willing to include Harmony in your project, you can use that to hook into AddComponentDataSource and add your own filtering.
https://github.com/pardeike/Harmony
The modes are 'normal' mode and that 'safe' mode they added when you are opening a project that has compile errors, it gives you a popup asking if you want to open it in safe mode.
[CustomPropertyDrawer(typeof(StateAction),false)]
public class StateActionDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
// Create property container element.
var container = new VisualElement();
// Create property fields.
var typePopUp = new PropertyField(property.FindPropertyRelative("type"));
container.Add(typePopUp);
return container;
}
}
why is it saying no GUI implemented???
seems like you have to have the inspector be UIEements too? probably (hopefully) a unity 2021 thing
this manual is ass
it doesn't tell you how to get a property from the desired object
ok u just use serializedObject
now im getting this
which i have no idea how to parse
seems to happen when I render a list inside a list
dk what im supposed to do to fix that tho
ok I just had to make my own list renderers
issue is now how do I update the ui? I have a button that adds an element but idk how to make it refresh the list
I tried to add an element in the button code but that doesn't work, it only updates if I close and reopen
my understanding is that, with UIToolkit, you need to bind the UI elements to serialized properties
with IMGUI, your code runs every time the UI is redrawn. that's not the case with a retained-mode UI.
Yeah this is a 2021 thing. I think the nested list thing was also a problem that was fixed in 2022.
I'm sorry for the recommendation, in your case due to the old version it might not be best
However if you use IMGUI for a property drawer you'll have to manually calculate the height of your properties in GetPropertyHeight and manage the rects yourself.
In an Editor you can use GUILayout
Is there any way to automatically arrange all Nodes in a GraphView? I'm using it to display some complex data structures and I can't find a way to solve layout in a neat way
so I need to bind the VisualElement to the list?
I can only seem to bind it to the serialized object
which does nothing
I need to use a list view?
idk if thats really what I want
Bit of a weird request but does Unity have anything that allows me to prevent specific renderer components from drawing in scene view, without actually disabling them?
@queen wharf https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Renderer-forceRenderingOff.html Would that work?
Ooo maybe. Ideally i'd prefer to handle it more on the scenes end of thing's and not mess with the actual content but I would prefer this over disabling the component, thanks
If the tool isnt going to be running during play mode, be careful. It may be possible that this flag can get serialized to the scene/prefab data. Id run a test first to be sure. It doesnt appear in the properties drawer for MeshRenderer, or its debug options, but always double check!
That would definitly be a better choice
use that
pretty sure thats what the eye icon in the editor is actually manipulating
!install
- Make sure you have enough space including on
C:drive. - Check that it's not being blocked by antivirus/security programs.
- Look through the logs for a real reason why the setup fails they are pinned [here](#💻┃unity-talk message).
If you still have issues, perform a clean install in another location:
- Install the Hub and Unity in a non-system drive or a clean new folder in the root of
C:drive. - Failing that use the recovery Refresh option or reinstall OS entirely then repeat the previous step.
I'm using an AssetPostprocessor to modify some of my FBX imports. However, Reimporting the asset triggers a consistency error.
Importer(FBXImporter) generated inconsistent result for asset(guid:8860e14097e834844b851dcf1953b64e) "Assets/SM_Suzanne.fbx"
This is normal behavior from what I can tell, as I am add/deleting objects from my AssetPostprocessor script.
https://docs.unity3d.com/2022.3/Documentation/Manual/ImporterConsistency.html
However, I can't seem to figure out if there is a way to keep that error from popping up?
From what I remember Unity doesn't like you messing with the assets imported from model files.
did EditorCoroutineUtility get removed in unity 6?
rider might be buggin but just thought i'd ask
Nope, but maybe you don't have the package or are not reference its assembly definition
Definitely seems like that. Is there no way to tell Unity to stfu?
The asset script itself works fine. Just the Importer warning that's annoying
(moved from #archived-code-general) I'm having issues with my PropertyDrawers not actually binding the values of a PopupField in the inspector. What's the most appropriate way to share the code I've got so far without flashbanging the channel?
I think I might be able to show just the following. While the dropdowns are available in the inspector as hoped, they do not actually bind to the associated EL1 and EL2 variables in the Character class. None of the changes are saved or reflected.
[CustomPropertyDrawer(typeof(Element))]
public class ElementDrawerUIE : PropertyDrawer {
public override VisualElement CreatePropertyGUI(SerializedProperty property) {
var field = new PopupField<Element>(
property.name,
new List<Element>(Element.elements),
Element.SKY,
element => element?.name,
element => element?.name
);
field.BindProperty(property);
return field;
}
}
im running this in editor
[Button]
public void GenerateCollidersLol()
{
foreach(GameObject fish in FishList)
{
//find the SkinnedMeshRenderer component in fish children
SkinnedMeshRenderer[] fishRenderers = fish.GetComponentsInChildren<SkinnedMeshRenderer>();
MeshCollider mc = fishRenderers[0].gameObject.AddComponent<MeshCollider>();
mc.convex = true;
}
AssetDatabase.SaveAssets();
}
but im getting an error that the FishList was not assigned, but in the inspector i see it and it contains a bunch of gameobjects
Can you show the code for FishList?
there is none
i fill it in the Editor
public List<GameObject> FishList = new List<GameObject>();
Hmm, can you share the exact error? It all looks fine, maybe the error has a hint I'm not seeing.
Strange, put a Debug.Log($"FishList: {FishList}"); right before the foreach loop and see what it logs...
when modifying game objects in edit mode make sure to set them as dirty + record prefab modifications via PrefabUtility.
Does anyone have an idea what's going wrong here?
that doesn't make sense 🤔
id reset the component and add some stuff back again and see ifs better
i tried, same thing
i dont understand, maybe a unity 6.1 beta bug
Are you sure you dont have multiple MasqFishZones in the scene?
You can search by type t:masqfishzone in the hierarchy
And make sure that nothing else is instantiating it
Hmm, then we would see two logs though...
only one, 100% sure
hi i have a scriptable object with a custom editor. So far all good i can add different rewards to the reward list but when i hit play all the field of the reward disappear. anyone might know why
left is after i added in editor, right is in play mode
and after i hit play it stays like that
are you having the asset be set as dirty correctly? If you edit things then save project, does the file update with the changes?
i presume when you play the domain reload causes the non saved changes to vanish
Check the pinned messages (specifically the second one)
im using set dirty. maybe if i share the code is better
Reward is an abstract class, and the different types of rewards extends this
this is the SO
But a Debug.Log in the if(GUI.changed) statement to see for sure if it is getting called
it does
i solved it. Seems like abstract class are not serialized even if the subclasses are set to serializable. I think its because the main type is of Reward. I just made the reward class an interface and everything works like a charm!
Oh yeah you gotta set Rewards list to have the [SerializeReference] attribute.
I'm surprised anything was showing up in the inspector at all
and also combined with this yes. I forgot to mention
Don't need to have it be an interface, just need the attribute.
if i make it an abstract class it doesnt work
are you setting a non abstract type instance somewhere then?
in unity if a flags enum has a value with index of -1 it shows that name in the place of "Eerything" but when i try to draw a flags field in a custom editor that -1 value causes error in short it does not let me rename the everything option. let me know if someone has any alternative
i want Both instead of every thing
found solution
why only 9 items being shown in listview?
That doesn't look like a correctly populated list view. Are you using the makeItem delegates?
If you change the flex manually to create this wrapping I doubt it's going to behave at all
List view is designed to only be vertical or horizontal, not wrapped
yep using makeitem
isn't listview has scrollview in it?
I'm not sure why that matters
It's a virtualised scroll view, and the virtualisation controller expects a certain setup
but its working properly before
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor;
using System;
using System.Collections.Generic;
using GameInventory;
using Unity.AppUI.UI;
public class ItemDeckTab : Tab
{
private VisualElement rootDeck;
private VisualTreeAsset slotUi;
private List<ItemObject> inventory;
private GridView GridView;
private Func<VisualElement> makeitem;
private Action<VisualElement, int> bindItem;
public ItemDeckTab()
{
rootDeck = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/Inventory/Uxml/ItemDeckTab.uxml").CloneTree();
slotUi = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/Inventory/Uxml/SlotsUIEditor.uxml");
SetStyle();
PopulateItemDeck();
this.Add(GridView);
}
public void SetStyle()
{
label = "AllGameObject";
this.style.flexGrow = 1;
rootDeck.style.flexGrow = 1;
}
private void PopulateItemDeck()
{
inventory = UIUtility.FindAssets<ItemObject>("Assets\\GameAssets\\ScriptableObject\\Items");
makeitem = () => Makeitem();
bindItem = (element, i) => BindItem(element, i);
GridView = new GridView(inventory, makeitem, bindItem);
}
VisualElement Makeitem()
{
VisualElement visualElement = slotUi.CloneTree();
visualElement.style.minHeight = 140;
visualElement.style.minWidth = 360;
visualElement.style.flexGrow = 0;
return visualElement;
}
public void BindItem(VisualElement element, int i)
{
element.dataSource = inventory[i];
}
}
why items are not shown in grid?
Hello, I have a bit of a problem while working in PropertyDrawer.
I wanna show a variable in the inspector, so I do:
EditorGUI.PropertyField(valueRect, serializedProperty);
It works when serializedProperty is an int, float, array, etc, but if it's a custom class or struct (even if Serializable) it just draws a dropdown which when opened shows nothing. What could be wrong?
Can you show the class or struct you are trying to draw?
it's quite lengthy so gimme a few minutes to write something shorter to show what it is
ok this has everything (struct and propertydrawer, but cut down to not waste anyones time):
https://pastebin.com/4Kn4kL14
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
ok I figured it out sorta? Seems like a EditorGUI.PropertyField skill issue, using EditorGUILayout.PropertyField works. Honestly no idea what the difference is but it works
oh wait bruh you just have to set includeChildren to true 🤦♂️
should be set to true by default imo but thats just cope from me tbh
It won't work. If the drawer is used in any context where it's not the last thing drawn all of the layout elements will draw at the very end
well this ended up being a good solution ¯_(ツ)_/¯
hey so for some reason my custom editor is super laggy and im not sure exactly what to do about it
the way it works is I have one StateMachine ScriptableObject asset. This has a list of State each state has lists of StateActions. In order to allow the StateActions to be serialized they are not polymorphic, and instead have enum to list all the different action types, and then have all the possible parameters of each type of action and only the relevant ones for the current type are shown.
one of these is a list of actions in and of itself, to allow for if conditional blocks basically
everything actually seems to be fine until I add an elseActions list, then everything gets suuuuper laggy. Looking at the profiler the call thats taking up the most time is OnGUI? which is weird because lm using UIElements not IMGUI from my understanding
yeah
it doesn't even have to be like
shown or anything
i just add it to StateAction and it lags the fuck out
you can use [SerializeReference] to serialize a base type
You can turn on the deep profiler mode to see specifically what is taking up the time.
so ur saying I would want to make StateAction a polymorphic type
and then if I use [SerializeReference] on my list of StateActions
it will let me have a list with different types in it
without having a bunch of assets for every single action
I still am not 100% sure that would even work
Yeah fields with the [SerializeReference] attribute will serialize the field as a reference type instead of a value type. This means it supports polymorphism along with null values.
the issue seems to be the second list of actions just existing
and both lists would exist on the same type of StateAction
so im worried I got to all this trouble and it doesn't help
why would my solution be laggy anyway? I dont get it
Yeah the [SerializeReference] thing is a separate note for how to improve your system. Unrelated to your performance issue.
For the performance issue, I would enable deep profile to see the exact call stack for the OnGUI method
Also make sure you don't have the IMGUI or UI Elements Debugger window open
what are those
Windows used for debugging the layout and styling of IMGUI and UIElements/UIToolkit respectively.
But since you were not sure, I assume you probably don't have them open haha
I wonder if you're having problems with recursive serialization
Dang you called it
its probably related to that but its weird its fine until I add a second array
ah, perhaps because that takes you from
n steps
still dk how to parse this, why would imgui be called
to 2^n steps
fair
would the SerializeReference solve that? i have no idea
its weird bc why would recursive serialization be a big issue, most of the arrays are empty so it should just skip over it
If you look at the call tree, OnGUI is being called from IMGUIContainer which is a UIToolkit VIsualElement used for drawing IMGUI within UITK
Yup
If there is a PropertyDrawer that doesn't implement CreatePropertyGUI and only OnPropertyGUI
right
UIToolkit can embed IMGUI (but not the other way around)
I tried to make sure I never did that
As for the serialization. It depends on how your class' are structured.
If you have something like
class A
{
public B[] Bs;
}
class B
{
public A A;
}
That will mess it up.
because it serializes it as a value, and values cannot be null
A
Bs
0:
A:
Bs (empty)
1:
A:
Bs (empty)
idk if that makes any sense
whats the issue with that
its would only be recursive if Bs wasn't an array
Yeah, it should be okay, but maybe the serializer is still struggling with it. Or maybe it isn't as straight forward. (Again it really depends on exactly how the classes are layed out).
[SerializeReference] public StateAction[] ifActions;
[SerializeReference] public StateAction[] elseActions;
tried this for shits and giggles
and now im getting an error on this
property.FindPropertyRelative("type").GetEnumValue<StateAction.Type>()
is there some issue with getting elements of ifActions as a property? I would need to feed it a serializedObject somehow?
Because the value of a StateAction can be null
ohh
do I still get it as a property like normal
just somehow check if its null? idk how to do that
oh its like
objectReferenceValue or something
StateAction needs to inhert UnityEngine.Object right?
No, when you serialize a field with SerializeReference it change it so the value can be null.
Or polymorphics
ok ty
why am I getting type is not a supported pptr value when trying to check if its null
property.objectReferenceValue == null maybe its failing because its null? how else would I null check
ok so
turns out making all lists of StateActions into serialized references actually worked a treat
its running fine now
I could convert it into polymorphic types but I honestly kinda like the enum version? It makes it easy to swap between types
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor;
using System;
using System.Collections.Generic;
using GameInventory;
using Unity.AppUI.UI;
public class ItemDeckTab : Tab
{
private VisualElement rootDeck;
private VisualTreeAsset slotUi;
private List<ItemObject> inventory;
private GridView GridView;
private Func<VisualElement> makeitem;
private Action<VisualElement, int> bindItem;
public ItemDeckTab()
{
rootDeck = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/Inventory/Uxml/ItemDeckTab.uxml").CloneTree();
slotUi = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/Inventory/Uxml/SlotsUIEditor.uxml");
SetStyle();
PopulateItemDeck();
this.Add(GridView);
}
public void SetStyle()
{
label = "AllGameObject";
this.style.flexGrow = 1;
rootDeck.style.flexGrow = 1;
}
private void PopulateItemDeck()
{
inventory = UIUtility.FindAssets<ItemObject>("Assets\\GameAssets\\ScriptableObject\\Items");
makeitem = () => Makeitem();
bindItem = (element, i) => BindItem(element, i);
GridView = new GridView(inventory, makeitem, bindItem);
}
VisualElement Makeitem()
{
VisualElement visualElement = slotUi.CloneTree();
visualElement.style.minHeight = 140;
visualElement.style.minWidth = 360;
visualElement.style.flexGrow = 0;
return visualElement;
}
public void BindItem(VisualElement element, int i)
{
element.dataSource = inventory[i];
}
}
why items are not shown in grid?
Hello, I made my own PropertyDrawer script for an object. I then created an array of this object. If I add to this array and then press undo I get this error:
ObjectDisposedException: SerializedProperty [blabla].Array.data[1] has disappeared!
Is there something specific you have to do to handle undoes?
Hey all, I’ve been working on a suite of extensions I want to sell on the asset store, and it relies on some common extensions I use not only in this package but in general, so I’m wondering if it’s possible to import those additional extensions (e.g. by getting them from a public git repo) as a separate process when a user imports the main package. If not I can always just include a copy of the latest version of that code as part of the main package, but I was just wondering if that’s possible or if maybe it’d be blocked since it would be importing data that Unity did not verify with the package.
There are a number of assets that only install a loader/login thing via the package manager and download additional (or all) resources through a fully custom process that Unity has no control over. There is also no way to forbid you from doing that without destroying the usefulness of unity as a platform.
@crisp rapids @wild edge I would make sure to read the TOS and EULA. From what I remember, you are not allowed to download Packages automatically or even with a prompt (meaning a package manager, package). And all contents of a Unity AssetStore asset must be contained in the asset it self.
They could have changed it or I could be misremembering. So doubleing check your self is a good idea.
Good idea. I’ll check out the documentation
Thanks
you should tell that to the assets that break the TOS/EULA, i'm just reporting whats happening.
Sorry if it came off as I was trying to correct what you were saying. I have no doubt that there are assets that are doing it (that are not Verified Solutions Partners). The checking process isn't that great.
I just know from what I have seen that Unity takes rules about external downloads or verification more seriously than there other rules when reported. So while others do it, I can't recommend it.
Unlike other things like Harmony, where 'lots' uses it and Unity doesn't really care haha.
If they stopped using .unitypackage for asset store stuff it would be a lot easier
So, I have a bunch of objects that have procedurally generated meshes and materials and a bunch of scripts on them. I want to save these to an asset to re-use later without needing to re-run all the stuff that generates them. I tried saving the objects as prefabs, but they were missing the procedurally generated assets. How could I serialize an object to a prefab and keep all of this intact?
Well, the only way to save the mesh for a prefab would be if you saved it as an asset, or 'inlined' the data in to a component and re-build the mesh from that data. The meshes live in the scene, so if you save each as a scene, the mesh can also be serialized with it. So the first thing is to pick your poison.
Yeah, I need to know how I can save all these meshes as an asset
Hard to recommend since I don't know the use-case. But the most straight forward would be to get GetComponentsOfType<MeshFilter>() on the root GO and then check if the mesh is persistent, if not, then save it as an asset.
Not really sure there is a better option.
So, recurse through all children, save the asset somewhere, change the object to use that mesh instead of the procedural one, and once finished, use PrefabUtility to save it as a prefab?
Saving the mesh is as simple as calling AssetDatabase.CreateAsset and passing in the mesh, right?
Yes but also no. You can use GetAllComponentsInChildren to get all MeshFilter components in the entire tree.
When you call AssetDatabase.CreateAsset it automatically changes the reference to reference the asset instead of the instance.
And yeah you can just do CreateAsset, I think unity uses the extension .mesh for mesh assets.
You also just run this as a MenuItem and then manually drag-and-drop the GO to create the Prefab normally
How would I go about checking if a mesh already exists as an asset? All the ways I can find to check involve checking if a path contains an asset, but I need it backwards - I need to check if an asset exists at any path
EditorUtility.IsPersistant or I think AssetDatabase.Contains would both work
Okay, it didn't die this time, I'll have to wait a bit to see if it actually manages to finish. It's a large object
Too late now, but in the future you can actually disable auto-updating of the asset database when you do batch operations.
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/AssetDatabase.StartAssetEditing.html
Yeah I should have mentioned that before hand, I thought about it haha
Ooh they added a new disposeable scope for doing it in 2023 https://docs.unity3d.com/6000.0/Documentation/ScriptReference/AssetDatabase.AssetEditingScope.html
Welp, if I missed anything, I'll be sure to use that before running it again
You know, considering there's several thousand mesh files to create I probably should just force quit it and try again
Definitely a good call. Took about twenty seconds to generate as much as it did in twenty minutes before the change
Okay, got all the meshes working. Is there a good way to save all materials and their textures as well, or am I gonna need to drill down into the shader properties and look for everything with an image set?
Hmm, yeah if they are only being referenced by the material then I don't think there is a good way to get them sadly.

Thankfully, they're all using the same shader so once I find the properties I can just apply it to all of them, but I'll need to write the images out manually from the data
Almost there. Getting problems saving Normal Maps. My guess is it's this fucky way I apparently have to save a compressed texture:
Texture2D baseMap = mat.GetTexture(shaderPropName) as Texture2D;
if (baseMap != null)
{
RenderTexture renderTexture = RenderTexture.GetTemporary(baseMap.width, baseMap.height);
Graphics.Blit(baseMap, renderTexture);
RenderTexture.active = renderTexture;
Texture2D dest = new Texture2D(baseMap.width, baseMap.height);
dest.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
dest.Apply();
File.WriteAllBytes($"Assets/Temp/Textures/{mat.name}_{suffix}.png", dest.EncodeToPNG());
}
Attempting to save it normally says I can't save a compressed texture and from what I can see there's no way to un compress it other than this rendertexture hack. The issue with this is that the generated normal maps are very wrong. First image is original normal map that is part of the runtime-loaded asset. Second picture is what this process spits out.
perhaps the render texture format was not matching so it fucked the pixels?
How would I find out what format the texture is in? Are Normals usually in a different format than RenderTextureFormat.default?
id make it the same as the baseMap and see if that resolves anything
Okay, regenerating
Normal maps might need some special format because they are in the (-1...1) range instead of (0..1)
that is done in shader, and ofc if you are generating normals in code, you remap before writing the pixels
Nope. Can't just pipe one into the other apparently
id expect a normal map to be rgb only to start but that is an odd format choice
I don't know if that error came up on the normal map or one of the other textures
check the stack then?
Okay, it's the main texture. Not sure how knowing which one is the issue helps though
Can you just create a normal texture instead of a render texture? hopefully if you just get all pixels from the compressed ver and set in a non compressed one you can write to disk.
DXT is for gpu use only (so dont use that format for the new tex to write to disk)
I'll give it a shot. I only ever found people suggesting to use render texture when saving a compressed texture. Let's see if that's just cargo culting
Well DXT compression is good for gpus as its natively usable but in a file i presume unity cannot convert dxt -> rgb -> png
Right, that's what I'm trying to circumvent with the rendertexture thing
but its default format may be something better suited for gpu use once again
It doesn't matter if it's better for the GPU if I can't save the file
I need to be able to save the texture as a file, so I need a way to un-compress it
So try what i suggested, make a new texture in say RGB24, get pixels from compress tex and set pixels in RGB24 tex, then save to png.
Trying that now
It takes a while to run the conversion
Well, it hasn't died yet so it's not an error, but I have to wait for the conversion to finish to see if it saved the image properly
if it takes this long i hope you can upgrade from your potato
It's not a potato, it's that it's working on about a gig and a half of meshes
Doesn't help that all the futzing with the asset database means I have to restart unity a bunch
So, good news, it didn't save the normal as orange.
Bad news, it saved it as this
which is somehow even less useful
I'm going to try some other ways to copy the pixel data over
you may need to debug on the pixel copying cus something is certainly wrong
Graphics.CopyTexture did not work
But there's a bunch of other ways to do the copy
CopyPixels also no dice, it says there's an array size mismatch, despite the fact that the destination texture is literally created with the exact dimensions. Probably because of compression making the size not actually equal to the size?
Fuck it, for loop and math
Okay, GetPixels literally cannot be used on these textures since they don't exist as a file already
I'm out of ideas
is read/write enabled for this source texture? @simple bloom
Otherwise unity may not be able tocopy/have the pixels cpu side.
There is no source texture
They're part of a runtime-loaded mesh I'm trying to turn into a texture file
The whole point is to save it as a file
then you need a gpu only copy to a texture that is read/write able
that is what I am trying to do
I'm trying to copy this into a texture that I can then write
its confusing me even, there should be a way to make it work :/
I have a texture that only exists in memory and I want to save it as a file. I can't do AssetDatabase.CreateAsset since it can't create image files. I can't do EncodeToPNG because it's compressed. I can't do GetPixels because it's only in memory. CopyPixels shows an array size mismatch even though the definition was created with new Texture2D(baseMap.width, baseMap.height). Blitting it to a render texture works for everything but the normal map.
my last idea is a gpu copy to a read/write texture that is created with a DXT format, then you can get pixels cpu side and hopefully then unity can correctly convert to RGB, then write to new texture in some RGB format.
or perhaps a compute shader can do something 🤷♂️
the issue is probably the DXT to RGB conversion. I have used libs to do this conversion but not in c# (rust, cpp)
https://discussions.unity.com/t/runtime-generated-bump-maps-are-not-marked-as-normal-maps/632215/4
This explanation of DXTnm explains the output you were getting from the blit. It's orange-ish because the red and blue channels are pure white and only the green channel has actual data. The alpha channel contains what would normally be in the red channel.
But apparently you should be able to import DXTnm format normal maps directly in the editor.
Okay that definitely explains the why. Now I just need to find out the "how" of a fix
You could either do the channel swapping with a custom blit shader, or make sure to save all channels, including alpha, and then use the new swizzle option in the texture importer to do it manually.
dang good catch, unity bullshit strikes again
Okay, so, alpha channel of the in-memory texture becomes red texture of saved normal map. Green channel remains unchanged. What about blue?
Or is that just always 1 and that's why the normal map is always so purple 🤔
It will be white, which is standard for RGB encoded normal maps, so you can leave it as is
Yes
This should work for the custom blit shader:
https://paste.ofcode.org/VBYf4YciNL8dT2N2q8e698
I'mma be real with you have I zero clue how to use that so I'm gonna try to transfer it over using a nested for loop and hope that works too
Gonna take forever, vs no difference with a custom blit shader over the standard one
Just make a material using this shader and pass that into Graphics.Blit
And then blit the baseMap onto that instead of the temporary renderTexture I'm currently using?
No, everything else stays the same, you just specify a custom blit material
The blit shader is responsible for copying the source to the destination. The default blit shader, when you don't specify one, just reads the texture and returns it. This one reads it, swaps the alpha and red channel and returns it.
Ah, okay, so it's a third parameter to blit. Okay, I'll give that a shot
To make the material, it's simplest to just create it from code: var blitMaterial = new Material(Shader.Find("Hidden/DXTnmToRGB"))
Good I had hoped that was the easiest way because threading through a material to this otherwise was gonna be annoying
Moment of truth
The shader is untested, written from memory, so it might be missing some detail.
I see now other blit shaders often have this line:
ZTest Always Cull Off ZWrite Off
Might be needed, might not.
Okay not moment of truth, I have to restart because my AssetDatabase is stuck in editing mode again and won't reimport
There's no quick way to test this on one asset at a time?
Not without rewriting the code that pulls the meshes from source to only grab one
Okay, good news, the normal map is working!
Bad news: I forgot to check to make sure it was only applied to the normal map 
But that's an easy fix
Also, I don't know if the normal maps you're working with can ever be encoded differently than DXTnm. It's a PC only format, so other formats are used for mobile and etc.
That should be fine, I don't need to support other platforms
My god it's finally over
it looks a tad pale so may need srgb correction
but glad this is resolved, I learnt about dxt nrm today too
Is there a way to open a script from c# code as if i double click it in the editor?
AssetDatabase.OpenAsset
Perfect, thank you
one more thing, I have a ScriptableObject, can i somehow extract the script asset from that?
Oh my, thats perfect, works! Thank you very much
Hola,
I'm working with Unity and nvim, and it seems my scripts aren't compiling automatically on save.
This is fine in my eyes, I wrote a little Editor script that is supposed to request Script Compilation.
using UnityEditor;
using UnityEditor.Compilation;
using UnityEngine;
// Adds a hotkey to (re)compile scripts.
// Useful when Unity doesn't recompile scripts automatically.
// (This can happen when using external code editors like neovim)
public static class ScriptCompilationHotkey
{
[MenuItem("Compile/Force Script Compilation #r")] // #r adds shift+r as the hotkey
private static void ForceRecompile()
{
Debug.Log("Forcing script compilation...");
CompilationPipeline.RequestScriptCompilation();
}
}
However, it only seems to work sporadically??
Sometimes it triggers recompilation, sometimes it just shows the debug log?
Anyone who knows what may cause this?
even if you go back to the editor?
eeeyup
well visual studio has functionality to make the editor recompile early it seems but id expect the "normal way" to work...
not using visual studio x)
yeah is it maybe not picking up the changes on the filesystem for some reason? if you select the script in editor, see if you can see if your changes show up in the inspector
are you on windows?
changes do show up in the inspector
nah, linux
Is 'directory monitoring' off?
where's this?
Preferences > Asset pipeline
yeah it is
it's fine if it doesn't automatically refresh, it's just that I can't get my editor script to recompile manually work consistently.
if a script file is re imported it should trigger recompilation then. But the function you call should too...
To my understanding it should recompile when I call either AssetDatabase.Refresh() or CompilationPipeline.RequestScriptCompilation();
you dont disable auto asset database refreshing anywhere do you? via AssetDatabase.DisallowAutoRefresh()
nah, its an otherwise empty project
probably some dumb linux bug then if its not refreshing automatically (and is enabled)
it's been a while since i tried it on linux but in my experience the file change monitoring in the windows editor does work better, so my suspicion would be it's not seeing the changes to recompile them until you manually reimport
i guess your script could just reimport your scripts folder instead if that works?
hmm yeah maybe i could just click reimport manually i guess
this should work from code in some form so something must be broken or bugged
you should be able to do AssetDatabase.ImportAsset on a whole folder iirc, that should be like clicking "reimport" in the editor context menu
Seems like pulling some additional code from GitHub would be okay according to this language in the TOS
Thanks for the suggestion to refer to TOS. Should have thought of that 😅
I've heard that you need to click "tools" to disable the references thing
where is tools
not sure if this is the right place, but for some reason the top options keep disappearing in the UI dropdown
there's supposed to be at least 2 more things above raw image
restarting unity fixes it, but it is happening often enough to be an annoyance
The version of Unity you're using is old. They removed this style of menu because of bugs like these.
was that v6 or a later 2023 version?
Not sure what you mean. 2023 is Unity 6, I don't remember the exact minor version they reverted the menus
I miss that menu
the unity way, discard something instead of maintaining it 😆
maybe in Unity 7, but not holding my breath
I really wish there was a way to create editor extensions at the editor level rather than importing it into every single project.
you could, nominally, edit your project templates
I mean sure, but that is not ideal either, it is still imported into every project. For asset creators and consumers of them, it would be a nice option to have.
For example, if someone wants to use this asset:
https://assetstore.unity.com/packages/tools/utilities/vfolders-2-255470
They have to import it into every project and exclude it from source control, otherwise they force their teammates to have the extension as well.
It is tedious.
And if it is a github editor package, it is almost worse because you constantly have to have manifest / packages-lock excluded.
Then you get to a point where you need to add a runtime package to the project and have to do this dance where you remove it from the manifest just to commit, then re add it to the manifest after and exclude it all over again.
Oh, I see -- you're talking about a package that will never exist outside of your own editor
Yes
I see now. I thought the issue was just that you had to import a package into every project that uses it (which seemed like an odd complaint!)
Like basically one that is attached to my install
and can be used by every project because it is just a "pure" extension to the editor
I know this can kind of be achieved with symlinks but that has its own drawbacks like still having to create a symlink in every project, plus these:
-
Assets/[Folder] is a symbolic link. Using symlinks in Unity projects may cause your project to become corrupted if you create multiple references to the same asset, use recursive symlinks or use symlinks to share assets between projects used with different versions of Unity. Make sure you know what you are doing.
-
Disabling directory monitoring for current editor session. Found Symlinks in project which cannot be used with directory monitoring. Directory monitoring settings can be changed in preferences.
How can I check if a Field is valid to be set in a VisualElement property field?
I create a VisualElement property Field like
propertyField = new PropertyField()
{
label = nameReady,
bindingPath = field.Name
};
extensionContainer.Add(propertyField);
Once Bind is called, it will add the necessary visual elements under, for example, if it's a float it will add a FloatField under PropertyField
However if it's not valid, lets say a Event, it doesn't add anything under it
Having a FieldInfo, is it possible to know if the FieldType will be valid for the property field to have data?
~cross posting because i used the wrong channel by mistake~
hello! i am writing an editor tool to automate the transfer of data from Dialogues(scriptable object) to the Unity Localization System and vice versa. It almost works, but the LocalizationTablesWindow doesn't refresh until i press the New Entry button, or i close and reopen the window. Is there a way to automate this process without messing up the layout?
LocalizationTablesWindow window = EditorWindow.GetWindow<LocalizationTablesWindow>();
window.Close();
window = EditorWindow.GetWindow<LocalizationTablesWindow>();
window.Show();```
Calling this code after modifying the SharedTableData works, but the window loses the docking state
It will always be 'valid' if it is a serialized field of a serializable type. So, just making everything serializable is the best. And if it isn't serializable, then it won't save the values anyway so not sure how much use there is for it.
How are you setting the data? Directly I assume? You probably need to look at the source code of the localization tables window. But my guess is there is a SerializedObject that you need to call .Update() on.
I don't understand your answer. I want to ensure that no Invalid property fields are created when im doing it manually by checking all the fields in a class and manually creating properties for them. I'm looking for a way to skip those that the property field will be invalid
I recommend just using SerializedObject to get the fields instead, because then they will always be valid.
Otherwise you first have to check if the field is public, or has [SerializeField] or [SerializeReference]. Then check if the type of the field either has the [Serializable] attribute, or is one of the 'primitive' types Unity supports (like Vector3, float, Bounds etc.)
How would i get the fields of a serialized object?
thanks for the answer, i looked into the code for the EditorWindow, but it appears nothing is exposed and data from StringTable and SharedTableEntry gets requested upon pressing that button or reloading the window. i'm trying to save the editor layout before messing it up, and restoring it afterwards, using an evil hack calling internal editor functions with reflection. Maybe there is a way to force refresh the window, but i wasn't able to figure it out, if anyone knows it is very useful!
Seems to do the trick, thanks!
How to draw debug text in scene and game views?
Handles.Label only shows up in Scene view.
Then there's:
void OnGUI() {
GUI.Label(new Rect(10, 10, 100, 20), "Hello World!");
}
And it simply doesn't work.
Did you add this to a MonoBehaviour and is there an active instance of that MB in the scene?
Yes
Handles work in OnDrawGizmos btw. Just need to enable gizmos in game view
That OnGUI should work, though. What Unity version are you on?
Unity 6
Did you add that OnGUI code to the editor script or the MB script?
Does anyone know how much spacing is applied here? I tried just using indent level, but that applies too much space.
Sorry not the height, bad arrow on my part, the horizontal space between the left pane and the labels
It seems like it's 10.
I was wondering if there was a property to read from for this margin, in case it ever changes in the future, but doesn't look like there is.
Looking at the source, it seems to be defined in built in editor resources and not exposed as a property.
the little drop down arrow things are 16x16 to give u some instant reference
15-20 is typical
indented subcats double that.. so 30-40
10 seems like the right value to make it line up with the title of the preferences page, I just wish they exposed this so custom preferences pages could use it. If they ever decide to change it, then I'll have to update it manually 😔
If you really pay attention, none of the preferences pages have consistent margin lol
So I guess it's whatever
What? The page in the screenshot is the built in general preferences window, so how would I even do that?
real quick since we're talkin about spacing..
is there a way to lock the hiearchy width?
Do you mean in code?
ya.. the icons on the right are editor scripting
i just gave up after i got the spacing on the right finished.. figured id go ahead and clean it up
and force the hiearchy to be so wide so teh icons dont cut into the text
I don't think so, because the window size is up to the user since it is a dockable window
ahh you're right..
You can try setting min width, but not sure if that would work
i'll give it a shot.. thanks
it may work.. as there already appears to be some limit
100 or so pixels looks like
I guess I won't be bothered to be consistent with the margin in my custom preferences page since Unity themselves can't even be bothered to be consistent in their own pages.
Yeah, just don't know if it will ever get overwritten by internal unity code. You could have an editor update loop that checks if the min size doesn't match what you expect and set it. Not sure if that is even needed though.
i seen this menu the other day posted in unity-talk
very nice window if i must say so myself..
soo unity may be going in the right direction 🙂
I mean yeah, some of those preferences pages have been around for a long time and basically legacy at this point. So I get it, but damn like it wouldn't be that hard to update them to have consistent margins.
Lmfao hard coded
that explains a lot
Yeah I know, I appreciate it!
It actually seems to be this line, which reads from built in resources.
I guess some of the pages are adding / subtracting margins themselves on top of that.
Why would calling EditorGUILayout.Space() in between EditorGUILayout.BeginVertical() and EditorGUILayout.EndVertical() cause the horizontal padding to change?
If I don't call space, then there is zero horizontal padding. When I do call it, it adds some horizontal padding to the vertical layout.
See line 45
For future reference, you can open up the IMGUI Debugger window or the UIElements Debugger window (depending on the window) to find out!
I knew about the UIElements debugger, but I didn't know IMGUI had a debugger lol. I will investigate more tomorrow morning with that then, ty!
Yeah no problem. Until like 2022 or 6 it was hidden unless you were in the hidden developer mode. So, not surprising you didn't know about it haha
Also you can look at the source code (pinned to this channel) and see what they did
the preferences window styles suck and and are hacky
~cross posting because i used the wrong
Yeah that's what I ended up doing, I started to mimic what how they draw the Graphics page. I couldn't figure out why their spacing was less than mine and it seems to be because I call EditorGUILayout.Space() which causes the extra spacing.
For whatever reason by omitting the space call it leaves left, right, and top margins which shifts it left.
When I add the space call, it zeros out those margins and doesn't shift.
Interestingly, calling GUILayout.Space() instead of EditorGUILayout.Space() does not have the same effect and the margins remain
I think it is because GUILayout.Space() has this which EditorGUILayout.Space() does not.
if (Event.current.type == EventType.Layout)
{
GUILayoutUtility.current.topLevel.entries[GUILayoutUtility.current.topLevel.entries.Count - 1].consideredForMargin = false;
}
Maybe it is intentional though, but I find it strange.
Description says use for horizontal layout, so okay maybe it is intentional. Oh wait, proceeds to show it used in vertical layout 🤦♂️
It says to use the width parameter for horizontal, doesn't say anything about using the method for vertical layout
Well calling it without it, just inserts a default width of 6 anyways
And uses that parameter for both the width and height of the rect
What's SettingsProviderGUIScope?
And this is from GUILayout which is more in line how I would it expect it to behave.
Class I stole from core render pipeline package.
internal class SettingsProviderGUIScope : GUI.Scope
{
float m_LabelWidth;
public SettingsProviderGUIScope(int offset = 10)
{
m_LabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 251;
GUILayout.BeginHorizontal();
GUILayout.Space(offset);
GUILayout.BeginVertical();
}
protected override void CloseScope()
{
GUILayout.EndVertical();
GUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = m_LabelWidth;
}
}
I just realized, they are calling GUILayout methods in this class lol and not the editor ones. Why do the editor ones even exist if they aren't going to use them in their own editor code?
Afaik EditorGUILayout has some extra features specifically for editor that are not available for the runtime API (GUILayout). Not really sure of the differences but at least EditorGUILayout.Space seems to have more overloads/options to choose from for parameters
Generally you would use GUILayout for pretty much everything and EditorGUILayout for some niche features that GUILayout doesn't have (in editor scripts)
I use editor gui layout for custom editor windows as it's easier to use the horizontal/vertical and scroll layouts
hey sorry, didn't realise this channel existed so i'm moving this question over
ive been told GUILayout doesn't work in propertydrawers so im currently working on replacing that to see if it fixes the issue
that hasn't seemed to work @real spindle
here's a curveball though:
if i edit the PassageHandlerDrawer and then try to change PassageName...it works. it lets me change the name. but after that, i can no longer change the name again
so i guess the drawer is being reloaded here which lets me modify the field and then the issue appears again
im doing some more testing to figure out the cause and i think it might actually be caused by a SceneHandler being serialized inside a PassageHandler
if i make a SceneHandler and add a passage, I can change the name whenever i want
if i make a second SceneHandler and attach it to the first PassageHandler, i can still edit the name freely
but as soon as I add the first SceneHandler to a PassageHandler in another SceneHandler object, i can no longer edit the fields in the first SceneHandler
yeah i think this is the issue. i just made a new SceneHandler, added a passage and gave it a name, and then added its own SceneHandler as the target. and i could no longer modify the passage name.
ngl i cannot follow what you are saying with when it works and when it doesnt 😆
hehe sorry its also incredible confusing for me
im super out of my depth with editor stuff
@chilly vault I skimmed it but I am almost positive the issue is that you are applying the modified properties and updating it.
The Editor for the UnityEngine.Object handles the applying and updating
sorry, ive removed that code. its a propertydrawer so i was told i dont need to call Update and ApplyModifiedProperties
Correct
i also removed any GUILayout lines since propertydrawer can't use them. also didn't fix the issue
uhh i didn't
what do i put in the override method
The height that the property requires to be drawn. Typically it is
return EditorGUIUtility.singleLineHeight * fieldCount + EditorGUIUtility.standardVerticalSpacing * (fieldCount - 1);
With you specifying the field count. And that being how many input fields tall the property is.
gotcha
it kinda messed up the UI but ill figure that out later
it hasn't solved the editing issue
still cant change the passage name
oh huh, you don't need to call ApplyModifiedProperties? That's good to know
oh wait, this is a property drawer
misread that as PropertyField
A PropertyField is just a wrapper around using PropertyDrawer
How to do world to screen in the editor?
you can get the current scene view camera so it should be doable as normal
How to do it?
https://docs.unity3d.com/ScriptReference/SceneView-camera.html
and grab the current scene view from SceneView.currentDrawingSceneView or other static vars
Hello there.
I'm trying to create a tool script to help me scale objects more accurately for human sizes. It's supposed to render a hand and a human next to the object that you are changing the scale of.
Rendering the hand works just fine, but using the exact same code it just doesn't do it for the human model. I can't seem to figure out why this is not working, or what could possibly be wrong with my human fbx.
Here's the code:
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
using UnityEditor;
using UnityEditor.EditorTools;
[CustomEditor(typeof(MeshRenderer))]
public class ScaleReferenceTool : Editor
{
private MeshRenderer meshRenderer;
private static Mesh handMesh;
private static Mesh humanMesh;
private static Material ghostMaterial;
private void OnEnable()
{
meshRenderer = target as MeshRenderer;
if (handMesh == null)
{
handMesh = AssetDatabase.LoadAssetAtPath<Mesh>("Assets/ToolResources/RightHand.fbx");
}
if (humanMesh == null)
{
humanMesh = AssetDatabase.LoadAssetAtPath<Mesh>("Assets/ToolResources/Human.fbx");
}
if (ghostMaterial == null)
{
ghostMaterial = AssetDatabase.LoadAssetAtPath<Material>("Assets/ToolResources/ScaleReferenceMaterial.mat");
}
}
private void OnSceneGUI()
{
if (Tools.current != Tool.Scale) return;
if (meshRenderer == null || handMesh == null || humanMesh == null) return;
if (ghostMaterial == null) return;
Vector3 boundsExtents = meshRenderer.bounds.extents;
ghostMaterial.SetPass(0);
Graphics.DrawMeshNow(handMesh, meshRenderer.transform.position + new Vector3(boundsExtents.x+0.05f,0,0), Quaternion.Euler(0, 0, -90));
//ghostMaterial.SetPass(0);
//Graphics.DrawMeshNow(humanMesh, meshRenderer.transform.position, quaternion.identity);
}
}
and these are the assets:
expected result:
Do you guys have any idea what could be my problem?
You never described the result you're getting, only that it doesn't work
On the screenshot, you can see the hand drawing just fine, but the human model just doesn't appear. I don't know how to debug this as I don't think I can put a break point in an editor script.
You can debug editor code just fine
Anyways, would be good to isolate things, if you render with a 2 sided material, does it show? Does it have a weird pivot and it's rendering offscreen somewhere?
pivot is in the center, it renders normally if I just drag it into the scene, and I just tried with a double sided material
You've verified that it manages to load from that path?
I know for a fact that it passed the null check because otherwise it wouldn't render the hand
plus I didn't type the path, I copied it from the editor
did a debug.log on it, unity says it's a mesh
Are there multiple meshes in your fbx?
I forgot whether load just gets the first one or a compound thing
Should be just one model. But just to make sure, earlier I went back to Blender and deleted everything, even the vertex groups. It is just a mesh, with applied transforms and no material. And no camera or light was exported with it.
The import settings are the same as for the hand.
what scale is it? perhaps its rendering super big or super small and thus you cannot see. Fbx always has shit scale on import
hopefully changing the import scale will fix it
I don't know why I haven't thought of this, changed it so Unity doesn't convert the unit of scale and now it's working
Often when you drag in a fbx its at 100 scale and its easy to forget its an issue. I try to use glb more often now due to this 💪
feeling a bit stupid. I know ShootProjectileActionView is running, but the propertyfield doesn't show up
its public
ShootPattern is serializable
idk why its not showing
no console errors
I can't breakpoint the ShootPatternDrawer for some reason
(also this was working before, idk what changed)
Where is ShootProjectileAction being used/serialized?
My first guess @wanton arrow would be that it is a polymorphic field that is not marked with [SerializeReference]
it is being marked with that, but how would the prefab show up then?
all the other types work as well
What is Getter<>?
just this one property on this one action
I mean can you share the definition of it?
Because ShootPattern is the only one not showing, and the only field it has is the Getter so I was wondering if there was just no serialized data to show
it also has a type enum
it shows in debug mode as well
but not in normal mode even if I remove the "custom property field" thing from the drawer
so im assuming it has nothing to do with that file
Well I don't have all that info, so I am just making educated guesses 😛
ik
im pretty sure the only thing I changed was making the stateactions polymorphic
and moving it to a different class
but idk how that makes this occur
its annoying I dont even get an error
So is your "testing" message being logged?
nope
i beleive only to be inherited from
You are trying to get a property called "shootPattern" when the property is just "pattern"
Been there done that. Since you are just using public fields, I would use nameof instead.
I think i never considered that bc I thought It is supposed to give you an error??
I blame unitys api for my mistakes
Hahaha, it has benefits to the way it works. But I agree it for sure also has drawbacks
im just wondering why an object cast is needed before the cast to T 🤔
in what world would you not want it to error when it can't find the correct property
you tell me 
But yeah, I do recommend using nameof if you are just going to use public fields.
as far as I can tell it just is
fair
never heard of that
Because it is returning a float/int and it 'knows' that it can't cast to some generic T.
nameof(My.thing)
something like that yeah
oh shit i see, i wonder if you can do an unsafe re interpret
after using c++ I kinda dislike how C# generic types work but ik they have other nice benefits
it would be nice to be able to just constexpr the type
cus of the old c# ver we cant do const string interpolation either 😭
const string interpolation?
when we get .net core clr in 17 years it will be good
Doesn't matter, it's a recognized pattern, it will be optimized away
at least on CLR.... lets just pray Mono does that too
Yea I'm sure when the generic function is generated for the type it will be optimised but I don't know how good old mono is
incase some nerds confused what recognized here means 🤤 (T)(object)SomeTypeT is a common pattern used since ancient times and known to be optimized away
modern c# or cpp or rust I would expect to optimise this well (but there we can use reinterpret_cast<>() or similar) in template/generic functions but unity I don't trust 🤔
i wish i could find it but i read a good blog post a bit ago that showcased some pretty shit IL code gen that was giving this person some bad performance with ui toolkit
uh, why rinterprate cast?
most of these come with unsafe price in c#
ref byte tref = ref Unsafe.As<TFrom, byte>(ref something);
var into = Unsafe.ReadUnaligned<T>(ref tref);
yeah, doesn't make any sense for such simple thing and might not be faster
let the compiler do it's job 🙂
you can use latest c# today, you just need to polyfill them by hand.. and update the ancient unity's Roslyn to latest
anywhere I can read how this is done? I work on mobile with il2cpp primarily anyway so I won't do anything like this
look up for polyfill in c#
I just noticed in the console window in the editor there is an option to use a monospace font. Does anyone know how to get a handle to this font so I can use it in my own editor window? I've taken a look through things like EditorStyles but no luck finding anything so far.
Hey, I had an issue a couple of days ago and got super confused so I've done some testing and I have a more clear idea of the problem now.
I have a SceneHandler scriptable object, a PassageHandler scriptable object, and some editor/property drawer scripts for them.
SceneHandler: https://paste.ofcode.org/XYGF2HaRgxfRGcNbNprGwu
PassageHandler: https://paste.ofcode.org/xzz8LHB5Y8y59dZ8DGnKRW
SceneHandlerEditor: https://paste.ofcode.org/KBWNpLUDFYJuvdyxbDmthD
PassageHandlerDrawer: https://paste.ofcode.org/MbwKTgVsRWgqY6w2QrirPG
The PassageHandlers are created and displayed in a SceneHandler. They have a passage name, a targeted scene handler, and can then select from a list of passage names from that targeted scene handler as their target passage.
If I create two SceneHandlers and create a PassageHandler on each, I can edit the name fields to give them custom passage names, I can select a target SceneHandler for both PassageHandlers, and I can set the target passage for both to the other passage on the other scene. (So Passage1 on Scene1Handler connects to Passage2 on Scene2Handler and vice versa).
If I then add another PassageHandler to one of the SceneHandlers, I can't edit any of the fields on any of the PassageHandlers (on any SceneHandler). For example, I can start writing in the passage name field but as soon as I click off the inspector panel, the changes aren't saved.
However...if I edit any file (meaning the Unity project is reloaded), I can edit anything I want on the currently-open SceneHandler and it saves the changes. As soon as I click off the SceneHandler, I go back to not being able to make edits to the PassageHandlers.
While testing whether or not the edit changes were being saved, I noticed that in PassageHandlerDrawer, after the line,
EditorGUI.PropertyField(rect, passageName);```
reading passageName.stringValue returns the **correct** new passage name for one frame and then immediately goes back to whatever the passage name was before the field edit.
I'm pretty new to Unity Editor stuff so I hope this is enough info on the problem. I've been told that I can't use EditorGUILayout in a PropertyDrawer but...it seems to be working fine right now and changing the code to replace any instances of EditorGUILayout didn't fix the issue.
You commented out the important part of the code 😛
What is the result you are trying to get?
Well actualy it isn't that important I guess
Two options, one, check if the instance id is the same as the first GameObject in the Scene. And only apply the scale if it is. Two is to use harmony and inject the scaling code in to the hierarchy window before it is draw.
The first because it does it draw order
Also ScaleAroundPivot modifies GUI.matrix
so you're doing that repeatedly, not once. It never gets reset
Nope, that would result in the same thing, you would want this I think https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/SceneHierarchy.cs#L871
you'll have to find a way to reset the matrix at the end. This is all just hacking things, so there's not going to be an easy way to do this
and I'd honestly be surprised if you got it to work properly
That is because changing the matirx is just changing how it is rendering, now the actual layout info
Can I ask what you hope to achieve with PassageHandler having [SerializeReference] public List<PassageHandler> TargetScenePassages?
your gui code is copying the reference from the SceneHandler so this is going to cause problems...
each PassageHandler needs to know about all of the PassageHandlers on its targeted SceneHandler to create a connection between two PassageHandlers.
the goal is to have 2 scenes with a passage object in each. each passage links to a PassageHandler on the correct SceneHandler and this is used to spawn the player at the correct place in the next scene.
So the player interacts with a Left Passage game object in Scene 1, the Left Passage game object connects to a Left Passage PassageHandler on Scene1Handler, that PassageHandler connects to a Right Passage PassageHandler on Scene2Handler, and that PassageHandler connects to a Right Passage game object which contains logic to spawn the player
SetPassageList() is called from SceneHandlerEditor when the SceneHandler's "Passages" list contains at least one PassageHandler. the function should just populate TargetScenePassageNames with the Passage Name of each PassageHandler on the TargetSceneHandler
and then TargetScenePassageNames is used by the property drawer to display a Popup of all the names
But why are these all Serialized and not just the index
so dont save TargetScenePassages and just reference them via TargetSceneHandler.Passages?
oh weird. i dont actually use TargetScenePassages anywhere from the looks of it
only here: cs TargetScenePassages = TargetSceneHandler.Passages which could easily be removed
oh my god i think that fixed it
aaaaaaa heheeheh
works flawlessly now
@surreal girder thank you so much! ive been pulling my hair out for days over this and it turns out i just needed to comment out 2 lines hahaha
do you know why that was causing the issue?
I think even with Serialize ref it won't be able to reference a field in another asset. You can always open the asset as text to see what data it has inside of it.
gotcha ty
It's been a year. Did you do it?
Lol, nope I fought off the urge. There are also a number of decent ones now, though none with 'baking'.
There is
EditorAttributes
Alchemy
Artifice Toolkit
I would probably give EditorAttributes a go first.
That answer is more than i could have hoped for. Thanks a lot and have a nice sunday 🙂


