版权声明:转载请注明出处!不注明也无所谓,嘿嘿。 https://blog.csdn.net/qq_15020543/article/details/82909186
为了方便开发,我们把GameController做成一个单例。
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
using UnityEngine.UI;
public class Done_GameController : MonoBehaviour
{
private static Done_GameController instance;
public GameObject[] hazards;
public GameObject[] UIPanels;//储存三个UIPanel
public Vector3 spawnValues;
public int hazardCount;
public float spawnWait;
public float startWait;
public float waveWait;
public bool gameOver = false;
public int level = 1;
public int score = 0;
public int loadCount = 1;
public static Done_GameController Instance
{
get
{
return instance;
}
set
{
instance = value;
}
}
private void Awake()
{
Instance = this;
UIPanels[0].SetActive(true);
}
public void StartIEnumerator()
{
StartCoroutine(SpawnWaves());
}
IEnumerator SpawnWaves ()
{
yield return new WaitForSeconds (startWait);
while (true)
{
for (int i = 0; i < hazardCount; i++)
{
GameObject hazard = hazards [Random.Range (0, hazards.Length)];
Vector3 spawnPosition = new Vector3 (Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate (hazard, spawnPosition, spawnRotation);
yield return new WaitForSeconds (spawnWait);
}
yield return new WaitForSeconds (waveWait);
if (gameOver)
{
break;
}
}
}
public void SetPanelInActive(int index)
{
UIPanels[index].SetActive(false);
}
public void SetPanelActive(int index)
{
UIPanels[index].SetActive(true);
}
}
给GameOverPanel挂载一个脚本
给GamePanel挂载一个脚本
给StartPanel挂载一个脚本
我们再开始做准备工作,将所有的游戏物体加上碰撞器,并且勾选Is Trigger.
改写
DestoryByContact
using UnityEngine;
using System.Collections;
public class Done_DestroyByContact : MonoBehaviour
{
public GameObject explosion;
public GameObject playerExplosion;
void OnTriggerEnter (Collider other)
{
switch (other.tag)
{
case "PlayerAttack":
if(gameObject.tag=="Enemy")
{
Instantiate(explosion, other.transform.position, other.transform.rotation);
Done_GameController.Instance.score += 100;
}
else if(gameObject.tag=="Stone")
{
Instantiate(explosion, other.transform.position, other.transform.rotation);
Done_GameController.Instance.score += 50;
}
Destroy(other.gameObject);
Destroy(gameObject);
break;
case "Player":
if (gameObject.tag=="EnemyAttack"||gameObject.tag=="Stone"|| gameObject.tag == "Enemy")
{
Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
Done_GameController.Instance.gameOver = true;
}
Destroy(other.gameObject);
Destroy(gameObject);
break;
default:
break;
}
}
}
GameOverPanel脚本,这里面涉及到了Dotween插件的的使用,如果小伙伴们不了解这个插件,就去百度学习一下~
OnComplete(() => SceneManager.LoadScene(0))这句兰布达表达式意思是当这个动画执行完毕,才重新加载场景。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using UnityEngine.SceneManagement;
public class GameOverPanel : MonoBehaviour {
private Text gameOver;
private Button reStart;
private Button rankingList;
private Button backToMenu;
private void Awake()
{
gameOver = transform.Find("GameOver").GetComponent<Text>();
reStart = transform.Find("ReStart").GetComponent<Button>();
rankingList = transform.Find("RankingList").GetComponent<Button>();
backToMenu = transform.Find("BackToMenu").GetComponent<Button>();
}
private void Start()
{
reStart.onClick.AddListener(ReStartGame);
rankingList.onClick.AddListener(ToRankingList);
backToMenu.onClick.AddListener(BackToMenu);
Exit();
}
private void Update()
{
if(Done_GameController.Instance.loadCount==2)
{
if (Done_GameController.Instance.UIPanels[0].activeSelf == false &&
Done_GameController.Instance.UIPanels[1].activeSelf == false)
{
Enter();
Done_GameController.Instance.loadCount++;
}
}
}
private void OnEnable()
{
Done_GameController.Instance.loadCount = 1;
Done_GameController.Instance.loadCount++;
}
private void ToRankingList()
{
//TODO
}
private void BackToMenu()
{
gameOver.transform.DOLocalMoveX(1500, 0.3f);
reStart.transform.DOLocalMoveX(1500, 0.6f);
rankingList.transform.DOLocalMoveX(1500, 0.9f);
backToMenu.transform.DOLocalMoveX(1500, 1.2f);
Done_GameController.Instance.gameOver = true;
Invoke("InActiveUI", 0.9f);
Invoke("SetPanelInActive",0.9f);
Done_GameController.Instance.SetPanelActive(0);
}
private void Enter()
{
ActiveUI();
gameOver.transform.DOLocalMoveX(0, 0.3f);
reStart.transform.DOLocalMoveX(0, 0.6f);
rankingList.transform.DOLocalMoveX(0, 0.9f);
backToMenu.transform.DOLocalMoveX(0, 1.2f);
}
private void Exit()
{
gameOver.transform.localPosition = new Vector3(1500, 433, 0);
reStart.transform.localPosition = new Vector3(1500, 201.7f, 0);
rankingList.transform.localPosition = new Vector3(1500, -39, 0);
backToMenu.transform.localPosition = new Vector3(1500, -282, 0);
InActiveUI();
}
private void ReStartGame()
{
gameOver.transform.DOLocalMoveX (1500,0.3f);
reStart.transform.DOLocalMoveX(1500, 0.6f);
rankingList.transform.DOLocalMoveX(1500, 0.9f);
backToMenu.transform.DOLocalMoveX(1500, 1.2f);
Done_GameController.Instance.gameOver = false;
Invoke("InActiveUI", 0.9f);
Invoke("SetPanelInActive", 0.9f);
Done_GameController.Instance.SetPanelActive(1);
}
private void ActiveUI()
{
gameOver.gameObject.SetActive(true);
reStart.gameObject.SetActive(true);
rankingList.gameObject.SetActive(true);
backToMenu.gameObject.SetActive(true);
}
private void InActiveUI()
{
gameOver.gameObject.SetActive(false);
reStart.gameObject.SetActive(false);
rankingList.gameObject.SetActive(false);
backToMenu.gameObject.SetActive(false);
}
private void SetPanelInActive()
{
Done_GameController.Instance.SetPanelInActive(2);
}
private void SetPanelActive()
{
Done_GameController.Instance.SetPanelActive(2);
}
}
GamePanel脚本,其中的经验值依据当前等级,几何倍数进行增加。经验每一次到达100%就增加等级。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class GamePanel : MonoBehaviour {
private Text score;
private Text percent_exp;
private Slider exp;
public GameObject player;
private void Awake()
{
score = transform.Find("Score").GetComponent<Text>();
exp = transform.Find("Exp").GetComponent<Slider>();
percent_exp = transform.Find("Exp/Text").GetComponent<Text>();
score.transform.localPosition = new Vector3(-1500, 819, 0);
exp.transform.localPosition = new Vector3(1500, 820, 0);
InActiveUI();
}
private void Update()
{
if(Done_GameController.Instance.loadCount==2)
{
if (Done_GameController.Instance.UIPanels[0].activeSelf == false &&
Done_GameController.Instance.UIPanels[2].activeSelf == false)
{
Done_GameController.Instance.score = 0;
Done_GameController.Instance.level = 1;
StartGame();
Done_GameController.Instance.loadCount++;
}
}
if (Done_GameController.Instance.gameOver)
{
GameOver();
}
score.text = "Score: " + Done_GameController.Instance.score.ToString();
exp.value = Done_GameController.Instance.score / (1000 * (Mathf.Pow(2, Done_GameController.Instance.level)));
percent_exp.text = "Level " + Done_GameController.Instance.level.ToString() + " " + (exp.value*100).ToString()+"%";
if(exp.value>=1)
{
Done_GameController.Instance.level++;
}
}
private void OnEnable()
{
Done_GameController.Instance.gameOver = false;
Done_GameController.Instance.loadCount = 1;
Done_GameController.Instance.loadCount++;
Done_GameController.Instance.StartIEnumerator();
Instantiate(player);
}
public void StartGame()
{
ActiveUI();
score.transform.DOLocalMoveX(-233, 0.5f);
exp.transform.DOLocalMoveX(334, 0.5f);
}
public void GameOver()
{
score.transform.DOLocalMoveX(-1500, 0.5f);
exp.transform.DOLocalMoveX(1500, 0.5f);
Invoke("InActiveUI", 0.5f);
Invoke("SetPanelInActive", 0.5f);
Done_GameController.Instance.SetPanelActive(2);
}
private void ActiveUI()
{
score.gameObject.SetActive(true);
percent_exp.gameObject.SetActive(true);
exp.gameObject.SetActive(true);
}
private void InActiveUI()
{
score.gameObject.SetActive(false);
percent_exp.gameObject.SetActive(false);
exp.gameObject.SetActive(false);
}
private void SetPanelInActive()
{
Done_GameController.Instance.SetPanelInActive(1);
}
private void SetPanelActive()
{
Done_GameController.Instance.SetPanelActive(1);
}
}
总结一下UI逻辑开发,本来我是打算直接使用场景跳转来实现UI变化的,可是考虑到那种实现方式过于生硬,并且不符合我们的主题——针对Android进行性能优化的主题,所以就写了这个算法。其实有一个UI框架https://pan.baidu.com/s/1vxtKrnDo4C23sA9nT0DFyw,它模拟UI的出栈入栈来更方便的调控UI的显示与隐藏而且他源码也很简单,但是我今天想要自己动手写一下,其实说来也惭愧,我算法写到一半了,才想起来那个UI框架的思想。我这个算法是判定是否除了想要显示的UIPanel其他的UIPanel均为失活状态来更新状态。这个算法不看也罢。
好了,主要UI的逻辑开发到这里就差不多了