public override void OnUnitClicked(Unit unit) { foreach (var f in BattleFieldManager.GetInstance().floors) { f.Value.SetActive(false); } range = new MoveRange(); if (unit.playerNumber.Equals(roundManager.CurrentPlayerNumber) && !unit.UnitEnd && SkillManager.GetInstance().skillQueue.Peek().Key.EName == "FirstAction") { SkillManager.GetInstance().skillQueue.Peek().Key.Reset(); roundManager.RoundState = new RoundStateUnitSelected(roundManager, unit); } else if (SkillManager.GetInstance().skillQueue.Peek().Key.EName == "FirstAction") { Camera.main.GetComponent <RenderBlurOutline>().RenderOutLine(unit.transform); SkillManager.GetInstance().skillQueue.Peek().Key.Reset(); RoundManager.GetInstance().RoundState = new RoundStateWaitingForInput(RoundManager.GetInstance()); range.CreateMoveRange(unit.transform); ((RoundStateWaitingForInput)RoundManager.GetInstance().RoundState).CreatePanel(unit); } Camera.main.GetComponent <RTSCamera>().FollowTarget(unit.transform.position); }
public void ExcuteChangeRoadColorAndRotate(Vector3 position) { //显示路径需要每一个路径点。 RecoverColor(); if (rangeDic.ContainsKey(position)) { List <Vector3> pathList = ChangePathType(UseAstar(character.position, position, range)); if (pathList.Count > 1) { Quaternion wantedRot = Quaternion.LookRotation(pathList[1] - character.position); character.rotation = wantedRot; } //这里可能会有问题,先调用变蓝,再调用变红,不知为何是管用的,可能是覆盖。 foreach (var f in pathList) { GameObject p = BattleFieldManager.GetInstance().GetFloor(f); if (p != null) { p.GetComponent <Floor>().ChangeRangeColorToRed(); } } BattleFieldManager.GetInstance().GetFloor(character.position).GetComponent <Floor>().ChangeRangeColorToRed(); } }
public Range() { BFM = BattleFieldManager.GetInstance(); }
//传入范围和创建范围角色的transform.position即可创建。p即transform.position public void CreateMoveRange(Transform character) { this.character = character; startRotation = character.rotation; range = character.GetComponent <CharacterStatus>().attributes.Find(d => d.eName == "mrg").value; if (range < 1) { return; } var list = CreateRange(range, character.position); //比list大一圈以保证enemy在范围外一圈时范围内颜色的正常显示。 var detect = CreateRange(range + 1, character.position); //此处创建范围比应有范围大1,正确的显示效果 是在下面 A*检测到路径但距离大于角色mrg的地块不显示 处得到保证。 //检测到敌人时地块不显示,且加入名单。 foreach (var position in detect) { if (CheckEnemy(Detect.DetectObject(position)) == 2) { enemyFloor.Add(position); continue; } //检测到障碍物时地块不显示。后期实现水上行走,跳远,树上行走。 if (DetectObstacle(position)) { continue; } BattleFieldManager.GetInstance().GetFloor(position).SetActive(true); rangeDic.Add(position, BattleFieldManager.GetInstance().GetFloor(position)); } //添加enemyFloor周围的坐标进入容器。 foreach (var floor in enemyFloor) { Vector3 V1 = new Vector3(floor.x - 1, 0, floor.z); Vector3 V2 = new Vector3(floor.x + 1, 0, floor.z); Vector3 V3 = new Vector3(floor.x, 0, floor.z - 1); Vector3 V4 = new Vector3(floor.x, 0, floor.z + 1); TryAddValue(floorAroundEnemy, V1); TryAddValue(floorAroundEnemy, V2); TryAddValue(floorAroundEnemy, V3); TryAddValue(floorAroundEnemy, V4); } var buffer0 = new List <Vector3>(); foreach (var floor in rangeDic) { if (!list.Contains(floor.Key)) { floor.Value.SetActive(false); buffer0.Add(floor.Key); } } foreach (var a in buffer0) { rangeDic.Remove(a); } //A*检测到路径但距离大于角色mrg的地块不显示。A*无法检测到路径的地块不显示。必须第二次遍历,即创建完成,A*寻路才有意义。 //不能迭代时改变或删除Dictionary中的元素。 var buffer = new List <Vector3>(); foreach (var floor in rangeDic) { if ((UseAstar(character.position, floor.Key, range).Count > range + 1) || (floor.Key != character.position && UseAstar(character.position, floor.Key, range).Count == 0)) { floor.Value.SetActive(false); buffer.Add(floor.Key); } } foreach (var a in buffer) { rangeDic.Remove(a); } RecoverColor(); }
public override bool OnUpdate(Transform character) { switch (skillState) { case SkillState.init: if (Init(character)) { skillState = SkillState.waitForInput; } break; case SkillState.waitForInput: if (final) { //角色取出忽略层 UnitManager.GetInstance().units.ForEach(u => u.gameObject.layer = 0); if (Check()) { foreach (var f in BattleFieldManager.GetInstance().floors) { if (f.Value.activeInHierarchy) { f.Value.GetComponent <Floor>().FloorClicked -= Confirm; f.Value.GetComponent <Floor>().FloorExited -= DeleteHoverRange; f.Value.GetComponent <Floor>().FloorHovered -= Focus; } } var player = RoundManager.GetInstance().Players.Find(p => p.playerNumber == SkillManager.GetInstance().skillQueue.Peek().Key.character.GetComponent <Unit>().playerNumber); if (player is HumanPlayer || (player is AIPlayer && ((AIPlayer)player).AI == false)) { ShowConfirm(); } } UnitManager.GetInstance().units.ForEach(u => u.gameObject.layer = 2); final = false; } break; case SkillState.confirm: if (originSkill != null) { //有连续技。连续技第二个技能的InitSkill在AttackSkill的ApplyEffects中进行处理。 originSkill.InitSkill(); } else { //无连续技 InitSkill(); } skillState = SkillState.applyEffect; break; case SkillState.applyEffect: if (ApplyEffects()) { animator.SetInteger("Skill", 0); return(true); } break; case SkillState.reset: return(true); } return(false); }
public override bool OnUpdate(Transform character) { switch (skillState) { case SkillState.init: if (Init(character)) { skillState = SkillState.waitForInput; } break; case SkillState.waitForInput: if (final) { //角色取出忽略层 UnitManager.GetInstance().units.ForEach(u => u.gameObject.layer = 0); if (Check()) { foreach (var f in BattleFieldManager.GetInstance().floors) { if (f.Value.activeInHierarchy) { f.Value.GetComponent <Floor>().FloorClicked -= Confirm; f.Value.GetComponent <Floor>().FloorExited -= DeleteHoverRange; f.Value.GetComponent <Floor>().FloorHovered -= Focus; } } ShowConfirm(); } UnitManager.GetInstance().units.ForEach(u => u.gameObject.layer = 2); final = false; } break; case SkillState.confirm: if (originSkill != null) { originSkill.InitSkill(); } else { InitSkill(); } skillState = SkillState.applyEffect; break; case SkillState.applyEffect: if (ApplyEffects()) { animator.SetInteger("Skill", 0); return(true); } break; case SkillState.reset: return(true); } return(false); }
//正方形去除四角的范围。 List <Vector3> CreateHoverRangeList() { var p = character.position + character.forward * 5; p = new Vector3((int)p.x + 0.5f, 0, (int)p.z + 0.5f); List <Vector3> list = new List <Vector3>(); //这个数组存放每一行(或者是每一列)应有的方块数。 int[] num = new int[2 * hoverRange + 1]; //这个数组应该是奇数个元素个数。 for (int i = 0; i < 2 * hoverRange + 1; i++) { if (i == 0 || i == 2 * hoverRange) { num[i] = 2 * hoverRange - 1; } else { num[i] = 2 * hoverRange + 1; } } //根据这个数组,来创建范围。遍历的两个维度,一个是数组的长度,即行数,另一个是数组每一个值,即每一行应该有的方块数。 for (int i = 0; i < num.Length; i++) { for (int j = 0; j < num[i]; j++) { //根据range、i、j、角色position算出每块地板的坐标。 //中心点为transform.position,个别列有偏移量。 float rX = p.x + (hoverRange - i); float rZ; if (i == 0 || i == num.Length - 1) { rZ = p.z + (hoverRange - j) - 1; } else { rZ = p.z + (hoverRange - j); } if (rX < 1 || rZ < 1 || rX > BattleFieldManager.GetInstance().GridX - 1 || rZ > BattleFieldManager.GetInstance().GridY - 1)//超出边界的不创建 由于A*报数组下标越界(因为要检测一个单元周围的所有单元,而边界单元没有完整的周围单元),所以这里把边界缩小一圈。 { continue; } Vector3 position = new Vector3(rX, p.y, rZ); list.Add(position); } } return(list); }
IEnumerator LoadLevel() { //LoadPrefab var r = Resources.LoadAsync("Prefabs/Level/Level_" + Global.GetInstance().IndexToString(Global.GetInstance().BattleIndex)); yield return(r); //LevelInit var go = Instantiate(r.asset) as GameObject; level = go.transform; level.name = r.asset.name; var rtsCamera = Camera.main.GetComponent <RTSCamera>(); rtsCamera.cameraRange = level.Find("CameraRange").gameObject; rtsCamera.enabled = true; //VectoryCondition vc = level.GetComponent <VectoryCondition>(); //LoadUnits var characterParent = level.Find("Characters"); var spawnPointParent = level.Find("SpawnPoints"); for (int i = 0; i < spawnPointParent.childCount; i++) { var c = Resources.Load("Prefabs/Character/" + spawnPointParent.GetChild(i).name.Substring(0, spawnPointParent.GetChild(i).name.IndexOf('_'))) as GameObject; var cInstance = Instantiate(c, characterParent); cInstance.transform.position = spawnPointParent.GetChild(i).position; cInstance.transform.rotation = spawnPointParent.GetChild(i).rotation; cInstance.GetComponent <CharacterStatus>().playerNumber = int.Parse(spawnPointParent.GetChild(i).name.Substring(spawnPointParent.GetChild(i).name.IndexOf('_') + 1)); cInstance.name = spawnPointParent.GetChild(i).name; } Destroy(spawnPointParent.gameObject); //Units var unitManager = UnitManager.GetInstance(); unitManager.InitUnits(); unitManager.units.ForEach(u => u.GetComponent <Unit>().UnitSelected += UIManager.GetInstance().OnUnitSelected); Units = unitManager.units; //DialogManager DialogManager.GetInstance().enabled = true; //Task var task = GameObject.Find("Canvas").transform.Find("BattlePrepare").Find("Task"); task.Find("TaskTitle").GetComponent <Text>().text = level.Find("TaskTitle").GetComponent <Text>().text; task.Find("TaskContent").GetComponent <Text>().text = level.Find("TaskContent").GetComponent <Text>().text; Destroy(level.Find("TaskTitle").gameObject); Destroy(level.Find("TaskContent").gameObject); BattleFieldManager.GetInstance().BuildFloors(level.GetComponent <LevelInfo>().GridX, level.GetComponent <LevelInfo>().GridY); yield return(StartCoroutine(XMLManager.LoadAsync <CharacterDataBase>(Application.streamingAssetsPath + "/XML/Core/Level/Level_Battle_" + Global.GetInstance().IndexToString(Global.GetInstance().BattleIndex) + ".xml", result => Global.GetInstance().levelCharacterDB = result))); BattleBegin = false; //Players Players = new List <Player>(); playersParent = level.Find("Players"); for (int i = 0; i < playersParent.childCount; i++) { var player = playersParent.GetChild(i).GetComponent <Player>(); if (player != null) { Players.Add(player); } else { Debug.LogError("Invalid object in Players Parent game object"); } } NumberOfPlayers = Players.Count; CurrentPlayerNumber = Players.Min(p => p.playerNumber); yield return(new WaitForSeconds(0.1f)); if (Global.GetInstance().levelCharacterDB != null && Global.GetInstance().levelCharacterDB.characterDataList.Count > 0) { foreach (var characterData in Global.GetInstance().levelCharacterDB.characterDataList) { Global.GetInstance().characterDB.characterDataList.Add(characterData); } } }
public override bool OnUpdate(Transform character) { switch (skillState) { case SkillState.init: if (!isAI) { Init(character); //we need to initial AI character manually } skillState = SkillState.waitForInput; break; case SkillState.waitForInput: if (final) { if (Check()) { if (!isAI) { foreach (var f in BattleFieldManager.GetInstance().floors) { f.Value.GetComponent <Floor>().FloorClicked -= Confirm; f.Value.GetComponent <Floor>().FloorHovered -= Focus; f.Value.GetComponent <Floor>().FloorExited -= RecoverColor; } } path = range.CreatePath(focus); //角色取出忽略层 UnitManager.GetInstance().units.FindAll(u => u.playerNumber == character.GetComponent <Unit>().playerNumber).ForEach(u => BattleFieldManager.GetInstance().GetFloor(u.transform.position).gameObject.layer = 0); UnitManager.GetInstance().units.ForEach(u => u.gameObject.layer = 0); skillState = SkillState.confirm; } else { final = false; } } break; case SkillState.confirm: movement.SetMovement(path, character); skillState = SkillState.applyEffect; break; case SkillState.applyEffect: if (movement.ExcuteMove()) { range.Delete(); if (!isAI) { character.GetComponent <CharacterAction>().SetSkill("SecondAction"); //SecondAction } skillState = SkillState.reset; return(true); } break; case SkillState.reset: return(true); } return(false); }
public override void Reset() { //按照顺序,逆序消除影响。因为每次会Init(),所以不必都Reset。 movement.Reset(); range.Reset(); foreach (var f in BattleFieldManager.GetInstance().floors) { f.Value.GetComponent <Floor>().FloorClicked -= Confirm; f.Value.GetComponent <Floor>().FloorHovered -= Focus; f.Value.GetComponent <Floor>().FloorExited -= RecoverColor; } //角色取出忽略层 UnitManager.GetInstance().units.FindAll(u => u.playerNumber == character.GetComponent <Unit>().playerNumber).ForEach(u => BattleFieldManager.GetInstance().GetFloor(u.transform.position).gameObject.layer = 0); UnitManager.GetInstance().units.ForEach(u => u.gameObject.layer = 0); base.Reset(); }
public override bool Init(Transform character) { this.character = character; range.CreateMoveRange(character); focus = new Vector3(-1, -1, -1); final = false; if (!isAI) { foreach (var f in BattleFieldManager.GetInstance().floors) { if (f.Value.activeInHierarchy) { f.Value.GetComponent <Floor>().FloorClicked += Confirm; f.Value.GetComponent <Floor>().FloorHovered += Focus; f.Value.GetComponent <Floor>().FloorExited += RecoverColor; } } } //角色加入忽略层,方便选取 UnitManager.GetInstance().units.FindAll(u => u.playerNumber == character.GetComponent <Unit>().playerNumber).ForEach(u => BattleFieldManager.GetInstance().GetFloor(u.transform.position).gameObject.layer = 2); UnitManager.GetInstance().units.ForEach(u => u.gameObject.layer = 2); return(true); }
protected List <Vector3> CreateStraightRange(int range, Vector3 p) { List <Vector3> list = new List <Vector3>(); int[] num = new int[2 * range + 1]; for (int i = 0; i < range; i++) { num[i] = 1; num[2 * range - i] = num[i]; } num[range] = 2 * range + 1; //根据这个数组,来创建范围。遍历的两个维度,一个是数组的长度,即行数,另一个是数组每一个值,即每一行应该有的方块数。 for (int i = 0; i < num.Length; i++) { for (int j = 0; j < num[i]; j++) { //根据range、i、j、角色position算出每块地板的坐标。 //中心点为transform.position,每一列应有一个偏移量。 float rX = p.x + (range - i); float rZ; if (i != range) { rZ = p.z + (range - j) - range; } else { rZ = p.z + (range - j); } if (rX < 1 || rZ < 1 || rX > BattleFieldManager.GetInstance().GridX - 1 || rZ > BattleFieldManager.GetInstance().GridY - 1)//超出边界的不创建 由于A*报数组下标越界(因为要检测一个单元周围的所有单元,而边界单元没有完整的周围单元),所以这里把边界缩小一圈。 { continue; } Vector3 position = new Vector3(rX, p.y, rZ); list.Add(position); } } return(list); }
//返回一个列表,包含以p为中心大小为range的菱形范围的所有Vector3。 public static List <Vector3> CreateRange(int range, Vector3 p) { List <Vector3> list = new List <Vector3>(); //这个数组存放每一行(或者是每一列)应有的方块数,例如:如果range = 3,则数组应为{1,3,5,7,5,3,1}。 int[] num = new int[2 * range + 1]; //这个数组应该是奇数个元素个数,并且以中间元素为轴对称。 for (int i = 0; i < range + 1; i++) { num[i] = 2 * i + 1; num[2 * range - i] = num[i]; } //根据这个数组,来创建范围。遍历的两个维度,一个是数组的长度,即行数,另一个是数组每一个值,即每一行应该有的方块数。 for (int i = 0; i < num.Length; i++) { for (int j = 0; j < num[i]; j++) { //根据range、i、j、角色position算出每块地板的坐标。 //中心点为transform.position,每一列应有一个偏移量,使最终显示结果为菱形而不是三角形。 float rX = p.x + (range - i); float rZ = p.z + (range - j) - Mathf.Abs(range - i); if (rX < 1 || rZ < 1 || rX > BattleFieldManager.GetInstance().GridX - 1 || rZ > BattleFieldManager.GetInstance().GridY - 1)//超出边界的不创建 由于A*报数组下标越界(因为要检测一个单元周围的所有单元,而边界单元没有完整的周围单元),所以这里把边界缩小一圈。 { continue; } Vector3 position = new Vector3(rX, p.y, rZ); list.Add(position); } } return(list); }
public void CreateStraightSkillRange(int range, Transform character) { this.character = character; startRotation = character.rotation; var list = CreateStraightRange(range, character.position); foreach (var position in list) { if (CheckEnemy(Detect.DetectObject(position))) { enemyFloor.Add(position); } else if (DetectObstacle(position)) { obstacleFloor.Add(position); continue; } BattleFieldManager.GetInstance().GetFloor(position).SetActive(true); rangeDic.Add(position, BattleFieldManager.GetInstance().GetFloor(position)); } //直线施法的障碍物遮挡效果 var buffer = new Dictionary <Vector3, GameObject>(); var listBuffer = new List <Vector3>(); foreach (var a in enemyFloor) { listBuffer.Add(a); } foreach (var a in obstacleFloor) { if (!listBuffer.Contains(a)) { listBuffer.Add(a); } } foreach (var floor in rangeDic.Values) { foreach (var f in listBuffer) { if (floor.activeInHierarchy) { var dis = floor.transform.position - character.position; var eDis = f - character.position; //两向量方向相同,且dis距离大于eDis,则不显示。即被遮挡住。 if ((dis.normalized == eDis.normalized) && (dis.magnitude > eDis.magnitude)) { BattleFieldManager.GetInstance().GetFloor(floor.transform.position).SetActive(false); buffer.Add(floor.transform.position, floor); } } } } foreach (var pair in buffer) { rangeDic.Remove(pair.Key); } }