Tanks!Tutorial 学习
Posted 志不强者智不达
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tanks!Tutorial 学习相关的知识,希望对你有一定的参考价值。
using UnityEngine; namespace Complete { public class CameraControl : MonoBehaviour { /// <summary> /// 相机重新聚焦的时间 /// </summary> public float m_DampTime = 0.2f; /// <summary> /// /// </summary> public float m_ScreenEdgeBuffer = 4f; /// <summary> /// 正交模式吓的最小视口大小 /// </summary> public float m_MinSize = 6.5f; /// <summary> /// 相机需要保卫的目标数组 /// </summary> [HideInInspector] public Transform[] m_Targets; /// <summary> /// 相机 /// </summary> private Camera m_Camera; /// <summary> /// 变焦速度 /// </summary> private float m_ZoomSpeed; /// <summary> /// 移动速度 /// </summary> private Vector3 m_MoveVelocity; /// <summary> /// 目标位置 /// </summary> private Vector3 m_DesiredPosition; private void Awake () { m_Camera = GetComponentInChildren<Camera> (); } private void FixedUpdate () { Move (); Zoom (); } /// <summary> /// 移动 /// </summary> private void Move () { FindAveragePosition (); transform.position = Vector3.SmoothDamp(transform.position, m_DesiredPosition, ref m_MoveVelocity, m_DampTime); } /// <summary> /// 查找所有目标的中间位置 /// </summary> private void FindAveragePosition () { Vector3 averagePos = new Vector3 (); int numTargets = 0; for (int i = 0; i < m_Targets.Length; i++) { if (!m_Targets[i].gameObject.activeSelf) continue; averagePos += m_Targets[i].position; numTargets++; } if (numTargets > 0) averagePos /= numTargets; averagePos.y = transform.position.y; m_DesiredPosition = averagePos; } /// <summary> /// 变焦 /// </summary> private void Zoom () { float requiredSize = FindRequiredSize(); m_Camera.orthographicSize = Mathf.SmoothDamp (m_Camera.orthographicSize, requiredSize, ref m_ZoomSpeed, m_DampTime); } /// <summary> /// 查找需要的视口大小 /// </summary> /// <returns></returns> private float FindRequiredSize () { Vector3 desiredLocalPos = transform.InverseTransformPoint(m_DesiredPosition); float size = 0f; for (int i = 0; i < m_Targets.Length; i++) { if (!m_Targets[i].gameObject.activeSelf) continue; Vector3 targetLocalPos = transform.InverseTransformPoint(m_Targets[i].position); Vector3 desiredPosToTarget = targetLocalPos - desiredLocalPos; size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.y)); size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.x) / m_Camera.aspect); } size += m_ScreenEdgeBuffer; size = Mathf.Max (size, m_MinSize); return size; } /// <summary> /// 设置相机的起始位置和大小 /// </summary> public void SetStartPositionAndSize () { FindAveragePosition (); transform.position = m_DesiredPosition; m_Camera.orthographicSize = FindRequiredSize (); } } }
using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; namespace Complete { public class GameManager : MonoBehaviour { /// <summary> /// 要赢得游戏的局数 /// </summary> public int m_NumRoundsToWin = 5; /// <summary> /// 从回合准备转换到回合开始的时间 /// </summary> public float m_StartDelay = 3f; /// <summary> /// 从回合开始转换到回合结束的时间 /// </summary> public float m_EndDelay = 3f; /// <summary> /// 摄像机控制 /// </summary> public CameraControl m_CameraControl; /// <summary> /// 消息文本 /// </summary> public Text m_MessageText; /// <summary> /// 坦克预设 /// </summary> public GameObject m_TankPrefab; /// <summary> /// 坦克管理数组 /// </summary> public TankManager[] m_Tanks; /// <summary> /// 当前回合数 /// </summary> private int m_RoundNumber; /// <summary> /// 回合开始后的等待时间 /// </summary> private WaitForSeconds m_StartWait; /// <summary> /// 回合结束后的等待时间 /// </summary> private WaitForSeconds m_EndWait; /// <summary> /// 回合获胜者 /// </summary> private TankManager m_RoundWinner; /// <summary> /// 游戏获胜者 /// </summary> private TankManager m_GameWinner; private void Start() { m_StartWait = new WaitForSeconds (m_StartDelay); m_EndWait = new WaitForSeconds (m_EndDelay); SpawnAllTanks(); SetCameraTargets(); //开启游戏主循环协程 StartCoroutine (GameLoop ()); } /// <summary> /// 孵化所有坦克 /// </summary> 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(); } } /// <summary> /// 设置相机目标 /// </summary> 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; } /// <summary> /// 游戏循环协程 /// </summary> /// <returns></returns> 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 ()); } } /// <summary> /// 回合准备协程 /// </summary> /// <returns></returns> private IEnumerator RoundStarting () { ResetAllTanks (); DisableTankControl (); m_CameraControl.SetStartPositionAndSize (); m_RoundNumber++; m_MessageText.text = "ROUND " + m_RoundNumber; yield return m_StartWait; } /// <summary> /// 回合开始协程 /// </summary> /// <returns></returns> private IEnumerator RoundPlaying () { EnableTankControl (); m_MessageText.text = string.Empty; while (!OneTankLeft()) { yield return null; } } /// <summary> /// 游戏结束协程 /// </summary> /// <returns></returns> private IEnumerator RoundEnding () { DisableTankControl (); m_RoundWinner = null; m_RoundWinner = GetRoundWinner (); if (m_RoundWinner != null) m_RoundWinner.m_Wins++; m_GameWinner = GetGameWinner (); string message = EndMessage (); m_MessageText.text = message; yield return m_EndWait; } /// <summary> /// 检查激活的坦克数量是否小于等于1,用来设置这局游戏是否结束 /// </summary> /// <returns></returns> 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; } /// <summary> /// 获取每局的胜者 /// </summary> /// <returns></returns> 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; } /// <summary> /// 获取游戏的胜者 /// </summary> /// <returns></returns> 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; } /// <summary> /// 每回合结束或游戏结束的消息 /// </summary> /// <returns></returns> 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; } /// <summary> /// 重置所有坦克 /// </summary> private void ResetAllTanks() { for (int i = 0; i < m_Tanks.Length; i++) { m_Tanks[i].Reset(); } } /// <summary> /// 开启所有坦克的控制 /// </summary> private void EnableTankControl() { for (int i = 0; i < m_Tanks.Length; i++) { m_Tanks[i].EnableControl(); } } /// <summary> /// 关闭所有坦克的控制 /// </summary> private void DisableTankControl() { for (int i = 0; i < m_Tanks.Length; i++) { m_Tanks[i].DisableControl(); } } } }
using System; using UnityEngine; namespace Complete { [Serializable] public class TankManager { /// <summary> /// 坦克颜色 /// </summary> public Color m_PlayerColor; /// <summary> /// 坦克孵化点 /// </summary> public Transform m_SpawnPoint; /// <summary> /// 玩家编号 /// </summary> [HideInInspector] public int m_PlayerNumber; /// <summary> /// 包含颜色的代表玩家的字符串 /// </summary> [HideInInspector] public string m_ColoredPlayerText; /// <summary> /// 坦克实例的引用 /// </summary> [HideInInspector] public GameObject m_Instance; /// <summary> /// 玩家已赢得的局数 /// </summary> [HideInInspector] public int m_Wins; /// <summary> /// 坦克移动 /// </summary> private TankMovement m_Movement; /// <summary> /// 坦克射击 /// </summary> private TankShooting m_Shooting; /// <summary> /// 坦克游戏物体上的canvas /// </summary> private GameObject m_CanvasGameObject; /// <summary> /// 设置坦克 /// </summary> 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; } } /// <summary> /// 关闭控制 /// </summary> public void DisableControl () { m_Movement.enabled = false; m_Shooting.enabled = false; m_CanvasGameObject.SetActive (false); } /// <summary> /// 开启控制 /// </summary> public void EnableControl () { m_Movement.enabled = true; m_Shooting.enabled = true; m_CanvasGameObject.SetActive (true); } /// <summary> /// 重置坦克状态 /// </summary> 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); } } }
using UnityEngine; using UnityEngine.UI; namespace Complete { /// <summary> /// 坦克生命 /// </summary> public class TankHealth : MonoBehaviour { /// <summary> /// 初始坦克生命 /// </summary> public float m_StartingHealth = 100f; /// <summary> /// 血量滑动条 /// </summary> public Slider m_Slider; /// <summary> /// 血量滑动条的图片 /// </summary> public Image m_FillImage; /// <summary> /// 坦克满血的滑动条颜色 /// </summary> public Color m_FullHealthColor = Color.green; /// <summary> /// 坦克没血的滑动条颜色 /// </summary> public Color m_ZeroHealthColor = Color.red; /// <summary> /// 坦克爆炸的预设 /// </summary> public GameObject m_ExplosionPrefab; /// <summary> /// 坦克爆炸的音效 /// </summary> private Audiosource m_ExplosionAudio; /// <summary> /// 坦克爆炸的粒子系统 /// </summary> private ParticleSystem m_ExplosionParticles; /// <summary> /// 坦克当前的血量 /// </summary> private float m_CurrentHealth; /// <summary> /// 坦克是否死亡 /// </summary> private bool m_Dead; private void Awake () { //实例化爆炸预设并获取爆炸粒子系统的引用 m_ExplosionParticles = Instantiate (m_ExplosionPrefab).GetComponent<ParticleSystem> (); //获取爆炸的音效 m_ExplosionAudio = m_ExplosionParticles.GetComponent<AudioSource> (); //禁用爆炸粒子系统 m_ExplosionParticles.gameObject.SetActive (false); } private void OnEnable() { //设置当前血量为起始血量 m_CurrentHealth = m_StartingHealth; //设置死亡标志位为false m_Dead = false; //修改血量UI SetHealthUI(); } /// <summary> /// 坦克受到伤害 /// </summary> /// <param name="amount"></param> public void TakeDamage (float amount) { //修改当前血量 m_CurrentHealth -= amount; //修改血量UI SetHealthUI (); //如果死亡,当前血量<=0 if (m_CurrentHealth <= 0f && !m_Dead) { OnDeath (); } } /// <summary> /// 设置坦克血量UI /// </summary> private void SetHealthUI () { //设置滑动条的值为当前血量 m_Slider.value = m_CurrentHealth; //根据当前血量和起始血量的比值设置坦克的滑动条血量的颜色 m_FillImage.color = Color.Lerp (m_ZeroHealthColor, m_FullHealthColor, m_CurrentHealth / m_StartingHealth); } /// <summary> /// 坦克死亡 /// </summary> private void OnDeath () { 以上是关于Tanks!Tutorial 学习的主要内容,如果未能解决你的问题,请参考以下文章unity 教程Tanks中的Transform.InverseTransformPoint理解
Azure 机器人微软Azure Bot 编辑器系列 : 机器人/用户提问回答模式,机器人从API获取响应并组织答案 (The Bot Framework Composer tutorial(代码片段