730 lines
21 KiB
C#
730 lines
21 KiB
C#
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
|
||
using Common;
|
||
using DarkTonic.MasterAudio;
|
||
using DragonLi.Core;
|
||
using LitJson;
|
||
using NaughtyAttributes;
|
||
using Pathfinding;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using UnityEngine;
|
||
using UnityEngine.PlayerLoop;
|
||
using UnityEngine.UIElements;
|
||
using XPlugin.Data.JsonLiteDB;
|
||
using static XPlugin.Data.JsonLiteDB.JsonLiteDB;
|
||
|
||
|
||
/// <summary>
|
||
/// 游戏状态
|
||
/// </summary>
|
||
public enum GameState
|
||
{
|
||
None = 0,
|
||
Playing = 1,
|
||
/// <summary>
|
||
/// 胜利
|
||
/// </summary>
|
||
Victory = 2,
|
||
/// <summary>
|
||
/// 失败
|
||
/// </summary>
|
||
Failur = 3,
|
||
Settle
|
||
}
|
||
|
||
|
||
public class GameManager : MonoBehaviour
|
||
{
|
||
public static GameManager Ins { get; private set; }
|
||
|
||
public TaskManager taskManager;
|
||
|
||
public GameState gameState;
|
||
|
||
public float vistEnd = 60 * 10;
|
||
public float curGameTime = 0;
|
||
|
||
//预制体
|
||
public GameObject playerPre;
|
||
public GameObject enemyPre;
|
||
public GameObject gameStartDoor;
|
||
public GameObject mirrorPre;
|
||
public GameObject witchPre;
|
||
|
||
public RightHand playerRightHand;
|
||
public Enemy enemy;
|
||
|
||
public bool isStartGame = false;
|
||
|
||
//添加
|
||
[Header("AI角色")]
|
||
public GameObject aiCharacterPre;//AI角色预制体
|
||
private GameObject aiCharacter;//AI角色实例
|
||
|
||
// 新增:指引系统
|
||
[Header("指引系统")]
|
||
public GameObject GuideArrowPre; // 指引箭头预制体
|
||
private GameObject guideArrowInstance; // 指引箭头实例
|
||
private GuideArrowPath guideArrowComponent; // 指引箭头组件
|
||
private bool isGuideArrowActive = false;
|
||
private Vector3 lastPlayerPosition; // 记录玩家上一次的位置
|
||
private float updatePathThreshold = 0.5f; // 更新路径的阈值(玩家移动超过这个距离才更新路径)
|
||
private float updatePathCooldown = 0.3f; // 更新路径的冷却时间
|
||
private float lastPathUpdateTime = 0f;
|
||
private Vector3[] lastPathPoints; // 上一次的路径点
|
||
private bool isPathSmoothed = false;
|
||
private List<Vector3> smoothedPath = new List<Vector3>();
|
||
|
||
void Awake()
|
||
{
|
||
Ins = this;
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
isStartGame = false;
|
||
// 新增:初始化指引系统
|
||
}
|
||
|
||
public void GameStart()
|
||
{
|
||
//CreateAICharacter();
|
||
//CleanupGuideArrow();
|
||
//CreateEnemy(GameLocal.Ins.enemyPos.position,GameLocal.Ins.enemyPos.eulerAngles);
|
||
}
|
||
|
||
//修改处:添加创建AI角色的方法
|
||
private void CreateAICharacter()
|
||
{
|
||
//检查是否已经存在AI角色
|
||
if (aiCharacter != null)
|
||
{
|
||
Debug.Log("AI角色已经存在,不再创建新的");
|
||
return;
|
||
}
|
||
|
||
if (aiCharacterPre != null)
|
||
{
|
||
Debug.Log("创建AI角色");
|
||
|
||
//在玩家前方创建AI角色
|
||
Vector3 spawnPosition = playerPre.transform.position + playerPre.transform.forward * 3f;
|
||
aiCharacter = Instantiate(aiCharacterPre, GameLocal.Ins.startDoorPos.position, Quaternion.identity);
|
||
|
||
//获取AIController并启动开场白
|
||
AIController aiController = aiCharacter.GetComponent<AIController>();
|
||
if (aiController != null)
|
||
{
|
||
//注册AI介绍完成回调
|
||
aiController.OnIntroductionComplete += StartGameAfterIntroduction;
|
||
|
||
//添加延迟,确保所有组件已经完成初始化
|
||
StartCoroutine(DelayedStartIntroduction(aiController));
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("AI预制体中的AIController组件丢失");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("AI预制体没有在GameManager分配!");
|
||
}
|
||
}
|
||
|
||
public void StartGameAfterIntroduction()
|
||
{
|
||
isStartGame = true;
|
||
|
||
Debug.Log("AI介绍完成,开始游戏正常流程");
|
||
|
||
HUDPanel.Show();
|
||
taskManager.bg.SetActive(true);
|
||
CreateEnemy(GameLocal.Ins.enemyPos.position, new Vector3(0, 180, 0));
|
||
}
|
||
|
||
private IEnumerator DelayedStartIntroduction(AIController aiController)
|
||
{
|
||
yield return new WaitForSeconds(0.1f); // 短暂延迟
|
||
aiController.StartIntroduction();
|
||
}
|
||
|
||
public void LoginGame()
|
||
{
|
||
CreatePlayer();
|
||
//PlaySound2DRPC("1.25");
|
||
PlayBGM(0);
|
||
CreateGameStartDoor(GameLocal.Ins.startDoorPos.position);
|
||
InitializeGuideArrow();
|
||
}
|
||
|
||
public void PlayBGM(int id)
|
||
{
|
||
foreach (var item in GameLocal.Ins.BGM)
|
||
{
|
||
item.SetActive(false);
|
||
}
|
||
GameLocal.Ins.BGM[id].SetActive(true);
|
||
}
|
||
|
||
|
||
public void GameOver(GameState state)
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新配置表
|
||
/// </summary>
|
||
public void UpdateConf()
|
||
{
|
||
// string text = Resources.Load<TextAsset>("Data").text;
|
||
// if (text != null)
|
||
// {
|
||
// ParseGameJson(text);
|
||
// }
|
||
}
|
||
|
||
public void ParseGameJson(string text)
|
||
{
|
||
// DB = new JsonLiteDB();
|
||
// DB.Load(text);
|
||
//
|
||
// TableReader infoReader = DB["EnemysInfo"].GetReader();
|
||
// while (infoReader.Read())
|
||
// {
|
||
// EnemyInfo info = new EnemyInfo(infoReader);
|
||
//
|
||
// }
|
||
|
||
Debug.Log("游戏数值更新 -> complete");
|
||
}
|
||
|
||
public void StopBgm()
|
||
{
|
||
|
||
}
|
||
|
||
public void PlaySound2DRPC(string sound)
|
||
{
|
||
MasterAudio.PlaySound(sound);
|
||
}
|
||
|
||
public void PlaySound3DRPC(string sound,Transform soundTran,bool isStop=false)
|
||
{
|
||
if(isStop)
|
||
MasterAudio.StopAllSoundsOfTransform(soundTran);
|
||
MasterAudio.PlaySound3DAtTransform(sound, soundTran);
|
||
}
|
||
|
||
public void CreateGameStartDoor(Vector3 pos)
|
||
{
|
||
var door= Instantiate(gameStartDoor, pos, Quaternion.identity);
|
||
// 延迟开始指引,确保玩家和门都已初始化
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
{
|
||
StartGuide();
|
||
}, 0.5f);
|
||
if (GameLocal.Ins.place == Place.Jiangsu_Xvzhou_Suning_Guangchang
|
||
||GameLocal.Ins.place == Place.Hunan_Changde_Lixian_WandaGuangchang
|
||
||GameLocal.Ins.place == Place.Hunan_Zhuzhou_Wanda_Shennongcheng_Chaowanshe
|
||
|
||
)
|
||
{
|
||
door.transform.eulerAngles = new Vector3(0, 90, 0);
|
||
}
|
||
if ( GameLocal.Ins.place == Place.Hunan_Zhuzhou_Wanda_Shennongcheng_Chaowanshe
|
||
|| GameLocal.Ins.place == Place.Hebei_Hengshui_Taocheng_WandaGuangchang
|
||
|| GameLocal.Ins.place == Place.Ningxia_Yinchuan_Jinfeng_XinhualianGuangchang
|
||
)
|
||
{
|
||
door.transform.eulerAngles = new Vector3(0, -90, 0);
|
||
}
|
||
else
|
||
{
|
||
door.transform.eulerAngles = new Vector3(0, 180, 0);
|
||
}
|
||
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
if (!isStartGame)
|
||
{
|
||
if (door.gameObject==null)
|
||
return;
|
||
door.gameObject.GetComponent<Collider>().enabled = false;
|
||
door.gameObject.SetActive(false);
|
||
Destroy(door.gameObject);
|
||
|
||
if (taskManager.curTaskId != 4)
|
||
{
|
||
GameStart();
|
||
|
||
}
|
||
else
|
||
{
|
||
|
||
StartDance();
|
||
}
|
||
}
|
||
},5);
|
||
}
|
||
|
||
public void CreatePlayer()
|
||
{
|
||
Instantiate(playerPre);
|
||
}
|
||
|
||
public void CreateEnemy(Vector3 pos,Vector3 eulerAngles)
|
||
{
|
||
var curEnemy=Instantiate(enemyPre,pos,Quaternion.identity);
|
||
curEnemy.transform.eulerAngles = eulerAngles;
|
||
curEnemy.GetComponent<Enemy>().Init();
|
||
enemy = curEnemy.GetComponent<Enemy>();
|
||
}
|
||
|
||
public void CreateMirrorPre()
|
||
{
|
||
var curMirror=Instantiate(mirrorPre,GameLocal.Ins.mirrorPos.position,Quaternion.identity);
|
||
curMirror.transform.eulerAngles = GameLocal.Ins.mirrorPos.eulerAngles;
|
||
curMirror.GetComponent<Enemy>().Init();
|
||
//enemy = curEnemy.GetComponent<Enemy>();
|
||
}
|
||
|
||
public void PlayerHit()
|
||
{
|
||
if(enemy.isDie)
|
||
return;
|
||
//玩家UI模糊
|
||
HUDPanel.Ins.ShowEgg();
|
||
Debug.Log("击中玩家");
|
||
PlaySound2DRPC("1.50");
|
||
}
|
||
|
||
public void EnemyHit(Vector3 pos)
|
||
{
|
||
if(enemy.isDie)
|
||
return;
|
||
enemy.Hit();
|
||
PlaySound3DRPC("1.49",enemy.transform,true);
|
||
}
|
||
|
||
public void EnemyTimeHit()
|
||
{
|
||
enemy.isTimeHit = true;
|
||
}
|
||
|
||
public void StartGameEnd()
|
||
{
|
||
//任务结束
|
||
PlaySound2DRPC("1.24");
|
||
playerRightHand.ChangeHand();
|
||
taskManager.OverTask();
|
||
isStartGame = false;
|
||
CreateGameStartDoor(GameLocal.Ins.self.transform.position.ReflectVectorXOZ()+new Vector3(0,0,2));
|
||
}
|
||
|
||
public void StartDance()
|
||
{
|
||
//开启舞会
|
||
Debug.LogError("开启舞会场景");
|
||
PlayBGM(1);
|
||
taskManager.bg.SetActive(false);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
WinPanel.Show();
|
||
},10f);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
Application.Quit();
|
||
}, 90f);
|
||
|
||
}
|
||
|
||
|
||
private void Update()
|
||
{
|
||
//if (Input.GetKeyDown(KeyCode.Q))
|
||
//{
|
||
// CreateEnemy(new Vector3(0, 1, 5), new Vector3(0, 180, 0));
|
||
// enemy.SetState(3);
|
||
// taskManager.curTaskId = 4;
|
||
// taskManager.StartTask();
|
||
//}
|
||
//更新指引箭头位置
|
||
UpdateGuideArrowPosition();
|
||
if (gameState == GameState.Playing)
|
||
{
|
||
curGameTime+=Time.deltaTime;
|
||
}
|
||
}
|
||
|
||
public int GetNowTime()
|
||
{
|
||
return Mathf.RoundToInt(curGameTime);
|
||
}
|
||
|
||
#region 工具
|
||
public string GetLessTimeStr()
|
||
{
|
||
string res = "";
|
||
if (gameState == GameState.Playing)
|
||
{
|
||
res = FormatTime((int)(vistEnd - DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds));
|
||
}
|
||
return res;
|
||
}
|
||
|
||
public int GetLessTimeSeconds()
|
||
{
|
||
return (int)(vistEnd - DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds);
|
||
}
|
||
|
||
// 时分秒
|
||
public string FormatTime(int totalSeconds)
|
||
{
|
||
int hours = totalSeconds / 3600;
|
||
// string hh = hours < 10 ? "0" + hours : hours.ToString();
|
||
int minutes = (totalSeconds - hours * 3600) / 60;
|
||
string mm = minutes < 10f ? "0" + minutes : minutes.ToString();
|
||
int seconds = totalSeconds - hours * 3600 - minutes * 60;
|
||
string ss = seconds < 10 ? "0" + seconds : seconds.ToString();
|
||
return string.Format("{0}:{1}", mm, ss);
|
||
}
|
||
#endregion
|
||
#region 指引系统
|
||
|
||
/// <summary>
|
||
/// 初始化指引箭头
|
||
/// </summary>
|
||
|
||
private void InitializeGuideArrow()
|
||
{
|
||
// 检查预制体是否存在
|
||
if (GuideArrowPre == null)
|
||
{
|
||
Debug.LogError("GuideArrowPre 预制体未分配!");
|
||
return;
|
||
}
|
||
|
||
// 实例化指引箭头预制体
|
||
guideArrowInstance = Instantiate(GuideArrowPre);
|
||
guideArrowInstance.name = "GuideArrow";
|
||
|
||
// 获取指引箭头组件
|
||
guideArrowComponent = guideArrowInstance.GetComponent<GuideArrowPath>();
|
||
if (guideArrowComponent == null)
|
||
{
|
||
Debug.LogError("GuideArrowPre 预制体上没有找到 GuideArrowPath 组件!");
|
||
Destroy(guideArrowInstance);
|
||
guideArrowInstance = null;
|
||
return;
|
||
}
|
||
|
||
// 设置指引箭头的层级和高度
|
||
guideArrowComponent.obstacleMask = LayerMask.GetMask("Default"); // 根据实际障碍物层级设置
|
||
guideArrowComponent.pathHeight = 0.5f; // 设置路径显示高度
|
||
|
||
// 初始隐藏指引
|
||
guideArrowComponent.ClosePath();
|
||
|
||
// 可选:设置父物体,保持场景整洁
|
||
guideArrowInstance.transform.SetParent(this.transform);
|
||
|
||
// 初始化玩家位置
|
||
if (GameLocal.Ins.self != null)
|
||
{
|
||
lastPlayerPosition = GameLocal.Ins.self.transform.position;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新指引箭头位置(实时跟随玩家移动)
|
||
/// </summary>
|
||
|
||
// 修改 UpdateGuideArrowPosition 方法
|
||
private void UpdateGuideArrowPosition()
|
||
{
|
||
if (!isGuideArrowActive || GameLocal.Ins.startDoorPos == null || GameLocal.Ins.self == null)
|
||
return;
|
||
|
||
// 获取玩家当前位置
|
||
Vector3 currentPlayerPosition = GameLocal.Ins.self.transform.position;
|
||
|
||
// 检查冷却时间
|
||
if (Time.time - lastPathUpdateTime < updatePathCooldown)
|
||
return;
|
||
|
||
// 检查玩家是否移动了足够远的距离
|
||
float distanceMoved = Vector3.Distance(currentPlayerPosition, lastPlayerPosition);
|
||
|
||
if (distanceMoved > updatePathThreshold)
|
||
{
|
||
// 获取门的位置
|
||
Vector3 doorPosition = GameLocal.Ins.startDoorPos.transform.position;
|
||
|
||
// 使用曲线检测和路径平滑
|
||
UpdatePathWithCurveDetection(currentPlayerPosition, doorPosition);
|
||
|
||
// 更新记录的位置和时间
|
||
lastPlayerPosition = currentPlayerPosition;
|
||
lastPathUpdateTime = Time.time;
|
||
}
|
||
}
|
||
|
||
// 新增:使用曲线检测和路径平滑的方法
|
||
private void UpdatePathWithCurveDetection(Vector3 start, Vector3 end)
|
||
{
|
||
if (guideArrowComponent == null)
|
||
return;
|
||
|
||
// 1. 检测是否为直接可见路径
|
||
if (IsDirectPathClear(start, end))
|
||
{
|
||
// 直接路径,使用简单的贝塞尔曲线
|
||
smoothedPath = GenerateBezierCurve(start, end, 0.2f);
|
||
guideArrowComponent.SetPath(smoothedPath); // 这里使用 List<Vector3> 参数
|
||
isPathSmoothed = true;
|
||
return;
|
||
}
|
||
|
||
// 2. 间接路径,使用优化的绕路算法
|
||
List<Vector3> newPath = CalculateObstacleAvoidancePath(start, end);
|
||
|
||
if (newPath != null && newPath.Count > 1)
|
||
{
|
||
// 应用路径平滑
|
||
smoothedPath = SmoothPath(newPath);
|
||
guideArrowComponent.SetPath(smoothedPath); // 这里使用 List<Vector3> 参数
|
||
isPathSmoothed = true;
|
||
lastPathPoints = smoothedPath.ToArray();
|
||
}
|
||
}
|
||
|
||
// 新增:检查直接路径是否畅通
|
||
private bool IsDirectPathClear(Vector3 start, Vector3 end)
|
||
{
|
||
Vector3 direction = (end - start).normalized;
|
||
float distance = Vector3.Distance(start, end);
|
||
|
||
// 使用射线检测,同时检查多个点
|
||
int checkPoints = Mathf.CeilToInt(distance / 0.5f);
|
||
for (int i = 0; i <= checkPoints; i++)
|
||
{
|
||
float t = (float)i / checkPoints;
|
||
Vector3 checkPoint = Vector3.Lerp(start, end, t);
|
||
|
||
// 检查周围小范围的碰撞
|
||
if (Physics.CheckSphere(checkPoint, 0.3f, guideArrowComponent.obstacleMask))
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// 新增:生成贝塞尔曲线路径
|
||
private List<Vector3> GenerateBezierCurve(Vector3 start, Vector3 end, float curveHeight)
|
||
{
|
||
List<Vector3> curvePoints = new List<Vector3>();
|
||
int segments = 20; // 曲线分段数
|
||
|
||
// 计算控制点(在中间稍微抬起形成曲线)
|
||
Vector3 controlPoint = (start + end) * 0.5f + Vector3.up * curveHeight;
|
||
|
||
for (int i = 0; i <= segments; i++)
|
||
{
|
||
float t = (float)i / segments;
|
||
|
||
// 二次贝塞尔曲线公式
|
||
Vector3 point = (1 - t) * (1 - t) * start +
|
||
2 * (1 - t) * t * controlPoint +
|
||
t * t * end;
|
||
|
||
curvePoints.Add(point);
|
||
}
|
||
|
||
return curvePoints;
|
||
}
|
||
|
||
// 新增:优化后的绕障碍物路径计算
|
||
private List<Vector3> CalculateObstacleAvoidancePath(Vector3 start, Vector3 end)
|
||
{
|
||
List<Vector3> path = new List<Vector3>();
|
||
path.Add(start);
|
||
|
||
// 尝试寻找最佳绕行点
|
||
Vector3 bypassPoint = FindOptimalBypassPoint(start, end);
|
||
|
||
if (bypassPoint != start)
|
||
{
|
||
// 如果有绕行点,构建曲线路径
|
||
List<Vector3> curve1 = GenerateBezierCurve(start, bypassPoint, 0.3f);
|
||
List<Vector3> curve2 = GenerateBezierCurve(bypassPoint, end, 0.3f);
|
||
|
||
path.AddRange(curve1.Skip(1));
|
||
path.AddRange(curve2.Skip(1));
|
||
}
|
||
else
|
||
{
|
||
// 没有找到绕行点,使用简单的曲线
|
||
path = GenerateBezierCurve(start, end, 0.2f);
|
||
}
|
||
|
||
return path;
|
||
}
|
||
|
||
// 新增:寻找最优绕行点
|
||
private Vector3 FindOptimalBypassPoint(Vector3 from, Vector3 to)
|
||
{
|
||
Vector3 direction = (to - from).normalized;
|
||
float distance = Vector3.Distance(from, to);
|
||
|
||
// 定义多个探测方向
|
||
Vector3[] probeDirections = new Vector3[]
|
||
{
|
||
Vector3.Cross(direction, Vector3.up).normalized, // 右侧
|
||
-Vector3.Cross(direction, Vector3.up).normalized, // 左侧
|
||
(Vector3.Cross(direction, Vector3.up).normalized + Vector3.up * 0.3f).normalized, // 右上
|
||
(-Vector3.Cross(direction, Vector3.up).normalized + Vector3.up * 0.3f).normalized // 左上
|
||
};
|
||
|
||
float[] probeDistances = new float[] { 2f, 3f, 4f, 5f };
|
||
|
||
Vector3 bestBypassPoint = from;
|
||
float bestScore = float.MaxValue;
|
||
|
||
foreach (Vector3 probeDir in probeDirections)
|
||
{
|
||
foreach (float probeDist in probeDistances)
|
||
{
|
||
Vector3 probePoint = from + probeDir * probeDist;
|
||
|
||
// 检查探测点是否可行
|
||
if (!Physics.CheckSphere(probePoint, 0.5f, guideArrowComponent.obstacleMask))
|
||
{
|
||
// 计算路径分数(距离 + 转向角度)
|
||
float pathLength = Vector3.Distance(from, probePoint) +
|
||
Vector3.Distance(probePoint, to);
|
||
float angleCost = Vector3.Angle(probePoint - from, to - probePoint) * 0.1f;
|
||
float score = pathLength + angleCost;
|
||
|
||
if (score < bestScore)
|
||
{
|
||
bestScore = score;
|
||
bestBypassPoint = probePoint;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return bestBypassPoint;
|
||
}
|
||
|
||
// 新增:路径平滑算法
|
||
private List<Vector3> SmoothPath(List<Vector3> rawPath)
|
||
{
|
||
if (rawPath.Count < 3)
|
||
return rawPath;
|
||
|
||
List<Vector3> smoothed = new List<Vector3>();
|
||
smoothed.Add(rawPath[0]);
|
||
|
||
// 使用简单的平均平滑
|
||
for (int i = 1; i < rawPath.Count - 1; i++)
|
||
{
|
||
Vector3 smoothedPoint = (rawPath[i - 1] + rawPath[i] + rawPath[i + 1]) / 3f;
|
||
smoothed.Add(smoothedPoint);
|
||
}
|
||
|
||
smoothed.Add(rawPath[rawPath.Count - 1]);
|
||
|
||
return smoothed;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 显示指引箭头
|
||
/// </summary>
|
||
|
||
public void ShowGuideArrow()
|
||
{
|
||
if (guideArrowComponent != null && GameLocal.Ins.startDoorPos != null && GameLocal.Ins.self != null)
|
||
{
|
||
guideArrowComponent.ShowPath();
|
||
isGuideArrowActive = true;
|
||
|
||
// 初始化路径
|
||
Vector3 playerPosition = GameLocal.Ins.self.transform.position;
|
||
Vector3 doorPosition = GameLocal.Ins.startDoorPos.transform.position;
|
||
UpdatePathWithCurveDetection(playerPosition, doorPosition);
|
||
|
||
// 记录初始位置
|
||
lastPlayerPosition = playerPosition;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 隐藏指引箭头
|
||
/// </summary>
|
||
|
||
public void HideGuideArrow()
|
||
{
|
||
if (guideArrowComponent != null)
|
||
{
|
||
guideArrowComponent.ClosePath();
|
||
isGuideArrowActive = false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始指引(在创建门后调用)
|
||
/// </summary>
|
||
|
||
public void StartGuide()
|
||
{
|
||
if (GameLocal.Ins.startDoorPos != null && GameLocal.Ins.self != null)
|
||
{
|
||
ShowGuideArrow();
|
||
|
||
// 初始化路径
|
||
Vector3 playerPosition = GameLocal.Ins.self.transform.position;
|
||
Vector3 doorPosition = GameLocal.Ins.startDoorPos.transform.position;
|
||
|
||
// 使用新的路径计算方法
|
||
UpdatePathWithCurveDetection(playerPosition, doorPosition);
|
||
|
||
// 记录初始位置
|
||
lastPlayerPosition = playerPosition;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 停止指引(在游戏开始或删除门时调用)
|
||
/// </summary>
|
||
|
||
public void StopGuide()
|
||
{
|
||
HideGuideArrow();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清理指引箭头实例
|
||
/// </summary>
|
||
|
||
public void CleanupGuideArrow()
|
||
{
|
||
if (guideArrowInstance != null)
|
||
{
|
||
Destroy(guideArrowInstance);
|
||
guideArrowInstance = null;
|
||
guideArrowComponent = null;
|
||
isGuideArrowActive = false;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|