using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using Lightbug.CharacterControllerPro.Implementation; using Lightbug.Utilities; using Lightbug.CharacterControllerPro.Core; namespace Lightbug.CharacterControllerPro.Demo { [AddComponentMenu("Character Controller Pro/Demo/Character/AI/Follow Behaviour")] public class AIFollowBehaviour : CharacterAIBehaviour { [Tooltip("The target transform used by the follow behaviour.")] [SerializeField] Transform followTarget = null; [Tooltip("Desired distance to the target. if the distance to the target is less than this value the character will not move.")] [SerializeField] float reachDistance = 3f; [Tooltip("The wait time between actions updates.")] [Min(0f)] [SerializeField] float refreshTime = 0.65f; float timer = 0f; NavMeshPath navMeshPath = null; protected CharacterStateController stateController = null; protected override void Awake() { base.Awake(); stateController = this.GetComponentInBranch(); stateController.MovementReferenceMode = MovementReferenceParameters.MovementReferenceMode.World; } void OnEnable() { navMeshPath = new NavMeshPath(); ; } public override void EnterBehaviour(float dt) { timer = refreshTime; } public override void UpdateBehaviour(float dt) { if (timer >= refreshTime) { timer = 0f; UpdateFollowTargetBehaviour(dt); } else { timer += dt; } } // Follow Behaviour -------------------------------------------------------------------------------------------------- /// /// Sets the target to follow (only for the follow behaviour). /// public void SetFollowTarget(Transform followTarget, bool forceUpdate = true) { this.followTarget = followTarget; if (forceUpdate) timer = refreshTime + Mathf.Epsilon; } void UpdateFollowTargetBehaviour(float dt) { if (followTarget == null) return; characterActions.Reset(); NavMesh.CalculatePath(transform.position, followTarget.position, NavMesh.AllAreas, navMeshPath); if (navMeshPath.corners.Length < 2) return; Vector3 path = navMeshPath.corners[1] - navMeshPath.corners[0]; bool isDirectPath = navMeshPath.corners.Length == 2; if (isDirectPath && path.magnitude <= reachDistance) return; if (navMeshPath.corners.Length > 1) SetMovementAction(path); } } }