[Unity官⽅教程]Tanks!单机双⼈坦克⼤战源码和素材
这是Unity官⽅案例Tanks的素材,读者可以⾃⾏取阅。
链接:pan.baidu/s/1PSAZeT5zQOQJXNxzP9qs1A
提取码:a57u
⽂章⽬录
前⾔
本篇⽂章是我在观看了官⽅教程后写的脚本,相较于官⽅的更为详细,⽅便你们拿来直接查看引⽤。⽽且是适⽤于新版本的Unity。我这⼀版本的Unity是Version 2019.2.9f1 Persional。
建议多阅读观看官⽹的⽂档和教程,⼀⽅⾯他们的代码更加的规范,另⼀⽅⾯游戏开发的思想要更加的好。⼀个很明显的区别在于,官⽅的代码,每个模块之间相互独⽴,各司其职缺⼀不可。但⼜不会在⼀个脚本⾥塞⼊过多的内容显得冗杂多余,整体上层次分明,架构清楚。各个类之间⾼内聚,低耦合。⽐国内所谓的⼀些学院教的要好得多,解释的也更加的清楚。
个⼈建议不要开倍速⼀点点看完,适应⼀下⽼师的语速,⽽不要知其然不知其所以然。那么,废话不多说,直接上代码。英语⽔平有限,注释能看懂就⾏,还望见谅。
脚本
GameManager类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
// Properties
public int m_NumRoundsToWin =5;// number of rounds per start
public float m_StartDelay =3f;// time delay ecah start
public float m_EndDelay =3f;// time delay each end
private int m_RoundNumber;// round in which you are
// Reference
public CameraContorller m_CameraContorl;
public Text m_MessageText;
public GameObject m_TankPrefab;
public TankManager[] m_Tanks;
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();
StartCoroutine(GameLoop());
}
private void SpawnAllTanks()
{
/
/ Spawn all the tanks for player, set their numbers from 1 to 2, and then call the function SetUp() to draw color for tanks.
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].ation);
m_Tanks[i].m_PlayerNumber = i +1;
m_Tanks[i].SetUp();
}
}
private void SetCameraTargets()
{
// Assign all the tank's transform to the GameraControl script.
Transform[] targets =new Transform[m_Tanks.Length];
for(int i =0; i < targets.Length;++i)
{
targets[i]= m_Tanks[i].ansform;
}
m_CameraContorl.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()
{
// When the game firstly starts or back to the scene(0) again, we should reset all tanks.
// And then, we disable all tanks' control so that the player couldn't contorl them.
// At the same time, we set the camera to the right position and size that calculated by the function in the CameraControl script.
// Finally, we show the text "Round" and we wait for a while so that it won't flash by.
ResetAllTanks();
DisableTankControl();
m_CameraContorl.SetStartPositionAndSize();
m_RoundNumber++;// plus 1 to the round count
="ROUND "+ m_RoundNumber;
yield return m_StartWait;
private IEnumerator RoundPlaying()
{
// Ok now, we need to give the palyers control of their tank, or they will be angry.
// So, we enable all tanks' control, and change the text to null.
// You don't expect a big line blocking the palyers' view.
// When two players fight out a winner, we can return the funcion.
// Of course, their is nothing we could return.
EnableTankControl();
=string.Empty;
while(!OneTankLeft())
{
yield return null;
}
}
private IEnumerator RoundEnding()
{
// A winner came out. Winner whould like to run around for celebrating, but we don't think is a wise move.
// So we disable tanks' control again, and we set winner for this round to null.
// Because it still stores the reference of the winner of the last round.
// And then, we need to find the reference of the winner of this round and we judge wether he is the game winner.
// Again we show some "text" and wait for a while, then we get into the next round or start game again.
DisableTankControl();
m_RoundWinner =null;
m_RoundWinner =GetRoundWinner();
if(m_RoundWinner !=null)
m_RoundWinner.m_Wins++;
m_GameWinner =GetGameWinner();
string message =EndMessage();
= message;
yield return m_EndWait;
}
private bool OneTankLeft()
{
// Determine if any tanks are dead.
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()
{
// Go through all the tanks, if find a TankManager who's Instance is active, then return it, or else return null.
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()
{
// Go through all the tanks, if find a TankManager who's m_Wins is equal to 5, then return it, or else return null.
for(int i =0; i < m_Tanks.Length;++i)
{
unity 教程if(m_Tanks[i].m_Wins == m_NumRoundsToWin)
return m_Tanks[i];
}
return null;
}
private string EndMessage()
{
string message ="DARW!";
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 +" WIN THE GAME!";
return message;
}
private void ResetAllTanks()
{
for(int i =0; i < m_Tanks.Length;++i)
{
m_Tanks[i].Reset();
}
}
private void DisableTankControl()
{
for(int i =0; i < m_Tanks.Length;++i)
{
m_Tanks[i].DisableTankControl();
}
}
private void EnableTankControl()
{
for(int i =0; i < m_Tanks.Length;++i)
{
m_Tanks[i].EnableTankControl();
}
}
}
TankManager类
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class TankManager
{
// Properties
[HideInInspector]public int m_PlayerNumber;
[HideInInspector]public int m_Wins;
[HideInInspector]public string m_ColoredPlayerText;
// Reference
public Color m_PlayerColor;
public Transform m_SpawnPoint;
private TankMovement m_Movement;
private TankShooting m_Shooting;
private GameObject m_CanvasGameObject;
[HideInInspector]public GameObject m_Instance;
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].lor = m_PlayerColor;
}
}
public void DisableTankControl()
{
// Turn off the script and turn off the canvas.
abled =false;
abled =false;
m_CanvasGameObject.SetActive(false);
}
public void EnableTankControl()
{
// Turn on the script and turn on the canvas.
abled =true;
abled =true;
m_CanvasGameObject.SetActive(true);
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。