我正在为游戏中的角色设置一个简单的小AI。由于某些原因,我在使用NavMeshAgent
时要播放动画时遇到了很多问题,我不明白为什么。我汇集了Unity API,这是一个航点系统,我什至无法正常工作。我希望,如果有人可以在这方面给我一些意见,也可以解决其他问题。我在这里真的迷路了,不胜感激。底部的代码一直有效,直到命中Patrol,然后玩家移动且没有动画。我觉得我需要进一步了解navmesh。或一般而言,我需要了解更多信息。
e// Patrol.cs
using UnityEngine;
using UnityEngine.AI;
using System.Collections;
public class Enemy_Patrol : MonoBehaviour
{
public Transform[] points;
public Animator anim;
private int destPoint = 0;
private NavMeshAgent agent;
void Start()
{
agent = GetComponent<NavMeshAgent>();
anim = GetComponent<Animator>();
// Disabling auto-braking allows for continuous movement
// between points (ie, the agent doesn't slow down as it
// approaches a destination point).
agent.autoBraking = false;
GotoNextPoint();
}
void GotoNextPoint()
{
// Returns if no points have been set up
if (points.Length == 0)
return;
// Set the agent to go to the currently selected destination.
agent.destination = points[destPoint].position;
anim.SetBool("WalkForwards", true);
anim.SetBool("IsIdle", false);
// Choose the next point in the array as the destination,
// cycling to the start if necessary.
destPoint = (destPoint + 1) % points.Length;
}
void Update()
{
// Choose the next destination point when the agent gets
// close to the current one.
if (!agent.pathPending && agent.remainingDistance < 0.5f)
GotoNextPoint();
}
}
// Code i wrote to handle following chasing etc.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class AI_Tester : MonoBehaviour
{
private float patrolSpeed = .2f;
public NavMeshAgent agent;
public GameObject[] waypoints;
private int waypointInd = 0;
public Transform player;
static Animator anim;
public SealForce_DestructableObjects destructableObjects;
public Transform enemy;
// Use this for initialization
void Start()
{
anim = GetComponentInChildren<Animator>();
agent = GetComponent<NavMeshAgent>();
destructableObjects = GetComponent<SealForce_DestructableObjects>();
waypoints = GameObject.FindGameObjectsWithTag("waypoints");
waypointInd = Random.Range(0, waypoints.Length);
}
void AIMovements()
{
if (Vector3.Distance(player.position, this.transform.position) <= 30)
{
Vector3 direction = player.position - this.transform.position;
direction.y = 0;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation,
Quaternion.LookRotation(direction), 0.1f);
if (direction.magnitude > 15)
{
MoveToFiringRange();
}
if (direction.magnitude <= 15)
{
AttackPlayer();
}
}
else if (Vector3.Distance(player.position, this.transform.position) > 30)
{
WaitingOnAction();
}
}
public void Update()
{
AIMovements();
}
public void AttackPlayer()
{
anim.SetTrigger("IsAttacking");
anim.SetBool("IsIdle", false);
anim.SetBool("RunForwards", false);
}
public void MoveToFiringRange()
{
this.transform.Translate(0, 0, 0.04f);
anim.SetBool("RunForwards", true);
anim.SetBool("IsIdle", false);
anim.ResetTrigger("IsAttacking");
}
public void WaitingOnAction()
{
anim.SetBool("IsIdle", true);
anim.SetBool("RunForwards", false);
StartCoroutine("BackToPatrol");
}
//program works fine all the up to here. The only thing wrong with patrol is no animation.
IEnumerator BackToPatrol()
{
yield return new WaitForSeconds(5);
anim.SetBool("IsIdle", false);
Patrol();
}
public void Patrol()
{
Debug.Log("In Patrol");
agent.speed = patrolSpeed;
if (Vector3.Distance(this.transform.position, waypoints[waypointInd].transform.position) >= 2)
{
agent.SetDestination(waypoints[waypointInd].transform.position);
anim.SetBool("WalkForwards", true);
}
if (Vector3.Distance(this.transform.position, waypoints[waypointInd].transform.position) <= 2)
{
waypointInd += 1;
if (waypointInd > waypoints.Length)
{
waypointInd = 0;
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class AI_Tester : MonoBehaviour
{
public bool isPatrolling;
private float patrolSpeed = 1.5f;
public NavMeshAgent agent;
public GameObject[] waypoints;
private int waypointInd = 0;
public Transform player;
static Animator anim;
//public SealForce_DestructableObjects destructableObjects;
//public Transform enemy;
// Use this for initialization
void Start()
{
anim = GetComponentInChildren<Animator>();
agent = GetComponent<NavMeshAgent>();
//destructableObjects = GetComponent<SealForce_DestructableObjects>();
waypoints = GameObject.FindGameObjectsWithTag("waypoints");
waypointInd = Random.Range(0, waypoints.Length);
}
void AIMovements()
{
if (Vector3.Distance(player.position, this.transform.position) <= 30)
{
Vector3 direction = player.position - this.transform.position;
direction.y = 0;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation,
Quaternion.LookRotation(direction), 0.1f);
if (direction.magnitude > 15)
{
//StopCoroutine("BackToPatrol");
StopCoroutine("Patrol");
isPatrolling = false;
MoveToFiringRange();
}
if (direction.magnitude <= 15)
{
//StopCoroutine("BackToPatrol");
StopCoroutine("Patrol");
isPatrolling = false;
AttackPlayer();
}
}
else if (Vector3.Distance(player.position, this.transform.position) > 30 && !isPatrolling)
{
//StopCoroutine("BackToPatrol");
StopCoroutine("Patrol");
WaitingOnAction();
}
}
public void Update()
{
AIMovements();
}
public void AttackPlayer()
{
anim.SetTrigger("IsAttacking");
anim.SetBool("IsIdle", false);
anim.SetBool("RunForwards", false);
}
public void MoveToFiringRange()
{
this.transform.Translate(0, 0, 0.04f);
anim.SetBool("RunForwards", true);
anim.SetBool("IsIdle", false);
anim.ResetTrigger("IsAttacking");
}
public void WaitingOnAction()
{
anim.SetBool("IsIdle", true);
anim.SetBool("RunForwards", false);
StartCoroutine("BackToPatrol");
}
IEnumerator BackToPatrol()
{
isPatrolling = true;
yield return new WaitForSeconds(5);
anim.SetBool("IsIdle", false);
yield return StartCoroutine ("Patrol");
isPatrolling = false;
}
IEnumerator Patrol()
{
Debug.Log("In Patrol");
agent.speed = patrolSpeed;
agent.SetDestination(waypoints[waypointInd].transform.position);
anim.SetBool("WalkForwards", true);
while (Vector3.Distance(this.transform.position, waypoints[waypointInd].transform.position) >= 2 && !isPatrolling)
{
yield return null;
}
waypointInd++;
if (waypointInd >= waypoints.Length) waypointInd = 0;
}
/* public void Patrol()
{
Debug.Log("In Patrol");
agent.speed = patrolSpeed;
if (Vector3.Distance(this.transform.position, waypoints[waypointInd].transform.position) >= 2)
{
agent.SetDestination(waypoints[waypointInd].transform.position);
anim.SetBool("IsIdle", false);
anim.SetBool("WalkForwards", false);
}
if (Vector3.Distance(this.transform.position, waypoints[waypointInd].transform.position) <= 2)
{
waypointInd += 1;
if (waypointInd > waypoints.Length)
{
waypointInd = 0;*/
}
答案 0 :(得分:1)
您正在每帧更新上调用WaitingOnAction
,这会将动画制作者的IsIdle
设置为true,并开始新的BackToPatrol
协程。这不应该发生。再次调用WaitingOnAction
之前,请尝试检查字符是否已到达目的地。像这样:
else if (Vector3.Distance(player.position, this.transform.position) > 30 && !isPatrolling)
{
WaitingOnAction();
}
在您的协同程序中:
IEnumerator BackToPatrol()
{
isPatrolling = true;
yield return new WaitForSeconds(5);
anim.SetBool("IsIdle", false);
yield return StartCoroutine("Patrol");
isPatrolling = false;
}
IEnumerator Patrol()
{
Debug.Log("In Patrol");
agent.speed = patrolSpeed;
agent.SetDestination(waypoints[waypointInd].transform.position);
anim.SetBool("WalkForwards", true);
agent.isStopped = false;
while (Vector3.Distance(this.transform.position, waypoints[waypointInd].transform.position) >= 2 && isPatrolling)
{
yield return null;
}
agent.isStopped = true;
anim.SetBool("WalkForwards", false);
waypointInd++;
if(waypointInd >= waypoints.Length) waypointInd = 0;
}
我没有测试它,但是类似的东西应该可以工作。