Files
FutureMen/Assets/Scripts/Ai/AIController.cs

222 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}