#if GRAPH_DESIGNER /// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Runtime.Tasks.Actions.GameObjectTasks { using Opsive.GraphDesigner.Runtime.Variables; using UnityEngine; [Opsive.Shared.Utility.Category("GameObject")] [Opsive.Shared.Utility.Description("Moves the Transform in a direction with acceleration.")] public class MoveInDirection : TargetGameObjectAction { [Tooltip("The direction to move in. If this value is 0 then the forward Transform direction is used.")] [SerializeField] protected SharedVariable m_Direction; [Tooltip("The base movement speed.")] [SerializeField] protected SharedVariable m_Speed = 5f; [Tooltip("The acceleration rate (units per second squared).")] [SerializeField] protected SharedVariable m_Acceleration = 10f; [Tooltip("The maximum speed.")] [SerializeField] protected SharedVariable m_MaxSpeed = 10f; [Tooltip("Should the movement be relative to the object's local space?")] [SerializeField] protected SharedVariable m_UseLocalSpace = false; private float m_CurrentSpeed; private Vector3 m_CurrentVelocity; private Rigidbody m_Rigidbody; /// /// Initializes the target GameObject and caches the Rigidbody reference. /// protected override void InitializeTarget() { base.InitializeTarget(); m_Rigidbody = m_ResolvedGameObject.GetComponent(); if (m_Rigidbody != null && m_Rigidbody.isKinematic) { Debug.LogWarning($"Warning: The Rigidbody on GameObject {m_ResolvedGameObject} must be a non-kinematic Rigidbody."); m_Rigidbody.isKinematic = false; m_Rigidbody.useGravity = false; } } /// /// Called when the state machine starts. /// public override void OnStart() { base.OnStart(); m_CurrentSpeed = 0f; m_CurrentVelocity = Vector3.zero; } /// /// Moves in the specified direction. /// /// The status of the action. public override TaskStatus OnUpdate() { Vector3 direction; if (m_Direction.Value != Vector3.zero) { direction = m_Direction.Value.normalized; } else { if (m_UseLocalSpace.Value) { direction = transform.localRotation * Vector3.forward; } else { direction = transform.forward; } } // Calculate velocity. m_CurrentSpeed = Mathf.Min(m_CurrentSpeed + m_Acceleration.Value * Time.deltaTime, m_MaxSpeed.Value); var targetSpeed = m_Speed.Value * m_CurrentSpeed / m_MaxSpeed.Value; m_CurrentVelocity = direction * targetSpeed; // Move. var moveDelta = m_CurrentVelocity * Time.deltaTime; if (m_Rigidbody != null) { var worldVelocity = m_UseLocalSpace.Value ? m_Rigidbody.rotation * m_CurrentVelocity : m_CurrentVelocity; #if UNITY_6000_3_OR_NEWER m_Rigidbody.linearVelocity = worldVelocity; #else m_Rigidbody.velocity = worldVelocity; #endif } else if (m_UseLocalSpace.Value) { transform.localPosition += moveDelta; } else { transform.position += moveDelta; } return TaskStatus.Running; } /// /// Resets the action values back to their default. /// public override void Reset() { base.Reset(); m_Direction = Vector3.zero; m_Speed = 5f; m_Acceleration = 10f; m_MaxSpeed = 10f; m_UseLocalSpace = false; } } } #endif