修改湖南吉首、山东济南室外场景
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 978ee1b84ebbb9148891a91ea5549fe3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,355 +0,0 @@
|
||||
using Knife.Effects.SimpleController;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using Mirror;
|
||||
|
||||
public enum AIState
|
||||
{
|
||||
//出生
|
||||
Init = 0,
|
||||
//开场
|
||||
Greet = 1,
|
||||
//走到玩家身侧
|
||||
ToPlayer = 2,
|
||||
}
|
||||
|
||||
public class AIController : NetworkBehaviour
|
||||
{
|
||||
public AudioClip introAudio;//开场白音频
|
||||
public float followDistance = 2f;//跟随距离
|
||||
public float followUpdateInterval = 0.5f;//更新跟随位置的间隔时间
|
||||
|
||||
//添加介绍完成事件
|
||||
public event Action OnIntroductionComplete;
|
||||
|
||||
private AudioSource audioSource;
|
||||
private NavMeshAgent navAgent;
|
||||
private Animator animator;
|
||||
[SyncVar]
|
||||
private bool isIntroductionStarted = false;
|
||||
[SyncVar]
|
||||
private bool isFollowing = false;
|
||||
private Transform playerTransform;
|
||||
private Coroutine followCoroutine;
|
||||
private Coroutine introductionCoroutine;
|
||||
[SyncVar]
|
||||
private bool hasIntroductionCompleted = false;//添加标志位
|
||||
|
||||
public override void OnStartServer()
|
||||
{
|
||||
base.OnStartServer();
|
||||
Debug.Log("AI服务器初始化");
|
||||
|
||||
//初始化组件
|
||||
audioSource = GetComponent<AudioSource>();
|
||||
if(audioSource == null)
|
||||
{
|
||||
audioSource = gameObject.AddComponent<AudioSource>();
|
||||
}
|
||||
navAgent=GetComponent<NavMeshAgent>();
|
||||
if (navAgent == null)
|
||||
{
|
||||
Debug.LogError("自动寻路组件不在AI身上");
|
||||
}
|
||||
animator = GetComponent<Animator>();
|
||||
if(animator == null)
|
||||
{
|
||||
Debug.LogError("动画组件不在AI身上");
|
||||
}
|
||||
|
||||
//服务器上查找玩家
|
||||
FindPlayer();
|
||||
}
|
||||
|
||||
public override void OnStartClient()
|
||||
{
|
||||
base.OnStartClient();
|
||||
Debug.Log("AI客户端初始化");
|
||||
|
||||
//客户端也需要获取组件引用
|
||||
audioSource = GetComponent<AudioSource>();
|
||||
navAgent = GetComponent<NavMeshAgent>();
|
||||
animator = GetComponent<Animator>();
|
||||
}
|
||||
|
||||
//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()
|
||||
//{
|
||||
// //只在服务器上执行AI逻辑
|
||||
// if (!isServer) return;
|
||||
|
||||
// FindPlayer();
|
||||
//}
|
||||
|
||||
|
||||
[Server]
|
||||
//动态查找Player
|
||||
private void FindPlayer()
|
||||
{
|
||||
Debug.Log("开始查找玩家");
|
||||
|
||||
//通过GameManager获取Player
|
||||
if (GameManager.Ins != null && GameManager.Ins.players.Count > 0)
|
||||
{
|
||||
playerTransform = GameManager.Ins.players[0];
|
||||
Debug.Log("在GameManager中找到Player" + playerTransform.name);
|
||||
return;
|
||||
}
|
||||
|
||||
//通过标签查找Player
|
||||
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
|
||||
if (playerObj != null)
|
||||
{
|
||||
playerTransform = playerObj.transform;
|
||||
Debug.Log("找到Player标签");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogError("Player没有找到,请重试");
|
||||
StartCoroutine(RetryFindPlayer());
|
||||
}
|
||||
|
||||
[Server]
|
||||
private IEnumerator RetryFindPlayer()
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
FindPlayer();
|
||||
}
|
||||
|
||||
[Server]
|
||||
public void StartIntroduction()
|
||||
{
|
||||
if (isIntroductionStarted || !isServer) return;
|
||||
|
||||
Debug.Log("开始AI介绍");
|
||||
|
||||
//确保我们有Player引用
|
||||
if(playerTransform == null)
|
||||
{
|
||||
FindPlayer();
|
||||
if (playerTransform == null)
|
||||
{
|
||||
Debug.LogError("不能开始介绍,玩家参考是空的");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
isIntroductionStarted = true;
|
||||
Debug.Log("AI介绍开始");
|
||||
|
||||
|
||||
//停止任何现有的协程
|
||||
if (introductionCoroutine != null)
|
||||
{
|
||||
StopCoroutine(introductionCoroutine);
|
||||
}
|
||||
|
||||
//启动开场白协程
|
||||
introductionCoroutine = StartCoroutine(IntroductionRoutine());
|
||||
}
|
||||
|
||||
[Server]
|
||||
private IEnumerator IntroductionRoutine()
|
||||
{
|
||||
Debug.Log("开始介绍开场白");
|
||||
|
||||
//面向玩家
|
||||
transform.LookAt(playerTransform);
|
||||
RpcLookAtPlayer(playerTransform.position);
|
||||
|
||||
//播放开场白音频
|
||||
if (introAudio != null)
|
||||
{
|
||||
Debug.Log("玩家音频播放:" + introAudio.name);
|
||||
//在服务器和所有客户端上播放音频
|
||||
RpcPlayAudio();
|
||||
|
||||
//等待音频播放完毕
|
||||
yield return new WaitForSeconds(introAudio.length);
|
||||
Debug.Log("介绍音频完成");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("AI身上没有介绍音频");
|
||||
yield return new WaitForSeconds(3f);
|
||||
}
|
||||
|
||||
//开始跟随玩家
|
||||
StartFollowing();
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
private void RpcLookAtPlayer(Vector3 playerPosition)
|
||||
{
|
||||
//客户端也面向玩家
|
||||
if(!isServer)//避免服务器执行两次
|
||||
{
|
||||
transform.LookAt(playerPosition);
|
||||
}
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
private void RpcPlayAudio()
|
||||
{
|
||||
if (audioSource != null && introAudio != null)
|
||||
{
|
||||
Debug.Log("客户端播放AI音频");
|
||||
audioSource.clip = introAudio;
|
||||
audioSource.Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("无法播放AI音频:AudioSource或AudioClip为空");
|
||||
}
|
||||
}
|
||||
|
||||
[Server]
|
||||
private void StartFollowing()
|
||||
{
|
||||
isFollowing = true;
|
||||
Debug.Log("开始跟随玩家");
|
||||
|
||||
//停止任何现有的跟随协程
|
||||
if (followCoroutine != null)
|
||||
{
|
||||
StopCoroutine(followCoroutine);
|
||||
}
|
||||
|
||||
//开始新的跟随协程
|
||||
followCoroutine = StartCoroutine(FollowPlayer());
|
||||
}
|
||||
|
||||
[Server]
|
||||
private IEnumerator FollowPlayer()
|
||||
{
|
||||
//添加一个标志,确保只触发一次介绍完成事件
|
||||
bool hasTriggeredCompletion = false;
|
||||
|
||||
while (isFollowing)
|
||||
{
|
||||
//确保Player引用有效
|
||||
if (playerTransform == null)
|
||||
{
|
||||
FindPlayer();
|
||||
if (playerTransform == null)
|
||||
{
|
||||
Debug.LogError("玩家参考丢失,停止跟随");
|
||||
yield return new WaitForSeconds(1f);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//计算玩家左侧的位置
|
||||
Vector3 leftOffset = -playerTransform.right * followDistance;
|
||||
Vector3 targetPosition = playerTransform.position + leftOffset;
|
||||
|
||||
//设置导航目标
|
||||
if (navAgent != null && navAgent.isActiveAndEnabled)
|
||||
{
|
||||
navAgent.SetDestination(targetPosition);
|
||||
RpcSetDestination(targetPosition);
|
||||
|
||||
//触发行走动画
|
||||
if (animator != null)
|
||||
{
|
||||
bool isMoving = navAgent.remainingDistance > navAgent.stoppingDistance;
|
||||
animator.SetBool("Walk", isMoving);
|
||||
RpcSetAnimatonBool("Walk", isMoving);
|
||||
}
|
||||
|
||||
//检查是否到达目标位置
|
||||
if (!hasTriggeredCompletion && !navAgent.pathPending && navAgent.remainingDistance <= navAgent.stoppingDistance)
|
||||
{
|
||||
hasTriggeredCompletion = true;
|
||||
hasIntroductionCompleted = true;
|
||||
|
||||
//触发介绍完成事件
|
||||
OnIntroductionComplete?.Invoke();
|
||||
Debug.Log("AI已到达玩家身侧,介绍完成");
|
||||
|
||||
//停止行走动画
|
||||
if (animator != null)
|
||||
{
|
||||
animator.SetBool("Walk", false);
|
||||
RpcSetAnimatonBool("Walk", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//等待一段时间再更新位置
|
||||
yield return new WaitForSeconds(followUpdateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
private void RpcSetDestination(Vector3 destination)
|
||||
{
|
||||
//客户端也设置导航目标(如果需要)
|
||||
if (!isServer && navAgent != null)
|
||||
{
|
||||
navAgent.SetDestination(destination);
|
||||
}
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
private void RpcSetAnimatonBool(string paramName,bool value)
|
||||
{
|
||||
//客户端也设置动画参数
|
||||
if (!isServer && animator != null)
|
||||
{
|
||||
animator.SetBool(paramName, value);
|
||||
}
|
||||
}
|
||||
|
||||
//停止跟随
|
||||
public void StopFollowing()
|
||||
{
|
||||
isFollowing = false;
|
||||
if (followCoroutine != null)
|
||||
{
|
||||
StopCoroutine(followCoroutine);
|
||||
followCoroutine = null;
|
||||
}
|
||||
|
||||
if (introductionCoroutine != null)
|
||||
{
|
||||
StopCoroutine(introductionCoroutine);
|
||||
introductionCoroutine = null;
|
||||
}
|
||||
|
||||
//停止移动
|
||||
if (navAgent != null && navAgent.isActiveAndEnabled)
|
||||
{
|
||||
navAgent.isStopped = true;
|
||||
}
|
||||
|
||||
//停止行走动画
|
||||
if (animator != null)
|
||||
{
|
||||
animator.SetBool("Walk", false);
|
||||
RpcSetAnimatonBool("Walk", false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
StopFollowing();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e9c9ba060174ae4996e2baf56ce4766
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1029,7 +1029,7 @@ public class GameManager : NetworkBehaviour
|
||||
}
|
||||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Jishou_Qianzhou_Tianhong)
|
||||
{
|
||||
EnergyPump.transform.position = new Vector3(0f, 0, 2f);
|
||||
EnergyPump.transform.position = new Vector3(4.82f, 0, -0.63f);
|
||||
}
|
||||
if (GameInit.Ins.gamePlace == GamePlace.Shandong_Jinan_Huaiyin_ShengfutongShangmao)
|
||||
{
|
||||
@@ -1037,7 +1037,7 @@ public class GameManager : NetworkBehaviour
|
||||
}
|
||||
if (GameInit.Ins.gamePlace == GamePlace.Shandong_Jinan_Huaiyin_ShengfutongShangmao_wai)
|
||||
{
|
||||
EnergyPump.transform.position = new Vector3(0.09f, 0, 1.09f);
|
||||
EnergyPump.transform.position = new Vector3(-0.84f, 0, 1.2f);
|
||||
}
|
||||
if (GameInit.Ins.gamePlace == GamePlace.Henan_Xinzheng_Shuanghudadao_Longhujinyicheng)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user