我正试图在unity engine中开发一种与光子网络系统一起工作的人工智能。它应该相当简单:它向一个随机的玩家跑去,直到他和玩家之间达到5个单位的距离,然后它以稍慢的速度行走,直到到达玩家的前面。然后他发起攻击。到目前为止还不错,但有时,当AI与玩家之间的距离达到5个单位时,它会被卡住。我在网上尝试了几次修复,但都没有效果。
以下是代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(PhotonView))]
[RequireComponent(typeof(PhotonTransformView))]
public class EnemyAI : Photon.MonoBehaviour {
NavMeshAgent agent;
Animator anim;
PlayerController target;
[Header("Base settings")]
[SerializeField]
float health = 100f, damage, timeBetweenAttacks = 5f;
[Space]
[Header("Enemy Ragdoll")]
[SerializeField]
GameObject ragdoll;
AudioSource emotAud, stepAud;
[Space]
[SerializeField]
[Header("Audio")]
List<AudioClip> attackingAuds;
[Space]
[Header("Sunete pasi")]
[SerializeField]
List<AudioClip> stepAuds;
[Space]
[Header("Alte optiuni")]
[SerializeField]
float distantaLaCareIncepeSaMearga = 5f, walkSpeed = .5f, runSpeed = 3.5f;
bool dead, walking;
PhotonView killer;
float nextAttackTime;
// Use this for initialization
void Start () {
emotAud = gameObject.AddComponent<AudioSource>();
stepAud = gameObject.AddComponent<AudioSource>();
emotAud.spatialBlend = 1;
emotAud.maxDistance = 7;
stepAud.spatialBlend = 1;
stepAud.maxDistance = 7;
emotAud.playOnAwake = false;
stepAud.playOnAwake = false;
dead = false;
target = null;
agent = GetComponent<NavMeshAgent>();
anim = GetComponent<Animator>();
killer = null;
}
// Update is called once per frame
void Update () {
if (photonView.isMine)
{
if (walking)
{
agent.speed = walkSpeed;
}
else
{
agent.speed = runSpeed;
}
if (health <= 0)
{
if (!dead)
{
dead = true;
photonView.RPC("die", PhotonTargets.AllBuffered);
}
}
if (!target)
{
if (!PhotonNetwork.offlineMode)
{
nextAttackTime = (float)PhotonNetwork.room.CustomProperties["remainTime"];
}
else
{
nextAttackTime = 0f;
}
PlayerController[] controllers = FindObjectsOfType<PlayerController>();
int randCh = Random.Range(0, controllers.Length);
if (controllers.Length > 0)
{
target = controllers[randCh];
}
anim.SetFloat("move", 0);
}
else
{
if (Vector3.Distance(transform.position, target.gameObject.transform.position) > 1.8f)
{
if (Vector3.Distance(transform.position, target.gameObject.transform.position) > distantaLaCareIncepeSaMearga)
{
walking = false;
}
else
{
walking = true;
}
anim.SetBool("walking", walking);
anim.SetFloat("move", 1);
//print("Active: " + agent.isActiveAndEnabled + " Pend: " + agent.pathPending + " Has path: " + agent.hasPath);
if (agent.isActiveAndEnabled)
{
if (!agent.pathPending)
{
agent.SetDestination(target.gameObject.transform.position - transform.forward * 1.2f);
}
}
}
else
{
if (!PhotonNetwork.offlineMode)
{
if (nextAttackTime >= (float)PhotonNetwork.room.CustomProperties["remainTime"])
{
anim.SetTrigger("attack");
nextAttackTime -= timeBetweenAttacks;
}
else
{
anim.SetFloat("move", 0);
}
}
else
{
if (nextAttackTime <= 0f)
{
anim.SetTrigger("attack");
nextAttackTime += timeBetweenAttacks;
}
else
{
nextAttackTime -= Time.deltaTime;
anim.SetFloat("move", 0);
}
}
}
}
}
}
void OnDrawGizmosSelected()
{
if (target)
{
Gizmos.color = Color.blue;
Gizmos.DrawSphere(agent.destination, 1);
}
}
[PunRPC]
void die()
{
if (killer)
{
killer.gameObject.GetComponent<PlayerController>().kill();
}
if (attackingAuds.Count > 0)
{
emotAud.clip = attackingAuds[Random.Range(0, attackingAuds.Count - 1)];
emotAud.Play();
}
gameObject.GetComponent<CapsuleCollider>().enabled = false;
Instantiate(ragdoll, transform.position, transform.rotation);
Destroy(this.gameObject);
}
public void attack()
{
if (target && target.health >= 0)
{
if (Vector3.Distance(target.gameObject.transform.position, transform.position) <= 2f)
{
target.doDamage(damage);
if (target.health <= 0)
{
target.photonView.RPC("die", PhotonTargets.All, true);
}
}
}
}
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag.Contains("Bullet"))
{
killer = col.gameObject.GetComponent<Magic_Bullet>().owner;
target = killer.gameObject.GetComponent<PlayerController>();
photonView.RPC("takeDamage", PhotonTargets.AllBuffered, col.gameObject.GetComponent<Magic_Bullet>().damage);
PhotonNetwork.Destroy(col.gameObject);
}
}
[PunRPC]
void takeDamage(float dmg)
{
health -= dmg;
}
public void step()
{
stepAud.clip = stepAuds[Random.Range(0, stepAuds.Count - 1)];
stepAud.Play();
}
}
我做错了什么?