222 lines
6.1 KiB
C#
222 lines
6.1 KiB
C#
using Knife.Effects.SimpleController;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.AI;
|
||
|
||
|
||
public class AIController : MonoBehaviour
|
||
{
|
||
public AudioClip introAudio;//开场白音频
|
||
|
||
//添加动画参数
|
||
public string waveAnimationTrigger = "Wave";//打招呼动画触发器
|
||
public string idleAnimationTrigger = "Idle"; // 待机动画触发器
|
||
public string leaveAnimationTrigger = "Leave";//离开动画触发器
|
||
|
||
//添加:添加离开动画最短播放时间
|
||
public float minLeaveAnimationTime = 3f; // 离开动画最少播放3秒
|
||
public float maxLeaveAnimationTime = 6f; // 离开动画最多播放4秒
|
||
|
||
//添加:打招呼动画旋转角度
|
||
public float waveRotationAngle = 90f; // 打招呼时相对于玩家的旋转角度
|
||
|
||
//添加介绍完成事件
|
||
public event Action OnIntroductionComplete;
|
||
|
||
private AudioSource audioSource;
|
||
private NavMeshAgent navAgent;
|
||
private Animator animator;
|
||
private bool isIntroductionStarted = false;
|
||
private Transform playerTransform;
|
||
private Coroutine introductionCoroutine;
|
||
private bool hasIntroductionCompleted = false;//添加标志位
|
||
|
||
//添加:存储初始旋转
|
||
private Quaternion initialRotation;
|
||
|
||
private void Awake()
|
||
{
|
||
audioSource= GetComponent<AudioSource>();
|
||
if(audioSource == null)
|
||
{
|
||
audioSource = gameObject.AddComponent<AudioSource>();
|
||
}
|
||
navAgent = GetComponent<NavMeshAgent>();
|
||
if(navAgent == null)
|
||
{
|
||
Debug.LogError("自动寻路组件不在AI身上");
|
||
}
|
||
animator = GetComponent<Animator>();
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
//存储初始旋转
|
||
initialRotation = transform.rotation;
|
||
FindPlayer();
|
||
}
|
||
|
||
//动态查找Player
|
||
private void FindPlayer()
|
||
{
|
||
//通过GameManager获取Player
|
||
if (GameManager.Ins != null && GameManager.Ins.player != null)
|
||
{
|
||
playerTransform = GameManager.Ins.player.transform;
|
||
Debug.Log("在GameManager中找到Player");
|
||
return;
|
||
}
|
||
|
||
//通过标签查找Player
|
||
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
|
||
if (playerObj != null)
|
||
{
|
||
playerTransform = playerObj.transform;
|
||
Debug.Log("找到Player标签");
|
||
return;
|
||
}
|
||
|
||
//通过类型查找Player组件
|
||
PlayerController playerController = FindObjectOfType<PlayerController>();
|
||
if (playerController != null)
|
||
{
|
||
playerTransform = playerController.transform;
|
||
Debug.Log("找到player组件");
|
||
return;
|
||
}
|
||
|
||
Debug.LogError("Player没有找到,请重试");
|
||
StartCoroutine(RetryFindPlayer());
|
||
}
|
||
|
||
private IEnumerator RetryFindPlayer()
|
||
{
|
||
yield return new WaitForSeconds(1f);
|
||
FindPlayer();
|
||
}
|
||
public void StartIntroduction()
|
||
{
|
||
if (isIntroductionStarted) return;
|
||
|
||
//确保我们有Player引用
|
||
if(playerTransform == null)
|
||
{
|
||
FindPlayer();
|
||
if (playerTransform == null)
|
||
{
|
||
Debug.LogError("不能开始介绍,玩家参考是空的");
|
||
return;
|
||
}
|
||
}
|
||
|
||
isIntroductionStarted = true;
|
||
Debug.Log("AI介绍开始");
|
||
|
||
|
||
//停止任何现有的协程
|
||
if (introductionCoroutine != null)
|
||
{
|
||
StopCoroutine(introductionCoroutine);
|
||
}
|
||
|
||
//启动开场白协程
|
||
introductionCoroutine = StartCoroutine(IntroductionRoutine());
|
||
}
|
||
|
||
private IEnumerator IntroductionRoutine()
|
||
{
|
||
Debug.Log("开始介绍开场白");
|
||
|
||
//面向玩家
|
||
transform.LookAt(playerTransform);
|
||
|
||
//存储当前朝向作为待机朝向
|
||
Quaternion idleRotation = transform.rotation;
|
||
|
||
//播放打招呼动画
|
||
if (animator != null && !string.IsNullOrEmpty(waveAnimationTrigger))
|
||
{
|
||
//旋转到打招呼方向 - 修正朝向问题
|
||
//计算正确的旋转方向:向左旋转90度
|
||
transform.Rotate(Vector3.up, waveRotationAngle);
|
||
|
||
animator.SetTrigger(waveAnimationTrigger);
|
||
Debug.Log("播放打招呼动画");
|
||
|
||
//同时播放开场白音频
|
||
if (introAudio != null)
|
||
{
|
||
Debug.Log("玩家音频播放:" + introAudio.name);
|
||
audioSource.clip = introAudio;
|
||
audioSource.Play();
|
||
}
|
||
|
||
//等待动画播放一会儿再开始音频
|
||
yield return new WaitForSeconds(10f);
|
||
|
||
//旋转回待机方向(面向玩家)
|
||
transform.rotation = idleRotation;
|
||
|
||
//播放待机动画
|
||
if (!string.IsNullOrEmpty(idleAnimationTrigger))
|
||
{
|
||
animator.SetTrigger(idleAnimationTrigger);
|
||
Debug.Log("播放待机动画");
|
||
}
|
||
|
||
//等待音频播放完毕
|
||
if (introAudio != null)
|
||
{
|
||
float remainingAudioTime = introAudio.length - 2f;
|
||
if (remainingAudioTime > 0)
|
||
{
|
||
yield return new WaitForSeconds(remainingAudioTime);
|
||
}
|
||
Debug.Log("介绍音频完成");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("AI身上没有介绍音频");
|
||
yield return new WaitForSeconds(3f);
|
||
}
|
||
|
||
//播放离开动画
|
||
if (animator != null && !string.IsNullOrEmpty(leaveAnimationTrigger))
|
||
{
|
||
animator.SetTrigger(leaveAnimationTrigger);
|
||
Debug.Log("播放离开动画");
|
||
|
||
//修改:随机选择3-4秒的播放时间
|
||
float leaveTime = UnityEngine.Random.Range(minLeaveAnimationTime, maxLeaveAnimationTime);
|
||
//等待离开动画播放
|
||
yield return new WaitForSeconds(leaveTime);
|
||
|
||
Debug.Log($"离开动画播放了 {leaveTime} 秒");
|
||
}
|
||
|
||
//触发介绍完成事件
|
||
hasIntroductionCompleted = true;
|
||
OnIntroductionComplete?.Invoke();
|
||
Debug.Log("AI介绍完成,准备离开");
|
||
|
||
//禁用AI角色
|
||
gameObject.SetActive(false);
|
||
|
||
//可选:销毁AI对象
|
||
//Destroy(gameObject);
|
||
}
|
||
|
||
|
||
private void OnDestroy()
|
||
{
|
||
//清理协程
|
||
if (introductionCoroutine != null)
|
||
{
|
||
StopCoroutine(introductionCoroutine);
|
||
}
|
||
}
|
||
}
|