using System;
using System.Collections;
using System.Collections.Generic;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Common;
using DragonLi.Core;
using Mirror;
using UnityEngine;
using UnityEngine.PlayerLoop;
using XPlugin.Data.JsonLiteDB;
using static XPlugin.Data.JsonLiteDB.JsonLiteDB;
using LitJson;
using Pathfinding;
using DarkTonic.MasterAudio;
using NaughtyAttributes;
using UnityEngine.UIElements;
using Random = UnityEngine.Random;
///
/// 游戏状态
///
public enum GameState
{
None = 0,
Playing = 1,
///
/// 胜利
///
Victory = 2,
///
/// 失败
///
Failur = 3,
Settle=4,
///
/// 准备阶段
///
Wave=5,
///
/// 冲锋阶段
///
EndEvent,
}
public enum GameEnemyEventType
{
None=0,//普通事件
Snipe=1,//狙击事件
Mortar=2,//迫击炮事件
MachineGun=3,//机关枪事件
SubmachineGun=4,//冲锋枪事件
Grenade=5,//手榴弹事件
Biochemical=6,//生化兵事件
Tank=7,//坦克兵事件
Bomber=8,//轰炸机事件
HelpNpc=9,//拯救平民事件
BulletUp=10,//子弹拾取事件
CleanUp=11,//清场事件
LastGame=12,//最终冲锋事件
}
public enum GameMode
{
OnePlayer=0,
TwoPlayers=1,
}
public class GameManager : NetworkBehaviour
{
public static GameManager Ins { get; private set; }
#region 预制体
public GameObject DoorPre;
public GameObject itemPropPre;
public GameObject mortarBulletPre;
public GameObject gqBulletPre;
public GameObject gqMuzzleBulletPre;
// 炮塔预制体集合
//public GameObject[] TowerPres;
// 怪物预制集合
public GameObject[] EnemyPres;
public GameObject[] playerAiPres;
public GameObject playerEndAiPres;
public GameObject explosionPre;
public GameObject enemyGrenadePre;
public GameObject enemyGasBombPre;
public GameObject enemyEndAiPre;
public GameObject enemyPlanePre;
public GameObject[] playerNpcPre;
// 怪物ui预制体
public GameObject EnemyUIPre;
#endregion
// json数据库
private JsonLiteDB DB;
// 怪物信息集合
//public Dictionary EnemyInfos = new Dictionary();
public Dictionary PlayerAiInfos = new Dictionary();
// 炮塔信息集合
public Dictionary> TowerInfos = new Dictionary>();
// 枪械信息集合
//public Dictionary GunInfos = new Dictionary();
// 子弹信息集合
public Dictionary BulletInfos = new Dictionary();
public Dictionary AiInfos = new Dictionary();
public Dictionary RoundInfos = new Dictionary();
// 剧情信息
public Dictionary CombatUnitInfos = new Dictionary();
private List curGunPropList = new List();
public Dictionary players = new Dictionary();
public GameMode gameMode = GameMode.OnePlayer;
///
/// 敌人自增
///
private int enemyIndex = 0;
///
/// 所有敌人
///
public Dictionary EnemyList = new Dictionary();
public Dictionary PlayerAiList = new Dictionary();
///
/// 所有敌人UI
///
public Dictionary EnemyUIList = new Dictionary();
///
/// 所有炮塔
///
public Dictionary TowerList = new Dictionary();
public Dictionary> TowerList2 = new Dictionary>();
public Dictionary SettleInfos = new Dictionary();
//public List curEnemyList = new List();
[SyncVar]
public bool isStart;
///
/// 波次自增
///
[SyncVar]
public int roundIndex = 0;
// 游玩结束时间
[NonSerialized]
[SyncVar]
public long vistEnd = 0;
// 总游玩时长
private int vistAllTime = (int)(60 * 12);
[SyncVar]
public string settleData = "";
[SyncVar]
public GameState gameState = GameState.None;
[SoundGroup] public string JointIn;
[SoundGroup] public string roundSound;
public int roundWaveTime;
public int curRoundWaveTime;
//添加
[Header("魔力队长角色")]
public GameObject player;
public GameObject aiCharacterPre;//AI角色预制体
private GameObject aiCharacter;//AI角色实例
private bool isAIIntroductionComplete = false;
//修改处:添加创建AI角色的方法
public void GamePlay()
{
CreateAICharacter();
}
private void CreateAICharacter()
{
//检查是否已经存在AI角色
if (aiCharacter != null)
{
Debug.Log("AI角色已经存在,不再创建新的");
return;
}
if (aiCharacterPre != null)
{
Debug.Log("创建AI角色");
//获取第一个玩家
Transform player = players[0].transform ;
if (player == null)
{
Debug.LogError("找不到玩家,无法创建AI角色");
return;
}
//在玩家前方创建AI角色
Vector3 spawnPosition = player.transform.position + player.transform.forward * 3f;
spawnPosition.y = 0f; // 固定Y坐标为0
aiCharacter = Instantiate(aiCharacterPre, spawnPosition, Quaternion.identity);
//获取AIController并启动开场白
AIController aiController = aiCharacter.GetComponent();
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 StartGameAfterIntroduction()
{
isAIIntroductionComplete = true;
GameStart();
}
void Awake()
{
Ins = this;
}
void Start()
{
if (isClient)
{
isStart = false;
CreateDoor();
}
}
///
/// 创建门
///
public void CreateDoor()
{
UpdateConf();
if (!isServer)
return;
GameObject door = Instantiate(DoorPre);
door.transform.position = GameLocal.Ins.doorPos.position.ReflectVectorXOZ();
NetworkServer.Spawn(door);
}
///
/// 创建初回合
///
public void CreateFirstRound()
{
RpcShowHUD();
roundIndex = 0;
PlaySound2DRPC("1.0");
// CoroutineTaskManager.Instance.WaitSecondTodo(() =>
// {
// PlaySound2DRPC("1.1");
// }, 10f);
CreatePlayerAi();
//SetGameState(GameState.Wave);
RpcMessageRound();
}
///
/// 创建下一回合
///
public void CreateNextRound()
{
roundIndex++;
roundWaveTime = 3;
curRoundWaveTime = 1;
RpcMessageRound();
}
[Server]
public void GameStart()
{
gameState = GameState.Playing;
gameMode = players.Count <= 1 ? GameMode.OnePlayer : GameMode.TwoPlayers;
vistEnd = (long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds + vistAllTime;
isStart = true;
ChangeBgmRpc(0);
AstarPath.active.Scan();
CreateFirstRound();
// 延迟1s后给所有人发放武器
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
GivePistol(GunType.Pistol);
}, 1f);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
//GameOver(GameState.Settle);
StartSpecialEvent(GameEnemyEventType.CleanUp);
}, vistAllTime);
}
[ClientRpc]
public void GivePistol(GunType type)
{
Debug.Log("创建武器中...");
GameLocal.Ins.self.PickUpGun(type, -999);
}
[Server]
public void SetGameState(GameState state)
{
gameState = state;
}
//1.游戏时间到
//2.所有怪物被消灭
//3.玩家被消灭
//以上都要跳出结算
[Server]
public void GameOver()
{
RpcShow();
DamageAllEnemy();
isStart = false;
PlaySound2DRPC("1.60");
}
[Server]
public void PlayEndEvent()
{
Debug.LogError("开启End事件");
gameState = GameState.EndEvent;
GivePistol(GunType.MeleeWeapon);
foreach (var item in PlayerAiList.Values)
{
item.EndEvent();
}
PlaySound2DRPC("1.61");
OpenDoor();
for (int i = 0; i < 7; i++)
{
Transform[] targetPos = GameLocal.Ins.enemyEndPos;
GameObject enemy = Instantiate(enemyEndAiPre);
NetworkServer.Spawn(enemy);
int posId = i / 3;
enemy.transform.position = GameLocal.Ins.enemyStartPos[posId].position;
enemy.transform.eulerAngles = targetPos[posId].eulerAngles;
enemyIndex++;
Enemy enemyScript = enemy.GetComponent();
enemyScript.OnSpawn(enemyIndex, 3, 1, GameLocal.Ins.pkPos.position);
enemyScript.ai.maxSpeed = 2;
EnemyList.Add(enemyIndex, enemyScript);
GameObject playerAi = Instantiate(playerEndAiPres);
NetworkServer.Spawn(playerAi);
playerAi.transform.position = GameLocal.Ins.endPlayerStartPos.position;
playerAi.transform.eulerAngles = AiInfos[1].EulerAngles;
PlayerAI playerAI = playerAi.GetComponent();
playerAI.OnSpawn(i + 2, PlayerAIType.EndPlayerAi, 1, enemy);
playerAI.ai.maxSpeed = 2;
PlayerAiList.Add(i + 2, playerAI);
}
curRoundEnemyCount = EnemyList.Count;
}
[ClientRpc]
public void OpenDoor()
{
GameLocal.Ins.OpenDoor();
}
[ClientRpc]
public void RpcShowWin(bool isBlue)
{
}
[ClientRpc]
public void RpcShow()
{
SettlePanel.Show();
}
///
/// 下一波进攻开始
///
[Server]
public void RpcMessageRound()
{
if (!isStart)
return;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
if (!isStart || gameState == GameState.EndEvent)
return;
PlaySound2DRPC("1.4");
}, curRoundWaveTime);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
if (!isStart || gameState == GameState.EndEvent)
return;
GetRoundEnemy();
SetGameState(GameState.Playing);
}, roundWaveTime);
}
[ClientRpc]
public void ShowHudRoundTime()
{
DragonLi.Core.EventDispatcher.TriggerEvent("NewWaveStart", roundIndex);
}
[ClientRpc]
public void ChangeBgmRpc(int i)
{
GameLocal.Ins.BGMState.StateChange(i);
}
public int curRoundEnemyCount;
///
/// 创建敌方单位
///
[Server]
IEnumerator CreateEnemy(RoundInfo info)
{
curRoundEnemyCount = info.EnemyList.Count;
for (int i = 0; i < info.EnemyList.Count; i++)
{
int enemyId = info.EnemyList[i];
bool isUerInfoAngles = (EnemyType)enemyId == EnemyType.Mortar;
Transform[] targetPos = GameLocal.Ins.enemyEndPos;
GameObject enemy = Instantiate(EnemyPres[enemyId - 3]);
NetworkServer.Spawn(enemy);
int posId = i / 3;
int posX = i % 3 == 0 ? 0 : i % 3 == 1 ? 1 : -1;
if (isUerInfoAngles)
posX = 0;
switch ((EnemyType)enemyId)
{
case EnemyType.Ordinary:
case EnemyType.Sniper:
break;
case EnemyType.Mortar:
targetPos = GameLocal.Ins.mortarPos;
break;
}
enemy.transform.position = GameLocal.Ins.enemyStartPos[posId].position;
enemy.transform.eulerAngles = isUerInfoAngles ? AiInfos[i + 3].EulerAngles : targetPos[posId].eulerAngles;
enemyIndex++;
Enemy enemyScript = enemy.GetComponent();
Vector3 endPos = targetPos[posId].position + new Vector3(0, 0, posX);
if (enemyScript.type == EnemyType.Riflemen)
{
endPos = GameLocal.Ins.riflemenPos.position;
}
enemyScript.OnSpawn(enemyIndex, info.EnemyList[i], 1, endPos);
EnemyList.Add(enemyIndex, enemyScript);
yield return new WaitForSeconds(0.5f);
}
}
///
/// 创建辅助AI
///
public void CreatePlayerAi()
{
for (int i = 0; i < 2; i++)
{
GameObject playerAi = Instantiate(playerAiPres[i]);
NetworkServer.Spawn(playerAi);
playerAi.transform.position = GameLocal.Ins.playerAiPos[i].position;
playerAi.transform.eulerAngles = AiInfos[i + 1].EulerAngles;
PlayerAI enemyScript = playerAi.GetComponent();
enemyScript.OnSpawn(i, (PlayerAIType)i, 1, GameLocal.Ins.playerAiEndPos[i].gameObject);
PlayerAiList.Add(i, enemyScript);
}
// else if(gameMode == GameMode.TwoPlayers)
// {
// GameObject playerAi = Instantiate(playerAiPres[0]);
// NetworkServer.Spawn(playerAi);
// playerAi.transform.position = GameLocal.Ins.playerAiPos[0].position;
// playerAi.transform.eulerAngles = AiInfos[1].EulerAngles;
// PlayerAI enemyScript = playerAi.GetComponent();
// enemyScript.OnSpawn(0,0, 1,GameLocal.Ins.playerAiEndPos[0].gameObject);
// PlayerAiList.Add(0, enemyScript);
// }
}
#region 创造敌人道具
[Server]
public void CreateExplosion(Vector3 pos, EnemyType type)
{
if (!isServer)
return;
var ex = Instantiate(explosionPre, pos, Quaternion.identity);
NetworkServer.Spawn(ex);
ex.GetComponent().Init(type);
}
public void CreateGrenade(Vector3 startPos)
{
if (!isServer)
return;
var ex = Instantiate(enemyGrenadePre, startPos, Quaternion.identity);
NetworkServer.Spawn(ex);
float x = Random.Range(-3, 3);
float z = Random.Range(-3, 3);
ex.GetComponent().Init(startPos, GameLocal.Ins.endMortarPos.position + new Vector3(x, 0, z));
}
public void CreateGasBomb(Vector3 startPos)
{
if (!isServer)
return;
var ex = Instantiate(enemyGasBombPre, startPos, Quaternion.identity);
NetworkServer.Spawn(ex);
float x = Random.Range(-3, 3);
float z = Random.Range(-3, 3);
ex.GetComponent().Init(startPos, GameLocal.Ins.endMortarPos.position + new Vector3(x, 0, z));
}
public void CreateEnemyPlane(Transform startPos)
{
if (!isServer)
return;
var ex = Instantiate(enemyPlanePre, startPos.position, Quaternion.identity);
NetworkServer.Spawn(ex);
}
public void CreateItemProp(Transform pos)
{
if (!isStart)
return;
var item = Instantiate(itemPropPre);
NetworkServer.Spawn(item);
item.transform.position = new Vector3(pos.position.x, 0.5f, pos.position.z);
item.GetComponent().SetItemProp(ItemPropType.Hp);
}
#endregion
public List GetRoundEnemy()
{
List curEnemyList = new List();
int curRoundIndex = roundIndex >= RoundInfos.Count ? Random.Range(1, RoundInfos.Count) : roundIndex;
var roundInfo = RoundInfos[curRoundIndex];
// curRoundIndex=5;
// roundInfo= RoundInfos[curRoundIndex];
StartEvent(roundInfo);
if (roundIndex % 5 == 0 && roundIndex != 0)
{
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
StartSpecialEvent(GameEnemyEventType.HelpNpc);
}, 5);
}
return curEnemyList;
}
public GameEnemyEventType curEnemyEventType;
public void StartEvent(RoundInfo info)
{
curEnemyEventType = (GameEnemyEventType)info.Belong;
StartCoroutine(CreateEnemy(info));
switch (curEnemyEventType)
{
case GameEnemyEventType.SubmachineGun:
case GameEnemyEventType.None:
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
Debug.LogError("播放音效:1.10");
PlayerAiList[0].PlaySound3DRPC("1.10", true);
EnemyShowOutline(EnemyType.Ordinary);
EnemyShowOutline(EnemyType.Charge);
}, 10);
break;
case GameEnemyEventType.Snipe:
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.14", true);
}, 5);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.15", true);
EnemyShowOutline(EnemyType.Sniper);
}, 7);
break;
case GameEnemyEventType.Mortar:
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.20", true);
StartCoroutine(CreateMortarBullet());
}, 7);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.21", true);
EnemyShowOutline(EnemyType.Mortar);
}, 10);
break;
case GameEnemyEventType.MachineGun:
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.24", true);
StartCoroutine(CreateGQBullet());
}, 7);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.25", true);
EnemyShowOutline(EnemyType.Riflemen);
}, 10);
break;
case GameEnemyEventType.Grenade:
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.35", true);
}, 5);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.38", true);
EnemyShowOutline(EnemyType.Grenade);
}, 7);
break;
case GameEnemyEventType.Biochemical:
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.40", true);
}, 5);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.42", true);
EnemyShowOutline(EnemyType.Virus);
}, 7);
break;
case GameEnemyEventType.Bomber:
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.56", true);
EnemyShowOutline(EnemyType.Commander);
EnemyShowOutline(EnemyType.Mortar);
EnemyShowOutline(EnemyType.Grenade);
EnemyShowOutline(EnemyType.Virus);
EnemyShowOutline(EnemyType.Riflemen);
StartCoroutine(CreateGQBullet());
StartCoroutine(CreateMortarBullet());
}, 10);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.59", true);
}, 20);
break;
}
}
public void StartSpecialEvent(GameEnemyEventType type)
{
switch (type)
{
case GameEnemyEventType.HelpNpc:
CreateNpc();
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayerAiList[0].PlaySound3DRPC("1.67", true);
}, 5);
break;
case GameEnemyEventType.CleanUp:
CreateEnemyEndBullet();
break;
}
}
private void Update()
{
// if (Input.GetKeyDown(KeyCode.Space))
// {
// StartSpecialEvent(GameEnemyEventType.HelpNpc);
// CoroutineTaskManager.Instance.WaitSecondTodo(() =>
// {
// StartSpecialEvent(GameEnemyEventType.CleanUp);
// }, 5);
// }
}
IEnumerator CreateMortarBullet()
{
Transform insPos = GameLocal.Ins.insMortarPos;
Transform endPos = GameLocal.Ins.endMortarPos;
bool isHaveMortar = IsHaveTypeEnemy(EnemyType.Mortar);
while (isHaveMortar)
{
var item = Instantiate(mortarBulletPre);
NetworkServer.Spawn(item);
item.transform.position = insPos.position;
int rangeIndexX = Random.Range(-5, 5);
int rangeIndexZ = Random.Range(-2, 2);
item.GetComponent().Init(insPos.position, endPos.position + new Vector3(rangeIndexX, 0, rangeIndexZ));
yield return new WaitForSeconds(AiInfos[(int)EnemyType.Mortar].FiringRate);
isHaveMortar = IsHaveTypeEnemy(EnemyType.Mortar);
}
}
IEnumerator CreateGQBullet()
{
Transform insPos = GameLocal.Ins.gQPos;
Vector3 endPos = GameLocal.Ins.riflemenEndPos.position;
bool isHaveMortar = IsHaveTypeEnemy(EnemyType.Riflemen);
while (isHaveMortar)
{
var item = Instantiate(gqBulletPre);
NetworkServer.Spawn(item);
item.transform.position = insPos.position;
int rangeIndexZ = Random.Range(-2, 2);
item.GetComponent().OnSpawn(endPos + new Vector3(rangeIndexZ, 0, rangeIndexZ), 20);
var itemMuzzle = Instantiate(gqMuzzleBulletPre);
NetworkServer.Spawn(itemMuzzle);
itemMuzzle.transform.position = insPos.position;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(itemMuzzle.gameObject);
}, 1);
yield return new WaitForSeconds(AiInfos[(int)EnemyType.Riflemen].FiringRate);
isHaveMortar = IsHaveTypeEnemy(EnemyType.Riflemen);
}
}
[ClientRpc]
public void OpenEndBullet()
{
GameLocal.Ins.OpenEndBullet();
}
[ClientRpc]
public void DownEndBullet()
{
GameLocal.Ins.DownEndBullet();
}
public List NpcEnemyList = new List();
public void CreateNpc()
{
if (!isStart)
return;
for (int posId = 0; posId < 2; posId++) // npcPos[0] 和 npcPos[1]
{
List npcList = new List();
// === 生成 3 个 NPC ===
for (int i = 0; i < 3; i++)
{
int id = Random.Range(0, playerNpcPre.Length);
// 在 npcPos 附近生成,带随机偏移
Vector3 randomOffset = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f));
Vector3 npcPos = GameLocal.Ins.npcPos[posId].position + randomOffset;
var npc = Instantiate(playerNpcPre[id], npcPos, Quaternion.identity);
NetworkServer.Spawn(npc);
npc.GetComponent().OnSpawn(i, GameLocal.Ins.npcEndPos.gameObject, false);
npcList.Add(npc);
}
// === 敌人生成逻辑 ===
// NPC 的平均位置(大致在3个 NPC 中心点)
Vector3 centerPos = Vector3.zero;
foreach (var npc in npcList)
centerPos += npc.transform.position;
centerPos /= npcList.Count;
// 前进方向
Vector3 forward = GameLocal.Ins.npcPos[posId].forward;
// 敌人在前进方向的反方向(后面)
Vector3 backOffset = -forward * 3f; // 敌人与NPC中心点的间隔,数值可调
for (int j = 0; j < 2; j++)
{
// 敌人横向展开
Vector3 sideOffset = Vector3.Cross(Vector3.up, forward).normalized * (j == 0 ? -1.5f : 1.5f);
Vector3 enemyPos = centerPos + backOffset + sideOffset;
var enemy = Instantiate(EnemyPres[0], enemyPos, Quaternion.identity);
NetworkServer.Spawn(enemy);
enemy.GetComponent().OnSpawn(-j, 3, -1, GameLocal.Ins.npcPos[posId].position);
enemy.GetComponent().isOutLine = true;
NpcEnemyList.Add(enemy.GetComponent());
}
}
}
public void CreateEnemyEndBullet()
{
PlayerAiList[0].PlaySound3DRPC("1.65", true);
OpenEndBullet();
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
foreach (var item in EnemyList.Values)
{
item.Die(null, transform);
}
foreach (var item in NpcEnemyList)
{
item.Die(null, transform);
}
}, 5);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
PlayEndEvent();
DownEndBullet();
}, 8);
}
public bool IsHaveTypeEnemy(EnemyType curType)
{
foreach (var enemy in EnemyList.Values)
{
if (enemy.type == curType)
return true;
}
return false;
}
public void EnemyShowOutline(EnemyType type)
{
foreach (var enemy in EnemyList.Values)
{
if (enemy.type == type)
{
enemy.isOutLine = true;
}
}
}
///
/// 删除敌方单位
///
[Server]
public void DeleteEnemy(int id, bool isNpcEnemy)
{
if (isNpcEnemy)
{
foreach (var item in NpcEnemyList)
{
if (item.id == id)
{
NpcEnemyList.Remove(item);
NetworkServer.Destroy(item.gameObject);
return;
}
}
return;
}
GameObject enemy = EnemyList[id].gameObject;
EnemyList.Remove(id);
curRoundEnemyCount--;
NetworkServer.Destroy(enemy);
ChangePlayerAiCountdownTime();
if (curRoundEnemyCount <= 0)
{
CreateNextRound();
if (gameState == GameState.EndEvent)
{
gameState = GameState.Victory;
GameOver();
}
}
}
///
/// 痛击场上所有敌方单位
///
[Command(requiresAuthority = false)]
public void DamageAllEnemy()
{
foreach (Enemy enemy in EnemyList.Values)
{
enemy.ApplyDamage(999999, null, null);
}
}
///
/// 更新配置表
///
public void UpdateConf()
{
string text = Resources.Load("Data").text;
if (text != null)
{
ParseGameJson(text);
}
}
public void ParseGameJson(string text)
{
DB = new JsonLiteDB();
DB.Load(text);
roundWaveTime = 15;
curRoundWaveTime = 12;
AiInfos.Clear();
RoundInfos.Clear();
TableReader infoReader = DB["AiInfo"].GetReader();
// EnemyInfos.Clear();
// while (infoReader.Read())
// {
// EnemyInfo info = new EnemyInfo(infoReader);
// EnemyInfos.Add((EnemyType)info.Type,info);
// }
//
// infoReader = DB["TowersInfo"].GetReader();
// while (infoReader.Read())
// {
// TowerInfo info = new TowerInfo(infoReader);
// TowerInfos.TryGetValue((TowerType)info.Type, out Dictionary infoList);
// if (infoList == null)
// {
// Dictionary list = new Dictionary();
// list.Add(info.Lvl, info);
// TowerInfos.Add((TowerType)info.Type, list);
// }
// else
// {
// infoList.Add(info.Lvl, info);
// }
// }
// infoReader = DB["GunsInfo"].GetReader();
// GunInfos.Clear();
// while (infoReader.Read())
// {
// GunInfo info = new GunInfo(infoReader);
// GunInfos.Add((GunType)info.Type,info);
// }
//
// infoReader = DB["BulletsInfo"].GetReader();
// BulletInfos.Clear();
// while (infoReader.Read())
// {
// BulletInfo info = new BulletInfo(infoReader);
// BulletInfos.Add((BulletType)info.Type,info);
// }
infoReader = DB["AiInfo"].GetReader();
while (infoReader.Read())
{
AiInfo info = new AiInfo(infoReader);
AiInfos.Add(info.ID, info);
}
infoReader = DB["RoundInfo"].GetReader();
while (infoReader.Read())
{
RoundInfo info = new RoundInfo(infoReader);
RoundInfos.Add(info.ID, info);
}
// infoReader = DB["StoryProgressInfo"].GetReader();
// while (infoReader.Read())
// {
// CombatUnitInfo info = new CombatUnitInfo(infoReader);
// CombatUnitInfos.Add(info.Belong,info);
// CombatUnitInfos.TryGetValue(info.Belong, out info);
// }
Debug.Log("游戏数值更新 -> complete");
}
///
/// 获取范围内敌人
///
public int GetRangeEnemyId(Vector3 pos, float radius)
{
int res = -1;
foreach (Enemy enemy in EnemyList.Values)
{
float dis = Vector3.Distance(enemy.transform.position, pos);
if (dis <= radius)
{
radius = dis;
res = enemy.id;
break;
}
}
return res;
}
///
/// 获取最近的Ai
///
///
public GameObject GetPlayerAi(Transform curTransform)
{
if (PlayerAiList.Count == 0)
return null;
GameObject nearestPlayer = null;
float minDistance = float.MaxValue;
foreach (var player in PlayerAiList)
{
if (player.Value == null || player.Key <= 1 || player.Value.isGet) continue;
// 计算XZ平面距离(使用你的 ReflectVectorXOZ 方法)
float dis = Vector3.Distance(
player.Value.transform.position.ReflectVectorXOZ(),
curTransform.position.ReflectVectorXOZ()
);
if (dis < minDistance)
{
minDistance = dis;
player.Value.isGet = true;
nearestPlayer = player.Value.gameObject;
}
}
return nearestPlayer;
}
public GameObject GetPlayer(Transform curTransform)
{
if (players == null || players.Count == 0)
return null;
GameObject nearestPlayer = null;
float minDistance = float.MaxValue;
foreach (var player in players.Values)
{
if (player == null) continue;
// 计算XZ平面距离(使用你的 ReflectVectorXOZ 方法)
float dis = Vector3.Distance(
player.transform.position.ReflectVectorXOZ(),
curTransform.position.ReflectVectorXOZ()
);
if (dis < minDistance)
{
minDistance = dis;
nearestPlayer = player.gameObject;
}
}
return nearestPlayer;
}
///
/// 获取最近敌人
///
///
public GameObject GetEnemy(Transform playerAi)
{
GameObject nearestPlayer = null;
float minDis = 999;
foreach (var enemy in EnemyList.Values)
{
if (enemy == null) continue;
// 计算XZ平面距离(使用你的 ReflectVectorXOZ 方法)
float dis = Vector3.Distance(
enemy.transform.position.ReflectVectorXOZ(),
playerAi.position.ReflectVectorXOZ()
);
if (dis < minDis)
{
nearestPlayer = enemy.gameObject;
minDis = dis;
}
}
return nearestPlayer;
}
public void ChangePlayerAiCountdownTime()
{
foreach (var ai in PlayerAiList.Values)
{
ai.ChangeKillEnemyTime();
}
}
public Transform GetPlayerPos()
{
int rand = Random.Range(0, 100);
if (players.Count >= 2) // 双人模式
{
if (rand < 45) // 0-44
return players[0].transform; // 玩家A
else if (rand < 90) // 45-89
return players[1].transform; // 玩家B
else // 90-99
return PlayerAiList[0].transform; // 队友A
}
else // 单人模式
{
if (rand < 60) // 0-59
return players[0].transform; // 玩家
else if (rand < 80) // 60-79
return PlayerAiList[0].transform; // 队友A
else // 80-99
return PlayerAiList[1].transform; // 队友B
}
}
[Server]
public void CreateEnemyUI(Enemy enemy)
{
GameObject enemyUI = Instantiate(EnemyUIPre);
NetworkServer.Spawn(enemyUI);
EnemyUI enemyUIScript = enemyUI.GetComponent();
enemyUIScript.Init(enemy);
EnemyUIList.Add(enemy.id, enemyUIScript);
}
[Server]
public void DeleteEnemyUI(int id)
{
GameObject enemyUI = EnemyUIList[id].gameObject;
EnemyUIList.Remove(id);
NetworkServer.Destroy(enemyUI);
}
[ClientRpc]
public void RpcShowHUD()
{
HUDPanel.Show();
}
#region 空投道具
///
/// 修复炮塔
///
public void RepairTower()
{
}
///
/// 进入联控
///
[Server]
public void JoinControlTower(int playerIndex)
{
PlayJointMusic();
// 修改所有炮塔模式
foreach (Tower tower in TowerList.Values)
{
if (tower.controllerId == -1)
{
tower.controllerId = playerIndex;
tower.mode = TowerMode.Joint;
}
}
TriggerEvent("JoinControlStart", playerIndex);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
ChangeBgmRpc(0);
foreach (Tower tower in TowerList.Values)
{
if (tower.mode == TowerMode.Joint)
{
tower.controllerId = playerIndex;
tower.mode = tower.originalMode;
}
TriggerEvent("JoinControlEnd", playerIndex);
}
}, 30f);
}
#endregion
[ClientRpc]
public void TriggerEvent(string key, int param)
{
DragonLi.Core.EventDispatcher.TriggerEvent(key, param);
}
public void AddScore(string index, int damage)
{
if (SettleInfos.ContainsKey(index))
{
SettleInfos[index].Score += damage;
}
string jsonStr = JsonMapper.ToJson(SettleInfos);
settleData = jsonStr;
}
public void SetTitle(string index, string title)
{
if (SettleInfos.ContainsKey(index))
{
SettleInfos[index].Title = title;
}
Debug.Log(SettleInfos);
}
public void SetPlayerName(string index)
{
if (SettleInfos.ContainsKey(index))
{
SettleInfos[index].playerName = int.Parse(index);
}
}
[Server]
public void AddData(int playerIndex)
{
SettleInfos.Add(playerIndex.ToString(), new SettleInfo());
}
public string SerializeSettleInfos()
{
return JsonUtility.ToJson(SettleInfos);
}
public bool IsHaveEnemy()
{
return EnemyList.Count > 0;
}
#region 工具
public string GetLessTimeStr()
{
string res = "";
if (isStart)
{
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
public void PlaySound2DRPC(string sound)
{
MasterAudio.PlaySound(sound);
}
[ClientRpc]
public void PlaySound3DRPC(string sound, Transform tran, bool isStop)
{
if (isStop)
MasterAudio.StopAllSoundsOfTransform(tran);
MasterAudio.PlaySound3DAtTransform(sound, tran);
}
public void PlayJointMusic()
{
MasterAudio.PlaySound(JointIn);
GameLocal.Ins.BGMState.StateChange(2);
}
}