namespace Zinnia.Tracking.Follow.Modifier.Property.Rotation { using UnityEngine; using Zinnia.Extension; /// /// Updates the rigidbody by applying force at the position difference between the source and the attachment point providing a torque rotation. /// public class RigidbodyForceAtPosition : PropertyModifier { [Tooltip("The point where the attachment was made.")] [SerializeField] private GameObject attachmentPoint; /// /// The point where the attachment was made. /// public GameObject AttachmentPoint { get { return attachmentPoint; } set { attachmentPoint = value; } } /// /// A cached version of the target rigidbody. /// protected Rigidbody cachedTargetRigidbody; /// /// A cached version of the target. /// protected GameObject cachedTarget; /// /// Clears . /// public virtual void ClearAttachmentPoint() { if (!this.IsValidState()) { return; } AttachmentPoint = default; } /// /// Applies a force at the attachment point position to the target rigidbody creating torque for rotation. /// /// The source to utilize in the modification. /// The target to modify. /// The offset of the target against the source when modifying. protected override void DoModify(GameObject source, GameObject target, GameObject offset = null) { cachedTargetRigidbody = cachedTargetRigidbody == null || target != cachedTarget ? target.TryGetComponent(true) : cachedTargetRigidbody; cachedTarget = target; if (cachedTargetRigidbody == null || source == null || AttachmentPoint == null) { return; } Vector3 attachmentPointPosition = AttachmentPoint.transform.position; Vector3 rotationForce = source.transform.position - attachmentPointPosition; cachedTargetRigidbody.AddForceAtPosition(rotationForce, attachmentPointPosition, ForceMode.VelocityChange); } } }