88 lines
2.2 KiB
C#
88 lines
2.2 KiB
C#
|
|
#if TOOLS
|
||
|
|
|
||
|
|
using Godot;
|
||
|
|
|
||
|
|
namespace Rokojori.Tools
|
||
|
|
{
|
||
|
|
// scenePath is a list of child names from the scene root, e.g. ["Player","CharacterBody3D"].
|
||
|
|
// SceneState has no parent/child API - nodes are a flat list, each with its own full relative
|
||
|
|
// path string (root is "."), so matching is by path-string comparison / prefix.
|
||
|
|
public static class ScenePathResolver
|
||
|
|
{
|
||
|
|
// SceneState.GetNodePath(idx, false) stringifies relative to the scene root as "./Name/Child",
|
||
|
|
// i.e. with an explicit "." leading segment - not a bare "Name/Child" as a naive join would produce.
|
||
|
|
public static string ToRelativePath( string[] scenePath )
|
||
|
|
{
|
||
|
|
if ( scenePath == null || scenePath.Length == 0 )
|
||
|
|
{
|
||
|
|
return ".";
|
||
|
|
}
|
||
|
|
|
||
|
|
return "./" + string.Join( "/", scenePath );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int FindNodeIndex( SceneState state, string relativePath )
|
||
|
|
{
|
||
|
|
var count = state.GetNodeCount();
|
||
|
|
|
||
|
|
for ( var i = 0; i < count; i++ )
|
||
|
|
{
|
||
|
|
if ( state.GetNodePath( i, false ).ToString() == relativePath )
|
||
|
|
{
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 0 = same node, 1 = direct child, 2 = grandchild, etc. -1 = not a descendant.
|
||
|
|
public static int DepthOf( string rootRelativePath, string candidateRelativePath )
|
||
|
|
{
|
||
|
|
if ( rootRelativePath == candidateRelativePath )
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
var prefix = rootRelativePath == "." ? "./" : rootRelativePath + "/";
|
||
|
|
|
||
|
|
if ( ! candidateRelativePath.StartsWith( prefix ) )
|
||
|
|
{
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
var remainder = candidateRelativePath.Substring( prefix.Length );
|
||
|
|
return remainder.Split( '/' ).Length;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Node FindNode( Node root, string[] scenePath )
|
||
|
|
{
|
||
|
|
if ( scenePath == null || scenePath.Length == 0 )
|
||
|
|
{
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
|
||
|
|
return root.GetNodeOrNull( new NodePath( string.Join( "/", scenePath ) ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static string[] ToStringArray( Rokojori.JSONArray array )
|
||
|
|
{
|
||
|
|
if ( array == null )
|
||
|
|
{
|
||
|
|
return new string[ 0 ];
|
||
|
|
}
|
||
|
|
|
||
|
|
var result = new string[ array.size ];
|
||
|
|
|
||
|
|
for ( var i = 0; i < array.size; i++ )
|
||
|
|
{
|
||
|
|
result[ i ] = array.Get( i ).stringValue;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|