add ckg
plantilla base para movimiento básico
This commit is contained in:
496
Assets/Game Kit Controller/Scripts/AI/AIPatrolSystem.cs
Normal file
496
Assets/Game Kit Controller/Scripts/AI/AIPatrolSystem.cs
Normal file
@@ -0,0 +1,496 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using static AIWayPointPatrol;
|
||||
using UnityEngine.Events;
|
||||
|
||||
public class AIPatrolSystem : MonoBehaviour
|
||||
{
|
||||
[Header ("Main Settings")]
|
||||
[Space]
|
||||
|
||||
public bool paused;
|
||||
public float minDistanceToNextPoint = 0.6f;
|
||||
public float patrolSpeed = 0.2f;
|
||||
public float returnToPatrolSpeed = 1;
|
||||
|
||||
public bool moveOnReversePatrolDirectionEnabled;
|
||||
|
||||
[Space]
|
||||
|
||||
public bool useCurrentPatrolIndexOnStart;
|
||||
public int currentPatrolIndex = 0;
|
||||
|
||||
[Space]
|
||||
[Header ("Patrol Time Settings")]
|
||||
[Space]
|
||||
|
||||
public bool useGeneralWaitTime = true;
|
||||
public float generalWaitTimeBetweenPoints;
|
||||
|
||||
[Space]
|
||||
|
||||
public bool moveBetweenPatrolsInOrder = true;
|
||||
|
||||
public float fixedTimeToChangeBetweenPatrols;
|
||||
|
||||
[Space]
|
||||
[Header ("Random Patrol Settings")]
|
||||
[Space]
|
||||
|
||||
public bool changeBetweenPointRandomly = true;
|
||||
[Range (0, 10)] public int changeRandomlyProbability = 1;
|
||||
public bool useTimeToChangeBetweenPointRandomly;
|
||||
|
||||
public bool useRandomTimeToChangePatrol;
|
||||
public Vector2 randomTimeLimits;
|
||||
|
||||
[Space]
|
||||
[Header ("Debug")]
|
||||
[Space]
|
||||
|
||||
public bool showDebugPrint;
|
||||
public bool returningToPatrol;
|
||||
public bool AIIsDestroyed;
|
||||
|
||||
[Space]
|
||||
[Header ("Gizmo Settings")]
|
||||
[Space]
|
||||
|
||||
public bool showGizmo;
|
||||
public float gizmoRadius;
|
||||
|
||||
[Space]
|
||||
[Header ("Event Settings")]
|
||||
[Space]
|
||||
|
||||
public bool useEventsOnPatrolWait;
|
||||
public UnityEvent eventsOnPatrolWait;
|
||||
|
||||
[Space]
|
||||
[Header ("Components")]
|
||||
[Space]
|
||||
|
||||
[Tooltip ("An AIWayPointPatrol path in your scene that this AI should follow. To create one add a GameObject with AIWayPointPatrol component and edit the Way Points then drag the GameObject here.")]
|
||||
public AIWayPointPatrol patrolPath;
|
||||
|
||||
public Transform AICharacter;
|
||||
public AINavMesh mainAINavmesh;
|
||||
|
||||
bool patrolAssigned;
|
||||
|
||||
Transform currentWayPoint;
|
||||
|
||||
int currentWaypointIndex = 0;
|
||||
Coroutine movement;
|
||||
bool settingNextPoint;
|
||||
float lastTimeChanged;
|
||||
float distanceToPoint;
|
||||
|
||||
Transform closestWaypointTransform;
|
||||
|
||||
List<patrolElementInfo> patrolList = new List<patrolElementInfo> ();
|
||||
|
||||
bool patrolListAssigned;
|
||||
|
||||
void Start ()
|
||||
{
|
||||
if (AICharacter == null) {
|
||||
AICharacter = transform;
|
||||
}
|
||||
|
||||
if (mainAINavmesh == null) {
|
||||
mainAINavmesh = AICharacter.GetComponent<AINavMesh> ();
|
||||
}
|
||||
|
||||
checkPatrolListAssigned ();
|
||||
|
||||
if (patrolPath != null) {
|
||||
setClosestWayPoint ();
|
||||
}
|
||||
}
|
||||
|
||||
void checkPatrolListAssigned ()
|
||||
{
|
||||
if (!patrolListAssigned) {
|
||||
if (patrolPath != null) {
|
||||
patrolList = patrolPath.patrolList;
|
||||
|
||||
patrolListAssigned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Update ()
|
||||
{
|
||||
if (!paused && patrolAssigned && !settingNextPoint) {
|
||||
|
||||
if (AIIsDestroyed) {
|
||||
enabled = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mainAINavmesh.isPatrolPaused ()) {
|
||||
if (AICharacter == null) {
|
||||
AIIsDestroyed = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
distanceToPoint = GKC_Utils.distance (AICharacter.position, currentWayPoint.position);
|
||||
|
||||
if (distanceToPoint < minDistanceToNextPoint) {
|
||||
if (returningToPatrol) {
|
||||
mainAINavmesh.setPatrolSpeed (patrolSpeed);
|
||||
|
||||
returningToPatrol = false;
|
||||
}
|
||||
|
||||
bool setRandomWayPoint = false;
|
||||
|
||||
if (changeBetweenPointRandomly) {
|
||||
int changeOrNotBool = Random.Range (0, (changeRandomlyProbability + 1));
|
||||
|
||||
if (changeOrNotBool == 0) {
|
||||
setRandomWayPoint = true;
|
||||
//print ("random waypoint");
|
||||
}
|
||||
}
|
||||
|
||||
if (setRandomWayPoint) {
|
||||
setNextRandomWaypoint ();
|
||||
} else {
|
||||
setNextWaypoint ();
|
||||
//print ("in order");
|
||||
}
|
||||
}
|
||||
|
||||
if (changeBetweenPointRandomly) {
|
||||
if (useTimeToChangeBetweenPointRandomly) {
|
||||
if (useRandomTimeToChangePatrol) {
|
||||
|
||||
} else {
|
||||
if (Time.time > fixedTimeToChangeBetweenPatrols + lastTimeChanged) {
|
||||
lastTimeChanged = Time.time;
|
||||
|
||||
setNextRandomWaypoint ();
|
||||
//print ("random waypoint");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void pauseOrPlayPatrol (bool state)
|
||||
{
|
||||
if (showDebugPrint) {
|
||||
print ("patrol paused state " + state);
|
||||
}
|
||||
|
||||
paused = state;
|
||||
}
|
||||
|
||||
public bool isPatrolPaused ()
|
||||
{
|
||||
return paused;
|
||||
}
|
||||
|
||||
public Transform closestWaypoint (Vector3 currentPosition)
|
||||
{
|
||||
float distance = Mathf.Infinity;
|
||||
|
||||
int patrolListCount = patrolList.Count;
|
||||
|
||||
if (useCurrentPatrolIndexOnStart) {
|
||||
int wayPointsCount = patrolList [currentPatrolIndex].wayPoints.Count;
|
||||
|
||||
for (int j = 0; j < wayPointsCount; j++) {
|
||||
float currentDistance = GKC_Utils.distance (currentPosition, patrolList [currentPatrolIndex].wayPoints [j].position);
|
||||
|
||||
if (currentDistance < distance) {
|
||||
distance = currentDistance;
|
||||
currentWaypointIndex = j;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < patrolListCount; i++) {
|
||||
|
||||
int wayPointsCount = patrolList [i].wayPoints.Count;
|
||||
|
||||
for (int j = 0; j < wayPointsCount; j++) {
|
||||
float currentDistance = GKC_Utils.distance (currentPosition, patrolList [i].wayPoints [j].position);
|
||||
|
||||
if (currentDistance < distance) {
|
||||
distance = currentDistance;
|
||||
currentPatrolIndex = i;
|
||||
currentWaypointIndex = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closestWaypointTransform = patrolList [currentPatrolIndex].wayPoints [currentWaypointIndex];
|
||||
|
||||
return closestWaypointTransform;
|
||||
}
|
||||
|
||||
public void setNextPatrolList ()
|
||||
{
|
||||
currentPatrolIndex++;
|
||||
|
||||
if (currentPatrolIndex > patrolList.Count - 1) {
|
||||
currentPatrolIndex = 0;
|
||||
}
|
||||
|
||||
settingNextPoint = false;
|
||||
|
||||
Vector3 currentPosition = AICharacter.position;
|
||||
|
||||
float distance = Mathf.Infinity;
|
||||
|
||||
int wayPointsCount = patrolList [currentPatrolIndex].wayPoints.Count;
|
||||
|
||||
for (int j = 0; j < wayPointsCount; j++) {
|
||||
float currentDistance = GKC_Utils.distance (currentPosition, patrolList [currentPatrolIndex].wayPoints [j].position);
|
||||
|
||||
if (currentDistance < distance) {
|
||||
distance = currentDistance;
|
||||
currentWaypointIndex = j;
|
||||
}
|
||||
}
|
||||
|
||||
currentWayPoint = patrolList [currentPatrolIndex].wayPoints [currentWaypointIndex];
|
||||
|
||||
setCurrentPatrolTarget (currentWayPoint);
|
||||
}
|
||||
|
||||
public void setNextWaypoint ()
|
||||
{
|
||||
if (movement != null) {
|
||||
StopCoroutine (movement);
|
||||
}
|
||||
|
||||
settingNextPoint = false;
|
||||
|
||||
if (mainAINavmesh.isPatrolPaused ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkPatrolListAssigned ();
|
||||
|
||||
movement = StartCoroutine (setNextWayPointCoroutine ());
|
||||
}
|
||||
|
||||
IEnumerator setNextWayPointCoroutine ()
|
||||
{
|
||||
mainAINavmesh.removeTarget ();
|
||||
|
||||
settingNextPoint = true;
|
||||
|
||||
if (useEventsOnPatrolWait) {
|
||||
eventsOnPatrolWait.Invoke ();
|
||||
}
|
||||
|
||||
if (useGeneralWaitTime) {
|
||||
WaitForSeconds delay = new WaitForSeconds (generalWaitTimeBetweenPoints);
|
||||
|
||||
yield return delay;
|
||||
} else {
|
||||
WaitForSeconds delay = new WaitForSeconds (patrolPath.waitTimeBetweenPoints);
|
||||
|
||||
yield return delay;
|
||||
}
|
||||
|
||||
if (!mainAINavmesh.isPatrolPaused ()) {
|
||||
if (moveOnReversePatrolDirectionEnabled) {
|
||||
currentWaypointIndex--;
|
||||
|
||||
if (currentWaypointIndex < 0) {
|
||||
currentWaypointIndex = patrolList [currentPatrolIndex].wayPoints.Count - 1;
|
||||
|
||||
if (moveBetweenPatrolsInOrder) {
|
||||
currentPatrolIndex++;
|
||||
|
||||
if (currentPatrolIndex > patrolList.Count - 1) {
|
||||
currentPatrolIndex = 0;
|
||||
}
|
||||
|
||||
currentWaypointIndex = patrolList [currentPatrolIndex].wayPoints.Count - 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
currentWaypointIndex++;
|
||||
|
||||
if (currentWaypointIndex > patrolList [currentPatrolIndex].wayPoints.Count - 1) {
|
||||
currentWaypointIndex = 0;
|
||||
|
||||
if (moveBetweenPatrolsInOrder) {
|
||||
currentPatrolIndex++;
|
||||
|
||||
if (currentPatrolIndex > patrolList.Count - 1) {
|
||||
currentPatrolIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentWayPoint = patrolList [currentPatrolIndex].wayPoints [currentWaypointIndex];
|
||||
|
||||
setCurrentPatrolTarget (currentWayPoint);
|
||||
}
|
||||
|
||||
settingNextPoint = false;
|
||||
}
|
||||
|
||||
public void setNextRandomWaypoint ()
|
||||
{
|
||||
if (movement != null) {
|
||||
StopCoroutine (movement);
|
||||
}
|
||||
|
||||
settingNextPoint = false;
|
||||
|
||||
if (mainAINavmesh.isPatrolPaused ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkPatrolListAssigned ();
|
||||
|
||||
movement = StartCoroutine (setNextRandomWayPointCoroutine ());
|
||||
}
|
||||
|
||||
IEnumerator setNextRandomWayPointCoroutine ()
|
||||
{
|
||||
mainAINavmesh.removeTarget ();
|
||||
|
||||
settingNextPoint = true;
|
||||
|
||||
if (useGeneralWaitTime) {
|
||||
WaitForSeconds delay = new WaitForSeconds (generalWaitTimeBetweenPoints);
|
||||
|
||||
yield return delay;
|
||||
} else {
|
||||
WaitForSeconds delay = new WaitForSeconds (patrolPath.waitTimeBetweenPoints);
|
||||
|
||||
yield return delay;
|
||||
}
|
||||
|
||||
if (!mainAINavmesh.isPatrolPaused ()) {
|
||||
|
||||
int currentWaypointIndexCopy = currentWaypointIndex;
|
||||
int currentPatrolIndexCopy = currentPatrolIndex;
|
||||
int checkLoop = 0;
|
||||
|
||||
if (patrolList.Count > 1) {
|
||||
while (currentPatrolIndexCopy == currentPatrolIndex) {
|
||||
currentPatrolIndex = Random.Range (0, patrolList.Count);
|
||||
|
||||
checkLoop++;
|
||||
|
||||
if (checkLoop > 100) {
|
||||
// print ("loop error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkLoop = 0;
|
||||
|
||||
while (currentWaypointIndexCopy == currentWaypointIndex) {
|
||||
currentWaypointIndex = Random.Range (0, patrolList [currentPatrolIndex].wayPoints.Count);
|
||||
|
||||
checkLoop++;
|
||||
|
||||
if (checkLoop > 100) {
|
||||
//print ("loop error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//print ("Next patrol: " + (currentPatrolIndex+1) + " and next waypoint: " + (currentWaypointIndex+1));
|
||||
currentWayPoint = patrolList [currentPatrolIndex].wayPoints [currentWaypointIndex];
|
||||
|
||||
setCurrentPatrolTarget (currentWayPoint);
|
||||
}
|
||||
|
||||
settingNextPoint = false;
|
||||
}
|
||||
|
||||
public void setClosestWayPoint ()
|
||||
{
|
||||
if (paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkPatrolListAssigned ();
|
||||
|
||||
patrolAssigned = true;
|
||||
|
||||
currentWayPoint = closestWaypoint (AICharacter.position);
|
||||
|
||||
setCurrentPatrolTarget (currentWayPoint);
|
||||
|
||||
mainAINavmesh.setPatrolSpeed (patrolSpeed);
|
||||
}
|
||||
|
||||
public void setCurrentPatrolTarget (Transform newTarget)
|
||||
{
|
||||
mainAINavmesh.setPatrolTarget (newTarget);
|
||||
|
||||
mainAINavmesh.setPatrolState (true);
|
||||
}
|
||||
|
||||
public void setReturningToPatrolState (bool state)
|
||||
{
|
||||
returningToPatrol = true;
|
||||
|
||||
if (returningToPatrol) {
|
||||
mainAINavmesh.setPatrolSpeed (returnToPatrolSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
public void resumePatrolStateOnAI ()
|
||||
{
|
||||
pauseOrPlayPatrol (false);
|
||||
|
||||
setClosestWayPoint ();
|
||||
}
|
||||
|
||||
public void pausePatrolStateOnAI ()
|
||||
{
|
||||
pauseOrPlayPatrol (true);
|
||||
|
||||
mainAINavmesh.setPatrolState (false);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void OnDrawGizmos ()
|
||||
{
|
||||
if (!showGizmo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GKC_Utils.isCurrentSelectionActiveGameObject (gameObject)) {
|
||||
DrawGizmos ();
|
||||
}
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected ()
|
||||
{
|
||||
DrawGizmos ();
|
||||
}
|
||||
|
||||
void DrawGizmos ()
|
||||
{
|
||||
if (showGizmo) {
|
||||
if (patrolList.Count > 0) {
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawSphere (patrolList [currentPatrolIndex].wayPoints [currentWaypointIndex].transform.position, gizmoRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user