Unity实战篇:移植游戏到安卓平台的注意事项及其实例(三)(UI交互逻辑开发)

版权声明:转载请注明出处!不注明也无所谓,嘿嘿。 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%就增加等级。

\boldsymbol{\mathbf{{\color{Red} maxExp=1000*2^{level}}}}

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的逻辑开发到这里就差不多了

猜你喜欢

转载自blog.csdn.net/qq_15020543/article/details/82909186