1494 lines
50 KiB
C#
1494 lines
50 KiB
C#
using BestHTTP;
|
||
using DragonLi.Core;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Unity.Mathematics;
|
||
using Unity.XR.PXR;
|
||
using UnityEngine;
|
||
using XPlugin.Data.JsonLiteDB;
|
||
using static XPlugin.Data.JsonLiteDB.JsonLiteDB;
|
||
using Random = UnityEngine.Random;
|
||
|
||
public enum GameKey
|
||
{
|
||
DinosaurPark2=0,//重返侏罗纪
|
||
SpongeBob=1,//深海冒险
|
||
XMen=2,//银河守护者
|
||
KOF=3,//幻影交锋
|
||
Valheim=4,//小小幻宠
|
||
FutureMen=5,//未来战警
|
||
AliceBall=6,//爱丽丝的舞会
|
||
Zombie=7,//僵尸来了
|
||
DefendNJ=8,//保卫金陵
|
||
Loong=9, //巨龙猎人
|
||
MRCS=10,//火力对决
|
||
SXDMystery=11,//三星堆之谜
|
||
}
|
||
/// <summary>
|
||
/// 游戏场地
|
||
/// </summary>
|
||
public enum GamePlace
|
||
{
|
||
// Test = -1,
|
||
Company1Floor = 0,
|
||
Company1FloorShiwai = -999,
|
||
LiaoningAnShan = 1,
|
||
Liaoning_AnShan_Lishan_Dayuecheng=-1,
|
||
HangZhouLongHuTianJie = 2,
|
||
Nanjing_Yuhua_Wanxiang = 3,
|
||
Nanjing_Xianlin_WanDaMao = 4,
|
||
Yangzhou_Hanjiang_Tansuozhongxin = 5,
|
||
Yangzhou_Hanjiang_TansuoZhongxin_wai = -5,
|
||
Zhejiang_Jinhua_KeJiGuan = 6,
|
||
Guangzhou_Panyv_Zhanting = 7,
|
||
Anhui_Wuhu_Guanwei = 8,
|
||
Shandong_Jining_Shangchang = 9,
|
||
Shandong_Jining_Shangchang_nei = -9,
|
||
ShanDong_Langfang_QingzhouTaihuacheng = 10,
|
||
Hubei_Xiangyang_Kejiguan = 11,
|
||
Zhejiang_Shaoxing_Shengzhou_WuyueGuangchang=12,
|
||
Hunan_Jishou_Qianzhou_Tianhong=13,
|
||
Jilin_Tonghua_Liuhe=14,
|
||
Shandong_Jinan_Huaiyin_ShengfutongShangmao = 15,
|
||
Shandong_Jinan_Huaiyin_ShengfutongShangmao_wai = -15,
|
||
Henan_Xinzheng_Shuanghudadao_Longhujinyicheng = 16,
|
||
Nanjing_Qixia_Yaohuamen_Jindiguangchang = 17,
|
||
Nanjing_Qixia_Yaohuamen_Jindiguangchang_nei = -17,
|
||
Anshan_Suzhou_Yueshan_Guchengshangyejie = 18,
|
||
Anhui_Suzhou_Yueshan_Guchengshangyejie_2=-18,
|
||
Gansu_Longnan_Shicheng_Dongsheng = 19,
|
||
Shandong_Heze_Yuncheng_Gefuli = 20,
|
||
Wulanhaote_Ouya_Shangchang = 21,
|
||
Wulanhaote_Wanda_Shangchang = -21,
|
||
Yunnan_Mile_Jinchen_Shidaiguangchang = 22,
|
||
Xinjiang_Yili_Yining_Wanrong = 23,
|
||
Hunan_Hengyang_Zhuhui_Dongzhoudao = 24,
|
||
Hunan_Hengyang_Zhuhui_Dongzhoudao_nei = -24,
|
||
Yunnan_Lincang_Linxiang_Hengji = 25,
|
||
Yunnan_Lincang_Linxiang_Hengji_Dixia = -25,
|
||
Guangxi_Guilin_Gongcheng_Shijixincheng = 26,
|
||
Guangdong_Shenzhen_Guangming_Wanda = 27,
|
||
Gansu_Jinchang_Jinchuan_Shijiguangchang = 28,
|
||
Gansu_Jinchang_Jinchuan_Shijiguangchang_Shiwai=-28,
|
||
Jiangsu_Xvzhou_Fengxian_Wuyueguangchang =29,
|
||
Hebei_Tangshan_Qianan_Tianyuangu = 30,
|
||
Guangdong_Guangzhou_Yanghaiyan = 31,
|
||
Guangdong_Guangzhou_Yanghaiyan_Lihu=-31,
|
||
Zhejiang_Hangzhou_Linping_Yintaicheng = 32,
|
||
Zhejiang_Hangzhou_Linping_Yintaicheng_Shinei= -32,
|
||
Henan_Xinxiang_Wandaguangchang =33,
|
||
Henan_Xinxiang_Wandaguangchang_Shinei=-33,
|
||
Yangzhou_Hanjiang_TansuoZhongxin_Waidai =34,
|
||
Nanjing_Pukou_Longhutianjie=35,
|
||
Jiangsu_Xvzhou_Guolou_Oulebao=36,
|
||
Jiangsu_Xvzhou_Guolou_Oulebao_2=-36,
|
||
Jiangsu_Xvzhou_Suning_Guangchang =37,
|
||
Jiangsu_Xvzhou_Suning_Guangchang_1=-37,
|
||
Shanxi_Baoji_Meixian_TianlongShangcheng = 38,
|
||
Hunan_Changde_Lixian_WandaGuangchang=39,
|
||
Jilin_Changchun_Beihu_WyueGuangchang=41,
|
||
Chongqing_Yuzhong_Hongyadong_Xiakexing=42,
|
||
Chongqing_Yuzhong_Hongyadong_Xiakexing_shiwan=-42,
|
||
Chengdu_Shuangliu_ShengfeiXuexiao =43,
|
||
Hebei_Hengshui_Xinji_WandaGuangchang = 44,
|
||
Hebei_Hengshui_Taocheng_WandaGuangchang=-44,
|
||
Ningxia_Yinchuan_Jinfeng_XinhualianGuangchang = 45,
|
||
Hunan_Zhuzhou_Wanda_Shennongcheng_Chaowanshe=46,
|
||
Anhui_Suzhou_Yueshan_Guchengshangyejie_Shinei=47,
|
||
Zhejiang_Wenzhou_Cangnan_Yintaicheng = 48,
|
||
Shandong_Jining_Shangchang_3=49,
|
||
Anhui_Manshan_XingyueGuangchang = 50,
|
||
Shandong_Weifang_Linqu_WandaGuangchang = 51,
|
||
Guangdong_Foushan_Haiyangguang = 52,
|
||
Jilin_Changchun_Chaoyang_OuyaMaichang=53,
|
||
Shandong_Weifang_Linqu_WandaGuangchang_Shinei=54,
|
||
Liaoning_Panjin_Shuangtaizi_Shuangtaicheng = 55,
|
||
Liaoning_Dalian_Pulandian_WandaGuangchang = 56,
|
||
Jiangxi_Ganzhou_Longnan_WandaGuangchang = 57,
|
||
Jiangxi_Ganzhou_Longnan_WandaGuangchang_Shinei=58,
|
||
Jiangxi_Ganzhou_Zhanggong_GanzhouShucheng=59,
|
||
Henan_Shangqiu_Juyang_WuyueGuangchang = 60,
|
||
Guangdong_Meizhou_Meixian_TianhongShangchang = 61,
|
||
Beijing_Tongzhou_Luyijie_XiangrikuiGuangchang = 62,
|
||
Ningxia_Yinchuang_Shizuishan_WandaGuangchang = 63,
|
||
Jilin_Jilin_Chuangying_Zhongdongxinshenghuo = 64,
|
||
}
|
||
|
||
public class GameManager : MonoBehaviour
|
||
{
|
||
public static GameManager Ins { get; private set; }
|
||
/// <summary>
|
||
/// 是否时间到了
|
||
/// </summary>
|
||
public bool isTimeEnd = true;
|
||
// json数据库
|
||
private JsonLiteDB DB;
|
||
|
||
// Enemy子弹数据
|
||
public Dictionary<int, BulletData> EnemyBulletDataDic = new Dictionary<int, BulletData>();
|
||
|
||
// Player子弹数据
|
||
public Dictionary<int, BulletData> PlayerBulletDataDic = new Dictionary<int, BulletData>();
|
||
|
||
public Dictionary<int, PropData> PropDataDic = new Dictionary<int, PropData>();
|
||
|
||
public Dictionary<int, BossPosData> BossPosDataDic = new Dictionary<int, BossPosData>();
|
||
|
||
|
||
public List<Enemy> curEnemyList = new List<Enemy>();
|
||
public Dictionary<int, EnemyData> EnemyDataDic = new Dictionary<int, EnemyData>();
|
||
|
||
[Header("道具")]
|
||
public GameObject EnergyPumpPre;
|
||
public GameObject gameStartPointPre;
|
||
public GameObject enemyDoorPre;
|
||
public GameObject point ;
|
||
[Header("敌人")]
|
||
public GameObject[] enemyPre;
|
||
|
||
public GameObject callEffectPre;//召唤特效
|
||
|
||
[Header("玩家")]
|
||
public GameObject playerPre;
|
||
public GameObject player;
|
||
|
||
public int gameTime=60*10;
|
||
public float curGameTime;
|
||
/// <summary>
|
||
/// 血包
|
||
/// </summary>
|
||
public GameObject BloodBagPre;
|
||
/// <summary>
|
||
/// 武器道具
|
||
/// </summary>
|
||
public GameObject weaponItemPre;
|
||
/// <summary>
|
||
/// 攻击BUFF
|
||
/// </summary>
|
||
public GameObject AtkBuffPre;
|
||
|
||
public GameObject deffBuffPre;
|
||
|
||
public bool GameStart = false;
|
||
|
||
public bool isGameEnd = false;
|
||
|
||
public int EnergyPumpTag = 0;
|
||
|
||
public float EnergyPumpFillAmount = 0;
|
||
|
||
public float curTime;
|
||
|
||
public float buffAtk = 0f;
|
||
public float buffDef = 0f;
|
||
|
||
public LoginInfo loginInfo = new LoginInfo();
|
||
|
||
public Enemy curBoss;
|
||
|
||
public int curLevel = 0;
|
||
|
||
//添加
|
||
[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>();
|
||
private void Awake()
|
||
{
|
||
|
||
}
|
||
|
||
public void Start()
|
||
{
|
||
Ins = this;
|
||
CreatePlayer();
|
||
LoginPanel.Show();
|
||
// 新增:初始化指引系统
|
||
InitializeGuideArrow();
|
||
if (gameStartPointPre != null)
|
||
{
|
||
point = Instantiate(gameStartPointPre);
|
||
point.SetActive(false); // 初始隐藏
|
||
}
|
||
#if !UNITY_EDITOR
|
||
PXR_Enterprise.InitEnterpriseService();
|
||
PXR_Enterprise.BindEnterpriseService();
|
||
TrueGearEffectManager.Ins.StartRequestTrueGear();
|
||
#endif
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(ShowPlayerUI, 1.5f);
|
||
|
||
}
|
||
void Update()
|
||
{
|
||
// 更新指引箭头位置
|
||
UpdateGuideArrowPosition();
|
||
if (isGamePlay)
|
||
{
|
||
curGameTime+=Time.deltaTime;
|
||
}
|
||
}
|
||
|
||
public int GetNowTime()
|
||
{
|
||
return Mathf.RoundToInt(curGameTime);
|
||
}
|
||
/// <summary>
|
||
/// 登录
|
||
/// </summary>
|
||
public void Request(Action<HTTPRequest, HTTPResponse> cb = null)
|
||
{
|
||
string url = "http://www.pineappletech.cn/startcount";
|
||
HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post, (req, response) =>
|
||
{
|
||
if (response != null)
|
||
{
|
||
Debug.Log("收到数据 ->" + response.DataAsText);
|
||
}
|
||
cb?.Invoke(req, response);
|
||
});
|
||
loginInfo.deviceSn = GetPicoSn();
|
||
loginInfo.startAt = ConvertTimestampToDateTime(GetTimestamp()) + "";
|
||
loginInfo.shop = 0;
|
||
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
|
||
loginInfo.shop = (int)GameInit.Ins.gamePlace;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Company1FloorShiwai)
|
||
loginInfo.shop = 0;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Liaoning_AnShan_Lishan_Dayuecheng)
|
||
loginInfo.shop = 1;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Yangzhou_Hanjiang_TansuoZhongxin_wai)
|
||
loginInfo.shop = 5;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Shandong_Jining_Shangchang_nei)
|
||
loginInfo.shop = 9;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Shandong_Jinan_Huaiyin_ShengfutongShangmao_wai)
|
||
loginInfo.shop = 15;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Nanjing_Qixia_Yaohuamen_Jindiguangchang_nei)
|
||
loginInfo.shop = 17;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Anhui_Suzhou_Yueshan_Guchengshangyejie_2)
|
||
loginInfo.shop = 18;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Wulanhaote_Wanda_Shangchang)
|
||
loginInfo.shop = 21;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Hunan_Hengyang_Zhuhui_Dongzhoudao_nei)
|
||
loginInfo.shop = 24;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Yunnan_Lincang_Linxiang_Hengji_Dixia)
|
||
loginInfo.shop = 25;
|
||
if(GameInit.Ins.gamePlace== GamePlace. Gansu_Jinchang_Jinchuan_Shijiguangchang_Shiwai)
|
||
loginInfo.shop = 28;
|
||
if(GameInit.Ins.gamePlace== GamePlace. Guangdong_Guangzhou_Yanghaiyan_Lihu)
|
||
loginInfo.shop = 31;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Zhejiang_Hangzhou_Linping_Yintaicheng_Shinei)
|
||
loginInfo.shop = 32;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Henan_Xinxiang_Wandaguangchang_Shinei)
|
||
loginInfo.shop = 33;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Jiangsu_Xvzhou_Guolou_Oulebao_2)
|
||
loginInfo.shop = 36;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Jiangsu_Xvzhou_Suning_Guangchang_1)
|
||
loginInfo.shop = 37;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Chongqing_Yuzhong_Hongyadong_Xiakexing_shiwan)
|
||
loginInfo.shop = 42;
|
||
|
||
if(GameInit.Ins.gamePlace== GamePlace.Hebei_Hengshui_Taocheng_WandaGuangchang)
|
||
loginInfo.shop = 44;
|
||
|
||
#endif
|
||
//loginInfo.shop = 0;
|
||
loginInfo.gameId = 5;
|
||
string authJson = JsonUtility.ToJson(loginInfo);
|
||
Debug.Log("发送数据 -> " + authJson);
|
||
request.RawData = System.Text.Encoding.UTF8.GetBytes(authJson);
|
||
request.AddHeader("Content-Type", "application/json");
|
||
request.Send();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新配置表
|
||
/// </summary>
|
||
public void InitData()
|
||
{
|
||
string text = "";
|
||
string text0 = Resources.Load<TextAsset>(string.Format("zh/{0}Data", GameInit.Ins.gamePlace)).text;
|
||
GetReaderJson(text0);
|
||
}
|
||
|
||
public static string ConvertTimestampToDateTime(long timestamp)
|
||
{
|
||
// Unix时间戳是从1970年1月1日00:00:00开始的秒数或毫秒数
|
||
// 这里以秒为单位,如果时间戳是毫秒则除以1000
|
||
DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;
|
||
return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||
}
|
||
|
||
public void GetReaderJson(string text)
|
||
{
|
||
DB = new JsonLiteDB();
|
||
DB.Load(text);
|
||
// 读取Info表数据
|
||
TableReader infoReader = DB["EnemyData"].GetReader();
|
||
EnemyDataDic.Clear();
|
||
while (infoReader.Read())
|
||
{
|
||
EnemyData info = new EnemyData(infoReader);
|
||
EnemyDataDic.Add(info.Id, info);
|
||
}
|
||
|
||
// 敌人子弹数据
|
||
TableReader EnemyBulletReader = DB["EnemyBulletData"].GetReader();
|
||
EnemyBulletDataDic.Clear();
|
||
while (EnemyBulletReader.Read())
|
||
{
|
||
BulletData data = new BulletData(EnemyBulletReader);
|
||
EnemyBulletDataDic.Add(data.ID, data);
|
||
}
|
||
|
||
// 玩家子弹数据
|
||
TableReader PlayerBulletReader = DB["PlayerBulletData"].GetReader();
|
||
PlayerBulletDataDic.Clear();
|
||
while (PlayerBulletReader.Read())
|
||
{
|
||
BulletData data = new BulletData(PlayerBulletReader);
|
||
PlayerBulletDataDic.Add(data.ID, data);
|
||
}
|
||
|
||
// 道具表
|
||
TableReader PropReader = DB["PropData"].GetReader();
|
||
PropDataDic.Clear();
|
||
while (PropReader.Read())
|
||
{
|
||
PropData data = new PropData(PropReader);
|
||
PropDataDic.Add(data.PropId, data);
|
||
}
|
||
|
||
// Boss位置
|
||
TableReader BossPosReader = DB["BossPosData"].GetReader();
|
||
BossPosDataDic.Clear();
|
||
while (BossPosReader.Read())
|
||
{
|
||
BossPosData data = new BossPosData(BossPosReader);
|
||
BossPosDataDic.Add(data.ID, data);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get sn
|
||
/// </summary>
|
||
public string GetPicoSn()
|
||
{
|
||
string res = "UnityEditor";
|
||
|
||
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
|
||
res = PXR_Enterprise.StateGetDeviceInfo(SystemInfoEnum.EQUIPMENT_SN);
|
||
#endif
|
||
return res;
|
||
}
|
||
|
||
public long GetTimestamp()
|
||
{
|
||
return (long)DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
|
||
}
|
||
|
||
public bool isGamePlay;
|
||
|
||
//AI介绍是否完成
|
||
private bool isAIIntroductionComplete = false;
|
||
|
||
// 游戏开始
|
||
public void GamePlay()
|
||
{
|
||
//TODO:添加一个玩家进入游戏AI进行游戏介绍,介绍完后,AI自动回到玩家左侧
|
||
//修改处:创建AI角色
|
||
CreateAICharacter();
|
||
CleanupGuideArrow();
|
||
//isGamePlay = true;
|
||
//CreateBoss();
|
||
//PlayerUIMessage(0);
|
||
//CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
// AudioManager.Ins?.SoundPlay("bgm2", true), 10f);
|
||
//CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
// AudioManager.Ins?.SoundPlay("2.39BGM", true), 30f);
|
||
}
|
||
|
||
//修改处:添加AI介绍完成后的游戏开始方法
|
||
public void StartGameAfterIntroduction()
|
||
{
|
||
isAIIntroductionComplete = true;
|
||
isGamePlay = true;
|
||
|
||
Debug.Log("AI介绍完成,开始游戏正常流程");
|
||
|
||
//创建Boss
|
||
CreateBoss();
|
||
|
||
PlayerUIMessage(0);
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
AudioManager.Ins?.SoundPlay("bgm2", true), 10f);
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
AudioManager.Ins?.SoundPlay("2.39BGM", true), 30f);
|
||
}
|
||
|
||
//修改处:添加创建AI角色的方法
|
||
private void CreateAICharacter()
|
||
{
|
||
//检查是否已经存在AI角色
|
||
if (aiCharacter != null)
|
||
{
|
||
Debug.Log("AI角色已经存在,不再创建新的");
|
||
return;
|
||
}
|
||
|
||
if (aiCharacterPre != null)
|
||
{
|
||
Debug.Log("创建AI角色");
|
||
|
||
//在玩家前方创建AI角色
|
||
Vector3 spawnPosition = player.transform.position + player.transform.forward * 3f;
|
||
aiCharacter = Instantiate(aiCharacterPre, spawnPosition, 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分配!");
|
||
}
|
||
}
|
||
|
||
private IEnumerator DelayedStartIntroduction(AIController aiController)
|
||
{
|
||
yield return new WaitForSeconds(0.1f); // 短暂延迟
|
||
aiController.StartIntroduction();
|
||
}
|
||
|
||
public void ShowPlayerUI()
|
||
{
|
||
OverlayUI.Ins.Cover("UI/PlayerUI", false);
|
||
}
|
||
|
||
public void ShowEndGameUI(bool isWin)
|
||
{
|
||
CurEnemyDie();
|
||
GameEndPanel.Show(isWin);
|
||
}
|
||
public GameObject CreateEnemy(int id, Vector3 pos, Vector3 eulerAngles, bool isBoss)
|
||
{
|
||
GameObject go = Instantiate(enemyPre[id], pos, Quaternion.identity);
|
||
go.transform.localEulerAngles = eulerAngles;
|
||
Enemy enemy = go.GetComponent<Enemy>();
|
||
enemy.Init();
|
||
if (isBoss)
|
||
{
|
||
curBoss = enemy;
|
||
}
|
||
else
|
||
{
|
||
curEnemyList.Add(enemy);
|
||
}
|
||
return go;
|
||
}
|
||
|
||
public GameObject CreateCallEnemyEffect(Vector3 pos)
|
||
{
|
||
GameObject go = Instantiate(callEffectPre, pos, quaternion.identity);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
Destroy(go);
|
||
}, 3f);
|
||
return go;
|
||
}
|
||
|
||
void Destroy()
|
||
{
|
||
|
||
#if !UNITY_EDITOR
|
||
PXR_Enterprise.UnBindEnterpriseService();
|
||
#endif
|
||
}
|
||
|
||
public void CreateEnergyPump(Vector3 pos)
|
||
{
|
||
isGamePlay = false;
|
||
GameObject EnergyPump = Instantiate(EnergyPumpPre);
|
||
//EnergyPump.transform.position = pos;
|
||
EnergyPump.transform.position = new Vector3(2, 0, 2);
|
||
if (GameInit.Ins.gamePlace == GamePlace.Nanjing_Xianlin_WanDaMao)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-1.2f, 0, 1.5f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Nanjing_Yuhua_Wanxiang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-3, 0, 2);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Yangzhou_Hanjiang_Tansuozhongxin)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-1.2f, 0, 0f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Yangzhou_Hanjiang_TansuoZhongxin_wai)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0, 0, 2f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Zhejiang_Jinhua_KeJiGuan)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0, 0, 2f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Jilin_Tonghua_Liuhe)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0, 0, 2f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Guangzhou_Panyv_Zhanting)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0, 0, 2f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Zhejiang_Shaoxing_Shengzhou_WuyueGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.23f, 0, 1.1f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.ShanDong_Langfang_QingzhouTaihuacheng)
|
||
{
|
||
EnergyPump.transform.position = pos;
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Jishou_Qianzhou_Tianhong)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(5f, 0, 1f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Shandong_Jinan_Huaiyin_ShengfutongShangmao)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0.62f, 0, 1f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Shandong_Heze_Yuncheng_Gefuli)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-10.9f, 0, 1.6f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Henan_Xinzheng_Shuanghudadao_Longhujinyicheng)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-2.08f, 0, -0.75f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Wulanhaote_Ouya_Shangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.92f, 0, 9.5f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Wulanhaote_Wanda_Shangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-8.47f, 0, 1.59f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Yunnan_Mile_Jinchen_Shidaiguangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(1.55f, 0, 1.7f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Xinjiang_Yili_Yining_Wanrong)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(1.55f, 0, 1.24f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Hengyang_Zhuhui_Dongzhoudao)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.5f, 0, 3.5f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Hengyang_Zhuhui_Dongzhoudao_nei
|
||
|| GameInit.Ins.gamePlace == GamePlace.Jiangsu_Xvzhou_Fengxian_Wuyueguangchang
|
||
|| GameInit.Ins.gamePlace == GamePlace.Jiangsu_Xvzhou_Guolou_Oulebao_2
|
||
|| GameInit.Ins.gamePlace == GamePlace.Chongqing_Yuzhong_Hongyadong_Xiakexing_shiwan
|
||
)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.39f, 0, 3.83f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Yunnan_Lincang_Linxiang_Hengji)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(1.8f, 0, 2.4f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Yunnan_Lincang_Linxiang_Hengji_Dixia)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0.03f, 0, 6.48f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Guangxi_Guilin_Gongcheng_Shijixincheng)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-5.41f, 0, 10.96f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Guangdong_Shenzhen_Guangming_Wanda)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.62f, 0, 1.07f);
|
||
}
|
||
|
||
if (GameInit.Ins.gamePlace == GamePlace.Liaoning_AnShan_Lishan_Dayuecheng)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-3.23f, 0, 5.47f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hebei_Tangshan_Qianan_Tianyuangu)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(2f, 0, 2f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Zhejiang_Hangzhou_Linping_Yintaicheng)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(1.12f, 0, 1.74f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Guangdong_Guangzhou_Yanghaiyan)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(1.63f, 0, 1.3f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Gansu_Jinchang_Jinchuan_Shijiguangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(3f, 0, 7.32f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Gansu_Jinchang_Jinchuan_Shijiguangchang_Shiwai)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0.18f, 0, 0.59f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Henan_Xinxiang_Wandaguangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(3.29f, 0, -11.05f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Henan_Xinxiang_Wandaguangchang_Shinei)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.09f, 0, 2.775f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Zhejiang_Hangzhou_Linping_Yintaicheng_Shinei)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(2f, 0, 6.23f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Nanjing_Pukou_Longhutianjie)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.37f, 0, 2.94f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Jiangsu_Xvzhou_Guolou_Oulebao || GameInit.Ins.gamePlace == GamePlace.Jiangsu_Xvzhou_Suning_Guangchang_1)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0f, 0, 2f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Changde_Lixian_WandaGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-1.13f, 0, 2.65f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Chongqing_Yuzhong_Hongyadong_Xiakexing)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(2f, 0, 28.22f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Chengdu_Shuangliu_ShengfeiXuexiao)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-1.33f, 0, 17.38f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Anhui_Suzhou_Yueshan_Guchengshangyejie_2)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(2f, 0, 2f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hebei_Hengshui_Xinji_WandaGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0.18f, 0, 5.09f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Ningxia_Yinchuan_Jinfeng_XinhualianGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(10.35f, 0, 4.33f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Zhuzhou_Wanda_Shennongcheng_Chaowanshe)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.09f, 0, 1.37f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Company1FloorShiwai)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.75f, 0, 22.38f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Anhui_Suzhou_Yueshan_Guchengshangyejie_Shinei)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.2f, 0, 3.23f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hebei_Hengshui_Taocheng_WandaGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-5.47f, 0, 7.12f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Shandong_Jining_Shangchang_3)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0.23f, 0, 4.29f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Anhui_Manshan_XingyueGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0.08f, 0, 6.77f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Zhejiang_Wenzhou_Cangnan_Yintaicheng)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.12f, 0, 4.64f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Shandong_Weifang_Linqu_WandaGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-7.19f, 0, -5.37f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Jilin_Changchun_Chaoyang_OuyaMaichang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-1.13f, 0, 2.01f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Shandong_Weifang_Linqu_WandaGuangchang_Shinei)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(2f, 0, 4.79f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Liaoning_Dalian_Pulandian_WandaGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.74f, 0, 4.91f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Henan_Shangqiu_Juyang_WuyueGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.17f, 0, 3.26f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Jiangxi_Ganzhou_Longnan_WandaGuangchang_Shinei)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0.64f, 0, 4.65f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Jiangxi_Ganzhou_Zhanggong_GanzhouShucheng)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-0.41f, 0, 5.47f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Guangdong_Meizhou_Meixian_TianhongShangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-7.77f, 0, 1.11f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Ningxia_Yinchuang_Shizuishan_WandaGuangchang)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(0.91f, 0, 3.67f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Jilin_Jilin_Chuangying_Zhongdongxinshenghuo)
|
||
{
|
||
EnergyPump.transform.position = new Vector3(-6.82f, 0, 2.8f);
|
||
}
|
||
|
||
EnergyPumpTag++;
|
||
|
||
EnergyPump.GetComponent<EnergyPump>().Init(EnergyPumpTag);
|
||
}
|
||
|
||
public void PlayerUIMessage(int index)
|
||
{
|
||
EventDispatcher.TriggerEvent("PromptMessage", index);
|
||
}
|
||
|
||
public void CreateGameStartPoint()
|
||
{
|
||
|
||
GameStart = true;
|
||
isGamePlay = false;
|
||
point.SetActive(true );
|
||
|
||
if (GameInit.Ins.gamePlace == GamePlace.LiaoningAnShan)
|
||
{
|
||
point.transform.position = new Vector3(-2, 0, 2);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.ShanDong_Langfang_QingzhouTaihuacheng)
|
||
{
|
||
point.transform.position = new Vector3(7.46f, 0, 1.65f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Ningxia_Yinchuan_Jinfeng_XinhualianGuangchang)
|
||
{
|
||
point.transform.position = new Vector3(4.15f, 0, 2.3f);
|
||
}
|
||
|
||
if (GameInit.Ins.gamePlace == GamePlace.Shandong_Weifang_Linqu_WandaGuangchang)
|
||
{
|
||
point.transform.position = new Vector3(-4.97f, 0, -4f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hebei_Hengshui_Taocheng_WandaGuangchang)
|
||
{
|
||
point.transform.position = new Vector3(-7.51f, 0, -2.78f);
|
||
}
|
||
if (GameInit.Ins.gamePlace == GamePlace.Jilin_Jilin_Chuangying_Zhongdongxinshenghuo)
|
||
{
|
||
point.transform.position = new Vector3(-6.48f, 0, 2.62f);
|
||
}
|
||
else
|
||
{
|
||
point.transform.position = new Vector3(0.27f, 0, 2.84f);
|
||
}
|
||
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
{
|
||
StartGuide();
|
||
}, 0.5f);
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
{
|
||
if (isGamePlay)
|
||
return;
|
||
Destroy(point.gameObject);
|
||
GamePlay();
|
||
}, 5f);
|
||
}
|
||
public GameObject CreateEnemyDoor(Vector3 pos, Vector3 angle, Vector3 scale)
|
||
{
|
||
GameObject crack = Instantiate(enemyDoorPre);
|
||
crack.transform.position = new Vector3(pos.x, pos.y, pos.z);
|
||
crack.transform.localEulerAngles = angle;
|
||
crack.transform.localScale = scale;
|
||
return crack;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建攻击BUFF
|
||
/// </summary>
|
||
/// <param name="pos"></param>
|
||
public void CreateAtkBuff(Vector3 pos)
|
||
{
|
||
GameObject atkBuff = Instantiate(AtkBuffPre);
|
||
atkBuff.transform.position = new Vector3(pos.x, 0, pos.z);
|
||
// 山东廊坊青州泰华城场地的特殊逻辑:道具自动飞向(0,0,0)点
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Zhuzhou_Wanda_Shennongcheng_Chaowanshe)
|
||
{
|
||
StartCoroutine(FlyToCenterPoint(atkBuff, new Vector3(0.1f, 1, 1.68f), 2.0f));
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建防御BUFF
|
||
/// </summary>
|
||
/// <param name="pos"></param>
|
||
public void CreateDeeBuff(Vector3 pos)
|
||
{
|
||
GameObject deeBuff = Instantiate(deffBuffPre);
|
||
deeBuff.transform.position = new Vector3(pos.x, 0, pos.z);
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Zhuzhou_Wanda_Shennongcheng_Chaowanshe)
|
||
{
|
||
StartCoroutine(FlyToCenterPoint(deeBuff, new Vector3(0.1f, 1, 1.68f), 2.0f));
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建血包
|
||
/// </summary>
|
||
public void CreateBloodBag(Vector3 pos)
|
||
{
|
||
GameObject bloodBag = Instantiate(BloodBagPre);
|
||
bloodBag.transform.position = new Vector3(pos.x, 0, pos.z);
|
||
// 山东廊坊青州泰华城场地的特殊逻辑:道具自动飞向(0,0,0)点
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Zhuzhou_Wanda_Shennongcheng_Chaowanshe)
|
||
{
|
||
StartCoroutine(FlyToCenterPoint(bloodBag, new Vector3(0.1f, 1, 1.68f), 2.0f));
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建武器道具
|
||
/// </summary>
|
||
public void CreatePlayerWeapon(PlayerWeaponType type, Vector3 pos)
|
||
{
|
||
GameObject prop = Instantiate(weaponItemPre);
|
||
prop.GetComponent<WeaponProp>().Init(type);
|
||
prop.transform.position = new Vector3(pos.x, 1f, pos.z);
|
||
// 山东廊坊青州泰华城场地的特殊逻辑:道具自动飞向(0,0,0)点
|
||
if (GameInit.Ins.gamePlace == GamePlace.Hunan_Zhuzhou_Wanda_Shennongcheng_Chaowanshe)
|
||
{
|
||
StartCoroutine(FlyToCenterPoint(prop, new Vector3(0.1f,1,1.68f), 2.0f));
|
||
}
|
||
|
||
|
||
}
|
||
/// <summary>
|
||
/// 道具飞向中心点(0,0,0)的协程
|
||
/// </summary>
|
||
/// <param name="prop">道具对象</param>
|
||
/// <param name="targetPosition">目标位置</param>
|
||
/// <param name="duration">飞行时间</param>
|
||
/// <returns></returns>
|
||
private IEnumerator FlyToCenterPoint(GameObject prop, Vector3 targetPosition, float duration)
|
||
{
|
||
if(prop == null) yield break;
|
||
|
||
// 获取道具的碰撞器组件,暂时禁用碰撞器避免飞行过程中被拾取
|
||
Collider propCollider = prop.GetComponent<Collider>();
|
||
if (propCollider != null)
|
||
{
|
||
propCollider.enabled = false;
|
||
}
|
||
|
||
Vector3 startPosition = prop.transform.position;
|
||
float elapsedTime = 0f;
|
||
|
||
// 添加一个向上的弧度,让飞行路径更自然
|
||
Vector3 controlPoint = (startPosition + targetPosition) * 0.5f + Vector3.up * 2f;
|
||
|
||
// 飞行过程中只更新位置,不改变旋转
|
||
while (elapsedTime < duration && prop != null)
|
||
{
|
||
elapsedTime += Time.deltaTime;
|
||
float t = elapsedTime / duration;
|
||
|
||
// 使用二次贝塞尔曲线计算位置
|
||
Vector3 position = CalculateBezierPoint(startPosition, controlPoint, targetPosition, t);
|
||
|
||
// 只更新位置,不改变旋转,让WeaponProp脚本的旋转动画自然运行
|
||
prop.transform.position = position;
|
||
|
||
yield return null;
|
||
}
|
||
|
||
// 飞行完成后重新启用碰撞器
|
||
if (prop != null && propCollider != null)
|
||
{
|
||
propCollider.enabled = true;
|
||
|
||
// 确保最终位置准确
|
||
prop.transform.position = targetPosition;
|
||
|
||
|
||
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 计算二次贝塞尔曲线上的点
|
||
/// </summary>
|
||
/// <param name="p0">起点</param>
|
||
/// <param name="p1">控制点</param>
|
||
/// <param name="p2">终点</param>
|
||
/// <param name="t">插值参数(0-1)</param>
|
||
/// <returns>曲线上的点</returns>
|
||
private Vector3 CalculateBezierPoint(Vector3 p0, Vector3 p1, Vector3 p2, float t)
|
||
{
|
||
float u = 1 - t;
|
||
float tt = t * t;
|
||
float uu = u * u;
|
||
|
||
Vector3 p = uu * p0; // (1-t)^2 * P0
|
||
p += 2 * u * t * p1; // 2(1-t)t * P1
|
||
p += tt * p2; // t^2 * P2
|
||
|
||
return p;
|
||
}
|
||
public bool isFirstGetWeapon;
|
||
public void EnemyDisGetWeapon(Vector3 pos)
|
||
{
|
||
|
||
bool isGet = Random.Range(0, 100) > 70;
|
||
if (!isGet) return;
|
||
|
||
int index = Random.Range(0, 100);
|
||
int id = 2;
|
||
if (index <= 10)
|
||
id = Random.Range(8, 10);
|
||
if (index is > 10 and <= 50)
|
||
id = Random.Range(5, 8);
|
||
if (index is > 50)
|
||
id = Random.Range(2, 5);
|
||
|
||
// 对于山东廊坊青州泰华城场地,掉落的位置改为(0,0,0)附近
|
||
Vector3 dropPosition = pos;
|
||
if (GameInit.Ins.gamePlace == GamePlace.Henan_Xinxiang_Wandaguangchang_Shinei)
|
||
{
|
||
// 在(0,0,0)点周围随机位置掉落
|
||
dropPosition = new Vector3(
|
||
Random.Range(1.5f, 2.5f),
|
||
1f,
|
||
Random.Range(1.5f, 2.5f)
|
||
);
|
||
}
|
||
|
||
CreatePlayerWeapon((PlayerWeaponType)id, dropPosition);
|
||
|
||
|
||
}
|
||
|
||
public void CurEnemyDie()
|
||
{
|
||
foreach (var enemy in curEnemyList)
|
||
{
|
||
if (enemy != null)
|
||
enemy.Dead();
|
||
}
|
||
curEnemyList.Clear();
|
||
}
|
||
|
||
public int GetCurEnemyListCount()
|
||
{
|
||
int count = 0;
|
||
foreach (var enemy in curEnemyList)
|
||
{
|
||
if (enemy != null)
|
||
count++;
|
||
}
|
||
|
||
return count;
|
||
}
|
||
|
||
public void CreatePlayer()
|
||
{
|
||
player = Instantiate(playerPre);
|
||
}
|
||
|
||
public bool IsAllBossPetDie()
|
||
{
|
||
foreach (var enemy in curEnemyList)
|
||
{
|
||
if (enemy != null && enemy.health > 0)
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public void CurLevelWin(Vector3 pos)
|
||
{
|
||
curLevel++;
|
||
CurEnemyDie();
|
||
CreateEnergyPump(pos);
|
||
}
|
||
|
||
public void CreateBoss()
|
||
{
|
||
BossPosData data = BossPosDataDic[curLevel];
|
||
GameObject door = null;
|
||
if (curLevel != 0)
|
||
door = CreateEnemyDoor(data.DoorPos, data.DoorAng, Vector3.one * data.DoorScale);
|
||
switch (curLevel)
|
||
{
|
||
case 0:
|
||
CreateEnemy(0, data.BossPos, Vector3.zero, true);
|
||
break;
|
||
case 1:
|
||
//舰载机
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
door.GetComponent<EnemyDoor>().desTime = 6;
|
||
door.GetComponent<EnemyDoor>().InitData();
|
||
}, 1f);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
CreateEnemy(2, data.BossPos, data.BossAng, true);
|
||
}, 3f);
|
||
break;
|
||
case 2:
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
door.GetComponent<EnemyDoor>().desTime = 10;
|
||
door.GetComponent<EnemyDoor>().InitData();
|
||
}, 1f);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
CreateEnemy(3, data.BossPos, data.BossAng, true);
|
||
}, 3f);
|
||
break;
|
||
case 3:
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
door.GetComponent<EnemyDoor>().desTime = 10;
|
||
door.GetComponent<EnemyDoor>().InitData();
|
||
}, 1f);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
CreateEnemy(5, data.BossPos, data.BossAng, true);
|
||
}, 3f);
|
||
break;
|
||
case 4:
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
door.GetComponent<EnemyDoor>().desTime = 6;
|
||
door.GetComponent<EnemyDoor>().InitData();
|
||
}, 1f);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
CreateEnemy(7, data.BossPos, data.BossAng, true);
|
||
}, 1f);
|
||
break;
|
||
}
|
||
}
|
||
|
||
public void WinEndGame()
|
||
{
|
||
isGameEnd = true;
|
||
ShowEndGameUI(true);
|
||
GameInit.Ins.PlayAudio("1.17", GameInit.Ins.self.transform, true);
|
||
AudioManager.Ins?.SoundPlay("bgm4", true);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
Debug.Log("游戏结束,5秒后退出");
|
||
Application.Quit();
|
||
}, 60f);
|
||
////修改处:销毁AI角色
|
||
if (aiCharacter != null)
|
||
{
|
||
//取消注册事件
|
||
AIController aiController = aiCharacter.GetComponent<AIController>();
|
||
if (aiController != null)
|
||
{
|
||
aiController.OnIntroductionComplete -= StartGameAfterIntroduction;
|
||
}
|
||
|
||
Destroy(aiCharacter);
|
||
}
|
||
}
|
||
|
||
public void LoseEndGame()
|
||
{
|
||
ShowEndGameUI(false);
|
||
if (curBoss != null)
|
||
{
|
||
Destroy(curBoss.gameObject);
|
||
}
|
||
|
||
GameInit.Ins.self.IsAlive = false;
|
||
GameInit.Ins.self.End();
|
||
isGameEnd = true;
|
||
CurEnemyDie();
|
||
AudioManager.Ins?.SoundPlay("bgm4", true);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
Debug.Log("游戏结束,5秒后退出");
|
||
Application.Quit();
|
||
}, 60f);
|
||
//修改处:销毁AI角色
|
||
if (aiCharacter != null)
|
||
{
|
||
//取消注册事件
|
||
AIController aiController = aiCharacter.GetComponent<AIController>();
|
||
if (aiController != null)
|
||
{
|
||
aiController.OnIntroductionComplete -= StartGameAfterIntroduction;
|
||
}
|
||
|
||
Destroy(aiCharacter);
|
||
}
|
||
}
|
||
#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 (GameInit.Ins.self != null)
|
||
{
|
||
lastPlayerPosition = GameInit.Ins.self.transform.position;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新指引箭头位置(实时跟随玩家移动)
|
||
/// </summary>
|
||
|
||
// 修改 UpdateGuideArrowPosition 方法
|
||
private void UpdateGuideArrowPosition()
|
||
{
|
||
if (!isGuideArrowActive || point == null || GameInit.Ins.self == null)
|
||
return;
|
||
|
||
// 获取玩家当前位置
|
||
Vector3 currentPlayerPosition = GameInit.Ins.self.transform.position;
|
||
|
||
// 检查冷却时间
|
||
if (Time.time - lastPathUpdateTime < updatePathCooldown)
|
||
return;
|
||
|
||
// 检查玩家是否移动了足够远的距离
|
||
float distanceMoved = Vector3.Distance(currentPlayerPosition, lastPlayerPosition);
|
||
|
||
if (distanceMoved > updatePathThreshold)
|
||
{
|
||
// 获取门的位置
|
||
Vector3 doorPosition = point.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 && point != null && GameInit.Ins.self != null)
|
||
{
|
||
guideArrowComponent.ShowPath();
|
||
isGuideArrowActive = true;
|
||
|
||
// 初始化路径
|
||
Vector3 playerPosition = GameInit.Ins.self.transform.position;
|
||
Vector3 doorPosition = point.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 (point != null && GameInit.Ins.self != null)
|
||
{
|
||
ShowGuideArrow();
|
||
|
||
// 初始化路径
|
||
Vector3 playerPosition = GameInit.Ins.self.transform.position;
|
||
Vector3 doorPosition = point.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
|
||
} |