您的位置:首页 > 移动开发 > Unity3D

Tanks Unity Tutorial - Phase 7 Managers

2017-05-09 16:41 816 查看
Youtube地址 :https://www.youtube.com/watch?v=M4bH9lWOJE4

主要理解 协程的应用.

注意 class  TankManager的 [Serializable]属性,才能显示到 Inspector上面。

[HideInInspector] 表示的属性,只能脚本调用。





using System;
using UnityEngine;

[Serializable]
public class TankManager
{
public Color m_PlayerColor;
public Transform m_SpawnPoint;
[HideInInspector] public int m_PlayerNumber;
[HideInInspector] public string m_ColoredPlayerText;
[HideInInspector] public GameObject m_Instance;
[HideInInspector] public int m_Wins;

private TankMovement m_Movement;
private TankShooting m_Shooting;
private GameObject m_CanvasGameObject;

public void Setup()
{
m_Movement = m_Instance.GetComponent<TankMovement>();
m_Shooting = m_Instance.GetComponent<TankShooting>();
m_CanvasGameObject = m_Instance.GetComponentInChildren<Canvas>().gameObject;

m_Movement.m_PlayerNumber = m_PlayerNumber;
m_Shooting.m_PlayerNumber = m_PlayerNumber;

m_ColoredPlayerText = "<color=#" + ColorUtility.ToHtmlStringRGB(m_PlayerColor) + ">PLAYER " + m_PlayerNumber + "</color>";

MeshRenderer[] renderers = m_Instance.GetComponentsInChildren<MeshRenderer>();

for (int i = 0; i < renderers.Length; i++)
{
renderers[i].material.color = m_PlayerColor;
}
}

public void DisableControl()
{
m_Movement.enabled = false;
m_Shooting.enabled = false;

m_CanvasGameObject.SetActive(false);
}

public void EnableControl()
{
m_Movement.enabled = true;
m_Shooting.enabled = true;

m_CanvasGameObject.SetActive(true);
}

public void Reset()
{
m_Instance.transform.position = m_SpawnPoint.position;
m_Instance.transform.rotation = m_SpawnPoint.rotation;

m_Instance.SetActive(false);
m_Instance.SetActive(true);
}
}


GameManager中 应用了协程 Coroutines 控制游戏流程:





using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
public int m_NumRoundsToWin = 5;
public float m_StartDelay = 3f;
public float m_EndDelay = 3f;
public CameraControl m_CameraControl;
public Text m_MessageText;
public GameObject m_TankPrefab;
public TankManager[] m_Tanks;

private int m_RoundNumber;
private WaitForSeconds m_StartWait;
private WaitForSeconds m_EndWait;
private TankManager m_RoundWinner;
private TankManager m_GameWinner;

private void Start()
{
m_StartWait = new WaitForSeconds(m_StartDelay);
m_EndWait = new WaitForSeconds(m_EndDelay);

SpawnAllTanks();
SetCameraTargets();

StartCoroutine(GameLoop());
}

private void SpawnAllTanks()
{
for (int i = 0; i < m_Tanks.Length; i++)
{
m_Tanks[i].m_Instance =
Instantiate(m_TankPrefab, m_Tanks[i].m_SpawnPoint.position, m_Tanks[i].m_SpawnPoint.rotation) as GameObject;
m_Tanks[i].m_PlayerNumber = i + 1;
m_Tanks[i].Setup();
}
}

private void SetCameraTargets()
{
Transform[] targets = new Transform[m_Tanks.Length];

for (int i = 0; i < targets.Length; i++)
{
targets[i] = m_Tanks[i].m_Instance.transform;
}

m_CameraControl.m_Targets = targets;
}

private IEnumerator GameLoop()
{
yield return StartCoroutine(RoundStarting());
yield return StartCoroutine(RoundPlaying());
yield return StartCoroutine(RoundEnding());

if (m_GameWinner != null)
{
SceneManager.LoadScene(0);
}
else
{
StartCoroutine(GameLoop());
}
}

private IEnumerator RoundStarting()
{
// As soon as the round starts reset the tanks and make sure they can't move.
ResetAllTanks();
DisableTankControl();

// Snap the camera's zoom and position to something appropriate for the reset tanks.
m_CameraControl.SetStartPositionAndSize();

// Increment the round number and display text showing the players what round it is.
m_RoundNumber++;
m_MessageText.text = "ROUND " + m_RoundNumber;

// Wait for the specified length of time until yielding control back to the game loop.
yield return m_StartWait;
}

private IEnumerator RoundPlaying()
{
EnableTankControl ();

// Clear the text from the screen.
m_MessageText.text = string.Empty;

// While there is not one tank left...
while (!OneTankLeft())
{
// ... return on the next frame.
yield return null;
}
}

private IEnumerator RoundEnding()
{
// Stop tanks from moving.
DisableTankControl();

// Clear the winner from the previous round.
m_RoundWinner = null;

// See if there is a winner now the round is over.
m_RoundWinner = GetRoundWinner();

// If there is a winner, increment their score.
if (m_RoundWinner != null)
m_RoundWinner.m_Wins++;

// Now the winner's score has been incremented, see if someone has one the game.
m_GameWinner = GetGameWinner();

// Get a message based on the scores and whether or not there is a game winner and display it.
string message = EndMessage();
m_MessageText.text = message;

// Wait for the specified length of time until yielding control back to the game loop.
yield return m_EndWait;
}

private bool OneTankLeft()
{
int numTanksLeft = 0;

for (int i = 0; i < m_Tanks.Length; i++)
{
if (m_Tanks[i].m_Instance.activeSelf)
numTanksLeft++;
}

return numTanksLeft <= 1;
}

private TankManager GetRoundWinner()
{
for (int i = 0; i < m_Tanks.Length; i++)
{
if (m_Tanks[i].m_Instance.activeSelf)
return m_Tanks[i];
}

return null;
}

private TankManager GetGameWinner()
{
for (int i = 0; i < m_Tanks.Length; i++)
{
if (m_Tanks[i].m_Wins == m_NumRoundsToWin)
return m_Tanks[i];
}

return null;
}

private string EndMessage()
{
string message = "DRAW!";

if (m_RoundWinner != null)
message = m_RoundWinner.m_ColoredPlayerText + " WINS THE ROUND!";

message += "\n\n\n\n";

for (int i = 0; i < m_Tanks.Length; i++)
{
message += m_Tanks[i].m_ColoredPlayerText + ": " + m_Tanks[i].m_Wins + " WINS\n";
}

if (m_GameWinner != null)
message = m_GameWinner.m_ColoredPlayerText + " WINS THE GAME!";

return message;
}

private void ResetAllTanks()
{
for (int i = 0; i < m_Tanks.Length; i++)
{
m_Tanks[i].Reset();
}
}

private void EnableTankControl()
{
for (int i = 0; i < m_Tanks.Length; i++)
{
m_Tanks[i].EnableControl();
}
}

private void DisableTankControl()
{
for (int i = 0; i < m_Tanks.Length; i++)
{
m_Tanks[i].DisableControl();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: