Level/DrawerComponent.cs
using Sandbox;
using System.Numerics;

public class DrawerComponent : BaseInteract
{
	[Property,Group("Movement")] public Angles MoveDir { get; set; }
	[Property, Group( "Movement" ), Range(0,10)] public float Distance { get; set; } = 10.0f;
	[Property, Group( "Movement" )] public float Speed { get; set; } = 1.0f;
	[Property,Group("Sound")] public SoundEvent OpenSound { get; set; }
	[Property,Group("Sound")] public SoundEvent CloseSound { get; set; }
	[Property,Group("Sound")] public SoundEvent FullyCloseSound { get; set; }

	[Property] public bool Open { get; set; } = false;
	[Property] public bool DrawGizmo { get; set; } = false;

	Rotation startRotation;
	Vector3 startPosition;

	float drawerDistance;

	Model drawerModel => GameObject.Components.Get<ModelRenderer>(FindMode.InSelf).Model;

	protected override void DrawGizmos()
	{
		base.DrawGizmos();

		if( !Gizmo.IsSelected ) return;

		Gizmo.Transform = new Transform( Transform.Position + Transform.Rotation.Forward * Distance, Transform.Rotation );
		Gizmo.Draw.Color = Color.Blue.WithAlpha( 1f );
		Gizmo.Draw.LineBBox( drawerModel.Bounds );
		Gizmo.Draw.Color = Color.Blue.WithAlpha( 0.5f );
		Gizmo.Draw.SolidBox( drawerModel.Bounds );
	}

	protected override void OnStart()
	{
		base.OnStart();

		startRotation = Transform.Rotation;
		startPosition = Transform.Position;
	}
	bool beenUsed = false;
	protected override void OnFixedUpdate()
	{
		if ( !beenUsed )
		{
			return;
		}

		if ( Open )
		{
			Log.Info( "Open" );

			drawerDistance = drawerDistance.LerpTo( Distance, Time.Delta * Speed );
			Transform.Position = startPosition + Transform.Rotation.Forward * drawerDistance;

			fullyClosed = false;
		}
		else
		{
			drawerDistance = drawerDistance.LerpTo( 0, Time.Delta * Speed );
			Transform.Position = startPosition + Transform.Rotation.Forward * drawerDistance;

			var pos = MathF.Abs( drawerDistance );

			if ( pos <= 0.5f && !fullyClosed )
			{
				fullyClosed = true;
				if ( FullyCloseSound != null )
				{
					Sound.Play( FullyCloseSound, Transform.Position );
				}
			}
		}

	}

	bool fullyClosed = false;

	public override void OnUse( GameObject player )
	{
		ToggleDoor( player );
	}

	public void ToggleDoor( GameObject player )
	{
		DetermineOpenDirection( player );
		Open = !Open;
	}
	private void DetermineOpenDirection( GameObject player )
	{
		if ( OpenSound != null && Open )
		{
			Sound.Play( CloseSound, Transform.Position );
		}

		if ( OpenSound != null && !Open )
		{
			Sound.Play( OpenSound, Transform.Position );
		}

		beenUsed = true;
	}

}