diff --git a/Source/Editor/Gizmo/TransformGizmo.cs b/Source/Editor/Gizmo/TransformGizmo.cs index eca5475ed..f7aed5597 100644 --- a/Source/Editor/Gizmo/TransformGizmo.cs +++ b/Source/Editor/Gizmo/TransformGizmo.cs @@ -71,7 +71,7 @@ namespace FlaxEditor.Gizmo if (hit != null) { // For child actor nodes (mesh, link or sth) we need to select it's owning actor node first or any other child node (but not a child actor) - if (hit is ActorChildNode actorChildNode) + if (hit is ActorChildNode actorChildNode && !actorChildNode.CanBeSelectedDirectly) { var parentNode = actorChildNode.ParentNode; bool canChildBeSelected = sceneEditing.Selection.Contains(parentNode); diff --git a/Source/Editor/SceneGraph/ActorChildNode.cs b/Source/Editor/SceneGraph/ActorChildNode.cs index 0711aa20a..328ca277a 100644 --- a/Source/Editor/SceneGraph/ActorChildNode.cs +++ b/Source/Editor/SceneGraph/ActorChildNode.cs @@ -19,6 +19,11 @@ namespace FlaxEditor.SceneGraph /// public readonly int Index; + /// + /// Gets a value indicating whether this node can be selected directly without selecting parent actor node first. + /// + public virtual bool CanBeSelectedDirectly => false; + /// /// Initializes a new instance of the class. /// @@ -66,6 +71,18 @@ namespace FlaxEditor.SceneGraph /// public override object UndoRecordObject => ParentNode.UndoRecordObject; + + /// + public override void Dispose() + { + // Unlink from the parent + if (parentNode is ActorNode parentActorNode && parentActorNode.ActorChildNodes != null) + { + parentActorNode.ActorChildNodes.Remove(this); + } + + base.Dispose(); + } } /// diff --git a/Source/Editor/SceneGraph/ActorNode.cs b/Source/Editor/SceneGraph/ActorNode.cs index 753440378..5cc5f5337 100644 --- a/Source/Editor/SceneGraph/ActorNode.cs +++ b/Source/Editor/SceneGraph/ActorNode.cs @@ -41,7 +41,7 @@ namespace FlaxEditor.SceneGraph /// /// The actor child nodes used to represent special parts of the actor (meshes, links, surfaces). /// - public readonly List ActorChildNodes = new List(); + public List ActorChildNodes; /// /// Initializes a new instance of the class. @@ -108,6 +108,8 @@ namespace FlaxEditor.SceneGraph /// The node public ActorChildNode AddChildNode(ActorChildNode node) { + if (ActorChildNodes == null) + ActorChildNodes = new List(); ActorChildNodes.Add(node); node.ParentNode = this; return node; @@ -125,9 +127,12 @@ namespace FlaxEditor.SceneGraph root.OnActorChildNodesDispose(this); } - for (int i = 0; i < ActorChildNodes.Count; i++) - ActorChildNodes[i].Dispose(); - ActorChildNodes.Clear(); + if (ActorChildNodes != null) + { + for (int i = 0; i < ActorChildNodes.Count; i++) + ActorChildNodes[i].Dispose(); + ActorChildNodes.Clear(); + } } /// @@ -275,8 +280,12 @@ namespace FlaxEditor.SceneGraph /// public override void Dispose() { - // Cleanup UI _treeNode.Dispose(); + if (ActorChildNodes != null) + { + ActorChildNodes.Clear(); + ActorChildNodes = null; + } base.Dispose(); } diff --git a/Source/Editor/SceneGraph/Actors/BoxVolumeNode.cs b/Source/Editor/SceneGraph/Actors/BoxVolumeNode.cs index 92b252138..24b035bc8 100644 --- a/Source/Editor/SceneGraph/Actors/BoxVolumeNode.cs +++ b/Source/Editor/SceneGraph/Actors/BoxVolumeNode.cs @@ -78,14 +78,14 @@ namespace FlaxEditor.SceneGraph.Actors { get { - var actor = (BoxVolume)((BoxVolumeNode)ParentNode).Actor; + var actor = (BoxVolume)_actor.Actor; var localOffset = _offset * actor.Size; Transform localTrans = new Transform(localOffset); return actor.Transform.LocalToWorld(localTrans); } set { - var actor = (BoxVolume)((BoxVolumeNode)ParentNode).Actor; + var actor = (BoxVolume)_actor.Actor; Transform localTrans = actor.Transform.WorldToLocal(value); var prevLocalOffset = _offset * actor.Size; var localOffset = Vector3.Abs(_offset) * 2.0f * localTrans.Translation; diff --git a/Source/Editor/SceneGraph/Actors/NavLinkNode.cs b/Source/Editor/SceneGraph/Actors/NavLinkNode.cs index 8eb5fbc8b..941e39267 100644 --- a/Source/Editor/SceneGraph/Actors/NavLinkNode.cs +++ b/Source/Editor/SceneGraph/Actors/NavLinkNode.cs @@ -37,13 +37,13 @@ namespace FlaxEditor.SceneGraph.Actors { get { - var actor = (NavLink)((NavLinkNode)ParentNode).Actor; + var actor = (NavLink)_actor.Actor; Transform localTrans = new Transform(_isStart ? actor.Start : actor.End); return actor.Transform.LocalToWorld(localTrans); } set { - var actor = (NavLink)((NavLinkNode)ParentNode).Actor; + var actor = (NavLink)_actor.Actor; Transform localTrans = actor.Transform.WorldToLocal(value); if (_isStart) actor.Start = localTrans.Translation; diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index 94b994ac8..b5a19b1ec 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -513,7 +513,7 @@ namespace FlaxEditor.Viewport if (hit != null) { // For child actor nodes (mesh, link or sth) we need to select it's owning actor node first or any other child node (but not a child actor) - if (hit is ActorChildNode actorChildNode) + if (hit is ActorChildNode actorChildNode && !actorChildNode.CanBeSelectedDirectly) { var parentNode = actorChildNode.ParentNode; bool canChildBeSelected = _window.Selection.Contains(parentNode);