Level/Test/ObstacleMover.cs
using Sandbox;
using System.Net.Sockets;

public sealed class ObstacleMover : BaseInteract
{
	[Property, Group( "Movement" )] public GameObject MoveTo { get; set; }
	[Property, Group( "Movement" )] public Curve Curve { get; set; } = new Curve( new Curve.Frame( 1.0f, 1.0f ), new Curve.Frame( 1.0f, 1.0f ) );
	[Property, Group( "Movement" ), Range(1,20)] public float MovementDuration { get; set; } = 2.0f;

	bool isMoving = false;
	float elapsedTime = 0f;

	Vector3 startPos;
	Rotation startRot;

	Vector3 endPos;
	Rotation endRot;

	bool Moved { get; set; } = false;

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

		Curve.Evaluate( 0 );

		startPos = Transform.Position;
		startRot = Transform.Rotation;

		if ( MoveTo == null ) return;

		endPos = MoveTo.Transform.Position;
		endRot = MoveTo.Transform.Rotation;
	}

	protected override void OnUpdate()
	{
		if ( isMoving )
		{
			elapsedTime += Time.Delta;

			float progress = elapsedTime / MovementDuration;
			progress = Math.Clamp( progress, 0, 1 );

			float curvedProgress = Curve.Evaluate( progress );

			Transform.Position = Vector3.Lerp( startPos, endPos, curvedProgress );
			Transform.Rotation = Rotation.Lerp( startRot, endRot, curvedProgress );

			if ( progress >= 1f )
			{
				isMoving = false;
				elapsedTime = 0;
				Moved = true;
			}
		}
	}

	public override void OnUse( GameObject player )
	{
		if ( Moved ) return;

		isMoving = true;
		elapsedTime = 0;
	}
}