mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-14 17:29:23 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
211 lines
5.4 KiB
C#
211 lines
5.4 KiB
C#
using Facepunch.ActionGraphs;
|
|
using Sandbox.ActionGraphs;
|
|
using System;
|
|
using System.Text.Json.Nodes;
|
|
|
|
namespace Sandbox;
|
|
|
|
public static partial class SceneExtensions
|
|
{
|
|
/// <summary>
|
|
/// We should make this globally reachanle at some point. Should be able to draw icons using bitmaps etc too.
|
|
/// </summary>
|
|
public static Editor.Menu CreateContextMenu( this Scene scene, Widget parent = null )
|
|
{
|
|
var menu = new Editor.Menu( parent );
|
|
|
|
menu.AddOption( "Save", "save", action: () => scene.Editor?.Save( false ) ).Enabled = (scene.Editor?.HasUnsavedChanges ?? false) && scene.Source is not null;
|
|
menu.AddOption( "Save Scene As..", action: () => scene.Editor?.Save( true ) );
|
|
|
|
return menu;
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Copy the target <see cref="Component"/> to the clipboard.
|
|
/// </summary>
|
|
/// <param name="component"></param>
|
|
public static void CopyToClipboard( this Component component )
|
|
{
|
|
using var scope = SceneEditorSession.Scope();
|
|
|
|
var result = component.Serialize();
|
|
if ( result is null ) return;
|
|
EditorUtility.Clipboard.Copy( result.ToString() );
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Paste component values from clipboard to the target <see cref="Component"/>.
|
|
/// </summary>
|
|
/// <param name="target"></param>
|
|
public static void PasteValues( this Component target )
|
|
{
|
|
var text = EditorUtility.Clipboard.Paste();
|
|
using var scope = SceneEditorSession.Scope();
|
|
|
|
try
|
|
{
|
|
if ( JsonNode.Parse( text ) is not JsonObject pastedJso )
|
|
return;
|
|
|
|
using ( SceneEditorSession.Active.UndoScope( "Paste Component Values" ).WithComponentChanges( target ).Push() )
|
|
{
|
|
pastedJso.AsObject().Remove( "__guid" );
|
|
target.DeserializeImmediately( pastedJso );
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// Do nothing.
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return true if this object should be shown in the GameObject list
|
|
/// </summary>
|
|
public static bool ShouldShowInHierarchy( this GameObject target )
|
|
{
|
|
if ( target is null ) return false;
|
|
if ( target.Flags.Contains( GameObjectFlags.Hidden ) ) return false;
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Paste a <see cref="Component"/> as a new component on the target <see cref="GameObject"/>.
|
|
/// </summary>
|
|
/// <param name="target"></param>
|
|
public static void PasteComponent( this GameObject target )
|
|
{
|
|
var text = EditorUtility.Clipboard.Paste();
|
|
|
|
using var scope = SceneEditorSession.Scope();
|
|
|
|
try
|
|
{
|
|
if ( JsonNode.Parse( text ) is not JsonObject pastedJso )
|
|
return;
|
|
|
|
var componentType = TypeLibrary.GetType<Component>( (string)pastedJso["__type"] );
|
|
if ( componentType is null )
|
|
{
|
|
Log.Warning( $"TypeLibrary couldn't find {nameof( Component )} type {pastedJso["__type"]}" );
|
|
return;
|
|
}
|
|
|
|
using ( SceneEditorSession.Active.UndoScope( $"Paste {componentType.Name} As New" ).WithComponentCreations().Push() )
|
|
{
|
|
SceneUtility.MakeIdGuidsUnique( pastedJso );
|
|
|
|
var cmp = target.Components.Create( componentType );
|
|
cmp.DeserializeImmediately( pastedJso );
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// Do nothing.
|
|
}
|
|
}
|
|
|
|
|
|
public static void PaintComponentIcon( this TypeDescription td, Rect rect, float opacity = 1 )
|
|
{
|
|
Paint.SetPen( Theme.Green.WithAlpha( opacity ) );
|
|
Paint.DrawIcon( rect, td.Icon, rect.Height, TextFlag.Center );
|
|
}
|
|
|
|
|
|
public static void EnableEditorRigidBody( this Scene scene, Rigidbody body, bool enabled )
|
|
{
|
|
var system = scene.GetSystem<ScenePhysicsSystem>();
|
|
if ( system is null )
|
|
return;
|
|
|
|
if ( enabled )
|
|
{
|
|
system.AddRigidBody( body );
|
|
}
|
|
else
|
|
{
|
|
system.RemoveRigidBody( body );
|
|
}
|
|
}
|
|
|
|
public static void DisableEditorRigidBodies( this Scene scene )
|
|
{
|
|
var system = scene.GetSystem<ScenePhysicsSystem>();
|
|
if ( system is null )
|
|
return;
|
|
|
|
system.RemoveRigidBodies();
|
|
}
|
|
|
|
public static void EnableEditorPhysics( this Scene scene, bool enabled )
|
|
{
|
|
var system = scene.GetSystem<ScenePhysicsSystem>();
|
|
if ( system is null )
|
|
return;
|
|
|
|
system.Enabled = enabled;
|
|
}
|
|
|
|
public static void SetTargetTransform( this Rigidbody body, Transform? tx )
|
|
{
|
|
body.TargetTransform = tx;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Editor helpers for scene.ref nodes.
|
|
/// </summary>
|
|
public static class SceneReferenceHelper
|
|
{
|
|
public static IReadOnlyDictionary<string, object> GetNodeProperties( GameObject go )
|
|
{
|
|
return new Dictionary<string, object>
|
|
{
|
|
{ "gameobject", GameObjectReference.FromInstance( go ) }
|
|
};
|
|
}
|
|
|
|
public static IReadOnlyDictionary<string, object> GetNodeProperties( Component component )
|
|
{
|
|
var t = TypeLibrary.GetType( component.GetType() );
|
|
|
|
return new Dictionary<string, object>
|
|
{
|
|
{ "component", ComponentReference.FromInstance( component ) }
|
|
};
|
|
}
|
|
|
|
public static IReadOnlyDictionary<string, object> GetNodeProperties( string prefabPath )
|
|
{
|
|
return new Dictionary<string, object>
|
|
{
|
|
{ "gameobject", GameObjectReference.FromPrefabPath( prefabPath ) }
|
|
};
|
|
}
|
|
|
|
private static Scene GetContainingScene( Node node )
|
|
{
|
|
return (node.ActionGraph.GetEmbeddedTarget() as GameObject)?.Scene ?? Game.ActiveScene;
|
|
}
|
|
|
|
public static GameObject ResolveTargetGameObject( Node node )
|
|
{
|
|
var scene = GetContainingScene( node );
|
|
|
|
return node.Properties.TryGetValue( "gameobject", out var prop ) && prop.Value is GameObjectReference goRef
|
|
? goRef.Resolve( scene ) : null;
|
|
}
|
|
|
|
public static Component ResolveTargetComponent( Node node )
|
|
{
|
|
var scene = GetContainingScene( node );
|
|
|
|
return node.Properties.TryGetValue( "component", out var prop ) && prop.Value is ComponentReference compRef
|
|
? compRef.Resolve( scene ) : null;
|
|
}
|
|
}
|