Player/InteractUse.cs
using Opium;
public sealed class InteractUse : Component
{
[Property] public bool IsDebugging { get; set; }
public TimeSince TimeSinceObjectChanged { get; private set; } = 0;
public TimeSince TimeSinceLookObjectChanged { get; private set; } = 0;
private IInteractable obj;
public IInteractable InteractingObject
{
get => obj;
set
{
if ( InteractingObject == value ) return;
obj = value;
TimeSinceObjectChanged = 0;
}
}
private IInteractable lookobj;
public IInteractable LookingAtObject
{
get => lookobj;
set
{
if ( LookingAtObject == value ) return;
lookobj = value;
TimeSinceLookObjectChanged = 0;
}
}
protected override void OnUpdate()
{
if ( !Components.Get<Actor>().IsAlive ) return;
var cameraObject = Components.Get<Actor>().CameraObject;
var tr = Scene.Trace.Ray( cameraObject.Transform.Position, cameraObject.Transform.Position + cameraObject.Transform.Rotation.Forward * 100.0f )
.IgnoreGameObjectHierarchy( GameObject )
.WithoutTags( "ragdoll" )
.Size( 7.5f )
.Run();
if ( IsDebugging )
{
Gizmo.Draw.Color = Color.White;
Gizmo.Draw.Line( tr.StartPosition, tr.EndPosition );
Gizmo.Draw.LineSphere( tr.EndPosition, 8 );
}
// If we're interacting with something right now
if ( Input.Down( "Use" ) && InteractingObject != null
&& InteractingObject.CanUse( GameObject ) )
{
InteractingObject.OnUseContinuous( GameObject );
return;
}
if ( tr.GameObject.IsValid() && tr.GameObject.Components.Get<IInteractable>( FindMode.EverythingInSelfAndParent ) is IInteractable interactable )
{
if ( interactable.CanUse( GameObject ) )
{
LookingAtObject = interactable;
if ( Input.Pressed( "Use" ) )
{
InteractingObject = interactable;
InteractingObject.OnUse( GameObject );
InteractingObject.OnUseStart( GameObject );
if ( GameObject.Components.Get<Opium.PlayerController>() is Opium.PlayerController player )
{
player.Inventory?.Current?.EventListener?.Invoke( "use" );
}
}
}
else
{
LookingAtObject = interactable;
if ( Input.Pressed( "Use" ) )
{
LookingAtObject.OnUseFail( GameObject );
}
}
}
else
{
LookingAtObject = null;
}
if ( Input.Released( "Use" ) )
{
InteractingObject?.OnUseStop( GameObject );
InteractingObject = null;
}
}
}
public interface IInteractable : IValid
{
public GameObject GameObject { get; }
public GameObject Source { get; }
public bool CanUse( GameObject player );
public void OnUse( GameObject player );
public abstract bool ShowInteractionUI { get; }
public virtual string GetUseIcon()
{
return null;
}
public virtual void OnUseStart( GameObject player )
{
//
}
public virtual void OnUseStop( GameObject player )
{
//
}
public virtual void OnUseFail( GameObject player )
{
//
}
public virtual void OnUseContinuous( GameObject player )
{
//
}
}