public class NPC5 : MonoBehaviour
{
public Transform player;//获取玩家的引用
public float rightspeed=1;
public float leftspeed = 0.5f;//npc转身的速度
private float dis;//玩家和npc之间的距离
private float dir;//玩家和npc之间的方向(左右侧)
private float angle;//玩家与npc之间的夹角
private Animator ani;
public int num;//玩家的状态
public AudioClip aud1;
public AudioClip aud2;
public AudioClip aud3;
private AudioSource aud;
public float longestDis = 5f;//触发范围
private Vector3 p;//npc指向玩家的向量
// Start is called before the first frame update
void Start()
{
ani = GetComponent<Animator>();
InvokeRepeating("jiance1", 0.0001f, Time.deltaTime);
}
// Update is called once per frame
void Update()
{
aud = GetComponent<AudioSource>();
dis = (player.position - transform.position).magnitude;
if (dis >= longestDis)
{
ani.SetBool("rightturn1", false);
ani.SetBool("rightturn2", false);
ani.SetBool("leftturn1", false);
ani.SetBool("leftturn2", false);
}
}
void jiance1()
{
p = player.position - transform.position;
dis = (player.position - transform.position).magnitude;//计算玩家和npc之间的距离
dir = Vector3.Cross(this.transform.forward, p).y;//大于0,玩家在npc右方,反之
Vector3 d1 = transform.forward;
Vector3 d2 = new Vector3(0, 3, 0);
float dot = Vector3.Dot(d1, player.forward.normalized); //d2.normalized向量归一化
float angle = Mathf.Acos(dot) * Mathf.Rad2Deg;
Debug.Log("夹角:"+Mathf.Abs(angle)+" dir:"+dir);
if (dis <= longestDis)
{
if (Mathf.Abs(angle) < 160f)
{
Debug.Log("夹角过大" + Mathf.Abs(angle));
if (dir > 0)
{
Debug.Log("检测到在右方,开始旋转"+dir);
ani.SetBool("rightturn1", true);
ani.SetBool("rightturn2", true);
rightturn();
}
else if (dir < 0)
{
Debug.Log("检测到在左方,开始旋转"+dir);
ani.SetBool("leftturn1", true);
ani.SetBool("leftturn2", true);
leftturn();
}
}
else if (Mathf.Abs(angle) >=160f)
{
Debug.Log("!!!!??????????????????!!!!!!!!!!!!!!!!");
Invoke("playclip", 0);
}
}
}
void playclip()
{
Debug.Log("开始播放音频,调用");
ani.SetBool("leftturn1", true);
ani.SetBool("rightturn1", true);
ani.SetBool("rightturn2", false);
ani.SetBool("leftturn2", false);
if (num == 1)
{
aud.clip = aud1;
aud.Play();
}
if (num == 2)
{
aud.clip = aud2;
aud.Play();
}
if (num == 3)
{
aud.clip = aud3;
aud.Play();
}
CancelInvoke("jiance1");
CancelInvoke("playclip");
}
void rightturn()
{
Vector3 v = new Vector3(player.position.x, transform.position.y, player.position.z);
Quaternion rotation = Quaternion.LookRotation(v - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * rightspeed);
}
void leftturn()
{
Vector3 v = new Vector3(player.position.x, transform.position.y, player.position.z);
Quaternion rotation = Quaternion.LookRotation(v - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * leftspeed);
}
}
状态机:
非常非常粗糙丑陋的代码,还有很多可以改进的地方,比如左右转身的速度没必要分开设置的……
但无所谓了