修改湖南吉首、山东济南室外场景

This commit is contained in:
ZYT
2025-09-15 17:51:04 +08:00
parent 90eadeb8ce
commit dc99f8b13e
24 changed files with 1177 additions and 629 deletions

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 978ee1b84ebbb9148891a91ea5549fe3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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();
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7e9c9ba060174ae4996e2baf56ce4766
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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)
{