当我们准备好了所有的模型 ,Prefab,音效,还有各个Script.
最终我们面临的问题 ,就是如何去将它们调动起来!
我们需要两样东西 :
1.管理每一个坦克的TankManager
2.管理游戏流程的 GameManager
接着我们就发现 :
GameManager 需要与坦克数量同等的 TankManager 而由TankManager控制Tank的生成状态(Active)计分
实现就不是很难了,因为下午那么长,所以我准备写上所有的注释。
1 //using UnityEngine.SceneManagement; 2 using UnityEngine.UI; 3 4 public class GameManager : MonoBehaviour 5 { 6 public int m_NumRoundsToWin = 5; //需要获胜多少场才算赢 7 public float m_StartDelay = 3f; //启动界面维持时间 8 public float m_EndDelay = 3f; //结束界面维持时间 9 public CameraControl m_CameraControl; //控制摄像机 10 public Text m_MessageText; //页面消息的UI组件 (用于展示 ROUND?? 和 胜负情况 的Text) 11 public GameObject m_TankPrefab; //实例化一个tank所需要的模型 12 public TankManager[] m_Tanks; //坦克们的妈妈桑组成的居委会 13 14 15 private int m_RoundNumber; //场次 16 private WaitForSeconds m_StartWait; //根据m_StartDelay的数值来生成的一个 延时对象 17 private WaitForSeconds m_EndWait; //根据m_EndDelay的数值来生成的一个 延时对象 18 private TankManager m_RoundWinner; //每局胜者 记录仪 19 private TankManager m_GameWinner; //最终胜者 记录仪 20 21 22 private void Start() 23 { 24 m_StartWait = new WaitForSeconds(m_StartDelay); //根据m_StartDelay的数值来生成的一个 延时对象 25 m_EndWait = new WaitForSeconds(m_EndDelay);//根据m_EndDelay的数值来生成的一个 延时对象 26 27 SpawnAllTanks(); //生成所有坦克 28 SetCameraTargets(); //为摄像机 设定好 追踪目标 29 30 StartCoroutine(GameLoop()); //开启游戏流程 31 } 32 33 34 private void SpawnAllTanks() //那么如何生成所有的坦克呢?? 35 { 36 for (int i = 0; i < m_Tanks.Length; i++) //一个麻麻一个儿子 37 { 38 m_Tanks[i].m_Instance = 39 Instantiate(m_TankPrefab, m_Tanks[i].m_SpawnPoint.position, m_Tanks[i].m_SpawnPoint.rotation) as GameObject;//为该麻麻在设定好的出生点生一个儿子 40 m_Tanks[i].m_PlayerNumber = i + 1;//并给小孩贴上正确的标号 41 m_Tanks[i].Setup(); //坦克,组装! 42 } 43 } 44 45 46 private void SetCameraTargets() //接下来学习一下 怎么告诉摄像机追踪目标 47 { 48 Transform[] targets = new Transform[m_Tanks.Length]; //首先告诉摄像机 有几个目标 49 50 for (int i = 0; i < targets.Length; i++) 51 { 52 targets[i] = m_Tanks[i].m_Instance.transform; //把每个目标的transform告诉它 53 } 54 55 m_CameraControl.m_Targets = targets; 56 } 57 58 59 private IEnumerator GameLoop() 60 { 61 yield return StartCoroutine(RoundStarting()); //游戏初始化阶段 62 yield return StartCoroutine(RoundPlaying()); //游戏进行阶段 63 yield return StartCoroutine(RoundEnding()); //游戏收尾阶段 64 65 if (m_GameWinner != null) 66 { 67 Application.LoadLevel (Application.loadedLevel); //如果有最终胜者,那就 68 } 69 else 70 { 71 StartCoroutine(GameLoop()); 72 } 73 } 74 75 76 private IEnumerator RoundStarting() 77 { 78 ResetAllTanks (); //重置所有坦克 79 DisableTankControl (); //不允许玩家控制 80 m_CameraControl.SetStartPositionAndSize (); //设置好摄像机的位置 81 m_RoundNumber++; //场次+1 82 m_MessageText.text = "Round " + m_RoundNumber; 83 yield return m_StartWait; //让Text飞一会 84 } 85 86 87 private IEnumerator RoundPlaying() 88 { 89 EnableTankControl (); //允许玩家控制 90 m_MessageText.text = string.Empty; //Text“消失” 91 while (!OneTankLeft ()) { 92 yield return null; //除非只剩下一个玩家,否则一直停留在游戏阶段 93 } 94 } 95 96 97 private IEnumerator RoundEnding() 98 { 99 DisableTankControl (); //不允许玩家控制 100 // Clear the winner from the previous round. 101 m_RoundWinner = null; //清除上次数据 102 m_RoundWinner = GetRoundWinner (); //获取胜者 103 if (m_RoundWinner != null) { 104 m_RoundWinner.m_Wins++; //胜者,积分+1 105 } 106 m_GameWinner = GetGameWinner (); //看看有没有玩家满足获胜条件 107 m_MessageText.text = EndMessage (); //发布战斗结果 108 109 yield return m_EndWait; 110 } 111 112 113 private bool OneTankLeft() 114 { 115 int numTanksLeft = 0; 116 117 for (int i = 0; i < m_Tanks.Length; i++) 118 { 119 if (m_Tanks[i].m_Instance.activeSelf) //存活着的才算数!! 120 numTanksLeft++; 121 } 122 123 return numTanksLeft <= 1; 124 } 125 126 127 private TankManager GetRoundWinner() 128 { 129 for (int i = 0; i < m_Tanks.Length; i++) 130 { 131 if (m_Tanks[i].m_Instance.activeSelf) 132 return m_Tanks[i]; //存活着的才算数!! 133 } 134 135 return null; 136 } 137 138 139 private TankManager GetGameWinner() 140 { 141 for (int i = 0; i < m_Tanks.Length; i++) 142 { 143 if (m_Tanks[i].m_Wins == m_NumRoundsToWin) //满足设定获胜场次的才算赢 144 return m_Tanks[i]; 145 } 146 147 return null; 148 } 149 150 151 private string EndMessage() 152 { 153 string message = "DRAW!"; //默认信息 154 155 if (m_RoundWinner != null) 156 message = m_RoundWinner.m_ColoredPlayerText + " WINS THE ROUND!"; 157 158 message += " "; 159 160 for (int i = 0; i < m_Tanks.Length; i++) 161 { 162 message += m_Tanks[i].m_ColoredPlayerText + ": " + m_Tanks[i].m_Wins + " WINS "; 163 } 164 165 if (m_GameWinner != null) 166 message = m_GameWinner.m_ColoredPlayerText + " WINS THE GAME!"; 167 168 return message; 169 } 170 171 172 private void ResetAllTanks() 173 { 174 for (int i = 0; i < m_Tanks.Length; i++) 175 { 176 m_Tanks[i].Reset(); 177 } 178 } 179 180 181 private void EnableTankControl() 182 { 183 for (int i = 0; i < m_Tanks.Length; i++) 184 { 185 m_Tanks[i].EnableControl(); 186 } 187 } 188 189 190 private void DisableTankControl() 191 { 192 for (int i = 0; i < m_Tanks.Length; i++) 193 { 194 m_Tanks[i].DisableControl(); 195 } 196 } 197 }
1 [Serializable] 2 public class TankManager 3 { 4 public Color m_PlayerColor; //坦克的颜色 5 public Transform m_SpawnPoint; //坦克出生点 6 [HideInInspector] public int m_PlayerNumber; //坦克编号 7 [HideInInspector] public string m_ColoredPlayerText; //用于展示战果时的文字标识 8 [HideInInspector] public GameObject m_Instance; //坦克 9 [HideInInspector] public int m_Wins; //分数 10 11 12 private TankMovement m_Movement; //坦克移动 代码 13 private TankShooting m_Shooting; //坦克射击 代码 14 private GameObject m_CanvasGameObject; //坦克血条所处的画布 15 16 17 public void Setup() 18 { 19 m_Movement = m_Instance.GetComponent<TankMovement>(); // 20 m_Shooting = m_Instance.GetComponent<TankShooting>(); // 21 m_CanvasGameObject = m_Instance.GetComponentInChildren<Canvas>().gameObject;//获取实例 22 23 m_Movement.m_PlayerNumber = m_PlayerNumber; //设定好独特编号 24 m_Shooting.m_PlayerNumber = m_PlayerNumber; //以便准确获取输入 25 26 m_ColoredPlayerText = "<color=#" + ColorUtility.ToHtmlStringRGB(m_PlayerColor) + ">PLAYER " + m_PlayerNumber + "</color>"; //设置 好 Player x 的文字,字体颜色为坦克颜色 27 28 MeshRenderer[] renderers = m_Instance.GetComponentsInChildren<MeshRenderer>(); //MeshRenderer是用于渲染3D对象的组件 29 30 for (int i = 0; i < renderers.Length; i++) 31 { 32 renderers[i].material.color = m_PlayerColor; //利用这一组件 , 给坦克刷颜色 33 } 34 } 35 36 37 public void DisableControl() 38 { 39 m_Movement.enabled = false; //设定代码不可用 40 m_Shooting.enabled = false; //设定代码不可用 41 42 m_CanvasGameObject.SetActive(false); //设定画布不可用 43 } 44 45 46 public void EnableControl() 47 { 48 m_Movement.enabled = true; //设定代码可用 49 m_Shooting.enabled = true; //设定代码可用 50 51 m_CanvasGameObject.SetActive(true); //设定画布可用 52 } 53 54 55 public void Reset() 56 { 57 m_Instance.transform.position = m_SpawnPoint.position; //设定位置回出生点 58 m_Instance.transform.rotation = m_SpawnPoint.rotation; //设定转向回出生转向 59 60 m_Instance.SetActive(false); //坦克得消失后 61 m_Instance.SetActive(true); //再出现,才能使数据生效 62 63 } 64 }