using System; using RebootKit.Engine.Extensions; using UnityEngine; namespace RebootKit.Engine.Services.Simulation { public class PhysicsObjectDragger : MonoBehaviour { [field: SerializeField] public float DampingFactor { get; private set; } = 1.0f; [field: SerializeField] public float AngularSlowdown { get; private set; } = 90.0f; [field: SerializeField] public float DragForce { get; private set; } = 10.0f; public Rigidbody Current { get; private set; } [field: SerializeField] public Vector3 TargetWorldPosition { get; set; } public bool IsDragging => Current != null; public void FixedUpdate() { if (Current.OrNull() == null) { return; } Vector3 direction = (TargetWorldPosition - Current.position).normalized; float distance = Vector3.Distance(TargetWorldPosition, Current.position); Vector3 damping = Current.linearVelocity * DampingFactor; Vector3 force = direction * Mathf.Clamp(distance * DragForce, 0, DragForce) - damping; Current.AddForce(force, ForceMode.Force); Current.angularVelocity = Vector3.MoveTowards(Current.angularVelocity, Vector3.zero, Time.fixedDeltaTime * AngularSlowdown); } void OnDrawGizmosSelected() { Gizmos.color = Color.green; Gizmos.DrawSphere(TargetWorldPosition, 0.1f); } public void Grab(Rigidbody physicsObject) { Drop(); Current = physicsObject; Current.linearDamping = 5.0f; } public void Drop() { if (Current == null) { return; } Current.linearDamping = 0.0f; Current = null; } } }