来源于一个因为某些原因做废了的Demo,但是里面的东西还是挺多的。
这里实现了一个怪物自动追击玩家,丢失目标后,自动返回其原点的功能:
实现思路:
首先,需要用到Unity自带的NavMeshAgent组件,也就是自动寻路组件
然后思路是分为两个部分,思考和移动,首先怪物会思考与玩家的位置,并在满足与玩家的某些交互条件的时候自动切换到相应的状态,也就是将思考结果付之行动。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine.AI;
/*
*琦玉老师的二弟子
*/
namespace Control{//NameSpace_Start--------------------------------------------------------------------------------------------------------
public class Ctrl_EnemyAi : MonoBehaviour {
//Class_Start--------------------------------------------------------------------------------------------------------
//1.思考
//2.移动
private NavMeshAgent agent;
private GameObject Player;
private Vector3 BoringPosition;
private Ctrl_Enemy_ShuXing EnemyShuXing;
public float RotateSpeed;
private void Awake()
{
agent = this.GetComponent<NavMeshAgent>();
EnemyShuXing = this.GetComponent<Ctrl_Enemy_ShuXing>();
BoringPosition = this.transform.position;
Player = GameObject.FindGameObjectWithTag("Player");
}
private void Start()
{
StartCoroutine("FindPlayer");
StartCoroutine("Moving");
}
/// <summary>
/// 寻找玩家协程
/// </summary>
/// <returns></returns>
IEnumerator FindPlayer()
{
while (true)
{
yield return new WaitForSeconds(0.45f);
Vector3 PlayerPosition = Player.transform.position;
if (EnemyShuXing.CurrentState!=Global.GlobalParameter.EnemyState.Dealth)
{
//得到与主角的距离
float Distance = Vector3.Distance(transform.position, PlayerPosition);
//距离判断
if (Distance <= 2.3f)
{
//攻击状态
EnemyShuXing.CurrentState = Global.GlobalParameter.EnemyState.Attack;
}
else if (Distance <=8f)
{
//追击状态
EnemyShuXing.CurrentState = Global.GlobalParameter.EnemyState.walking;
}
else
{
//返回出生位置,Idle
EnemyShuXing.CurrentState = Global.GlobalParameter.EnemyState.LostTarget;
}
}
}
}
IEnumerator Moving()
{
while (true)
{
yield return null;
switch (EnemyShuXing.CurrentState)
{
case Global.GlobalParameter.EnemyState.walking:
agent.SetDestination(Player.transform.position);
break;
case Global.GlobalParameter.EnemyState.LostTarget:
agent.SetDestination(BoringPosition);
if (Vector3.Distance(BoringPosition, this.transform.position) <= 2.3f)
{
EnemyShuXing.CurrentState = Global.GlobalParameter.EnemyState.idle;
}
break;
default:
break;
}
}
}
private void Update()
{
if (EnemyShuXing.CurrentState == Global.GlobalParameter.EnemyState.Attack)
{
transform.rotation = Quaternion.Lerp(transform.rotation,Quaternion.LookRotation(Player.transform.position-this.transform.position),RotateSpeed* Time.deltaTime);
}
}
//Class_End--------------------------------------------------------------------------------------------------------
}
}//NameSpace_End--------------------------------------------------------------------------------------------------------