141 lines
2.8 KiB
C#
141 lines
2.8 KiB
C#
|
|
using Godot;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
|
|
using Rokojori.Extensions;
|
|
namespace Rokojori
|
|
{
|
|
[GlobalClass, Tool ]
|
|
public partial class SelectNode3D : Action
|
|
{
|
|
[Export]
|
|
public Selector selector;
|
|
|
|
bool _enteredTree = false;
|
|
|
|
public override void _EnterTree()
|
|
{
|
|
base._EnterTree();
|
|
_enteredTree = true;
|
|
}
|
|
|
|
Node _target;
|
|
|
|
[Export]
|
|
public Node target
|
|
{
|
|
get => _target;
|
|
set
|
|
{
|
|
if ( _target == value )
|
|
{
|
|
return;
|
|
}
|
|
|
|
_target = value;
|
|
|
|
// Deserialization sets exported properties before _EnterTree fires, so this
|
|
// only triggers for genuine interactive edits in the editor, never for a scene
|
|
// being loaded (regardless of property order) or for runtime reassignment.
|
|
if ( _enteredTree && Engine.IsEditorHint() )
|
|
{
|
|
targetMember = "";
|
|
|
|
#if TOOLS
|
|
NotifyPropertyListChanged();
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
[Export]
|
|
public string targetMember;
|
|
|
|
|
|
|
|
protected override void _OnTrigger()
|
|
{
|
|
if ( target == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Node3D node3D = null;
|
|
|
|
if ( selector == null )
|
|
{
|
|
ReflectionHelper.SetValue<Node3D>( target, targetMember, node3D );
|
|
this.LogInfo( "Set Null:", HierarchyName.Of( target ), targetMember );
|
|
return;
|
|
}
|
|
|
|
var selectedNode = Unique<SelectManager>.Get().Select( selector );
|
|
|
|
|
|
if ( selectedNode is Selectable )
|
|
{
|
|
var go = selectedNode.GetParent<GameObject3D>();
|
|
|
|
if ( go != null )
|
|
{
|
|
node3D = go.body;
|
|
}
|
|
}
|
|
|
|
ReflectionHelper.SetValue<Node3D>( target, targetMember, node3D );
|
|
|
|
}
|
|
|
|
#if TOOLS
|
|
|
|
public override void _ValidateProperty( Godot.Collections.Dictionary property )
|
|
{
|
|
if ( property[ "name" ].AsString() != nameof( targetMember ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var members = GetTargetNode3DMemberNames();
|
|
|
|
property[ "hint" ] = (long) PropertyHint.Enum;
|
|
property[ "hint_string" ] = members.Count == 0
|
|
? "(Invalid Target)"
|
|
: "None," + string.Join( ",", members );
|
|
}
|
|
|
|
List<string> GetTargetNode3DMemberNames()
|
|
{
|
|
var names = new List<string>();
|
|
|
|
if ( target == null )
|
|
{
|
|
return names;
|
|
}
|
|
|
|
var infos = ReflectionHelper.GetDataMemberInfos( target, BindingFlags.Public | BindingFlags.Instance );
|
|
|
|
foreach ( var info in infos )
|
|
{
|
|
if ( ! info.IsDefined( typeof( ExportAttribute ) ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var memberType = info.GetMemberType();
|
|
|
|
if ( memberType == null || ! memberType.IsAssignableFrom( typeof( Node3D ) ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
names.Add( info.Name );
|
|
}
|
|
|
|
return names;
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
} |