BITFALL/Assets/Plugins/Character Controller Pro/Demo/Scripts/AI/AIFollowBehaviour.cs

110 lines
2.9 KiB
C#

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<CharacterActor, CharacterStateController>();
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 --------------------------------------------------------------------------------------------------
/// <summary>
/// Sets the target to follow (only for the follow behaviour).
/// </summary>
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);
}
}
}