Park/SelectionSystem.cs
using HC3.Terraforming;
using HC3.UI;
namespace HC3;
/// <summary>
/// Handles selecting objects in the world and showing selection effects.
/// </summary>
public sealed class SelectionSystem : Component
{
/// <summary>
/// Singleton
/// </summary>
public static SelectionSystem Instance { get; private set; }
// Currently selected object
GameObject Selected;
// Currently hovered object -- this can differ from the selected object
GameObject Hovered;
protected override void OnAwake()
{
Instance = this;
}
protected override void OnUpdate()
{
if ( Input.Released( "Attack1" ) )
{
// Get screen ray
var screenToWorld = Scene.Camera.ScreenPixelToRay( Mouse.Position );
// Trace to the ground
var trace = Scene.Trace.Ray( screenToWorld, 1024000f )
.UsePhysicsWorld()
.HitTriggers()
.WithTag( "selectable" )
.RunAll();
// Find selectable
var obj = trace
.OrderByDescending( x => x.GameObject.GetComponent<Guest>() is not null )
.ThenBy( x => x.Distance )
.FirstOrDefault();
Hovered = obj.GameObject;
Select( Hovered );
}
}
/// <summary>
/// Called when we select something
/// </summary>
/// <param name="inspectable"></param>
public void OnSelected( IInspectable inspectable )
{
ShowEffect( Selected, false );
Selected = inspectable?.GameObject;
IInspectable.Current = inspectable;
// Do we have any effects?
ShowEffect( Selected, true );
}
/// <summary>
/// Show a selection effect if the GameObject we're selecting has a <see cref="SelectionEffect"/> component
/// </summary>
/// <param name="obj"></param>
/// <param name="show"></param>
private void ShowEffect( GameObject obj, bool show )
{
if ( !obj.IsValid() )
return;
var effectComponent = obj.GetComponentInChildren<SelectionEffect>( true );
if ( !effectComponent.IsValid() ) return;
effectComponent.GameObject.Enabled = show;
}
/// <summary>
/// We are selecting an object
/// </summary>
/// <param name="obj"></param>
public void Select( GameObject obj )
{
if ( !obj.IsValid() )
{
return;
}
// TODO: Split this out, this is shit
if ( BuildingPlacer.Instance.IsPlacing || BuildingPlacer.Instance.IsDestroying )
return;
if ( Terraformer.Instance?.IsTerraforming ?? false )
return;
/// Do we have an inspectable?
if ( obj.GetComponentInParent<IInspectable>() is { IsValid: true } inspectable )
{
if ( inspectable.Select() is { } inspector )
{
// TODO: Configurable sound?
Sound.Play( "click5" );
WindowManager.Instance.Open( inspector );
}
}
}
}