這篇文章進行對遊戲ui邏輯的總結。
首先給每個機器人添加一個血條的效果,在機器人的遊戲物體下建立一個畫布,并添加一個slider,隻保留其中的Fill Area,把其他的删掉,如圖。
将Fill中的image修改為紅色,然後給slider添加一個腳本,主要功能是讓slider的value的值與血量占比相當
using UnityEngine;
using UnityEngine.UI;
public class follower : MonoBehaviour
{
[SerializeField]
private float m_offsety;
public Transform m_robot;
private float m_robotinithp;//機器人初始的hp
private void Start()
{
m_robotinithp = m_robot.gameObject.GetComponent<RobotController>().M_hp;
}
private void Update()
{
//确定血條位置
gameObject.transform.position =
new Vector3(m_robot.position.x, m_robot.position.y + m_offsety, m_robot.position.z);
//根據實際情況扣血
gameObject.GetComponent<Slider>().value=
((m_robot.gameObject.GetComponent<RobotController>().M_hp / m_robotinithp));
}
}
然後對該畫布的Canvas元件中的Render Mode進行如圖設定:
建立一個新的相機,将它拖入Canvas元件中的Render Camera,在第三篇文章中的gamemanager類中擁有該相機遊戲對象的引用,名為m_secondcamera,并将其與主相機的transform同步。這樣子就相當與每個機器人都擁有一個與血量相當slider,并且它時刻面向玩家的視角,形成血條的效果。
血條設定好以後,建立多個scene來存儲關卡,把每個scene的地圖自己div一下,将多個機器人放置其中并設定好巡邏點。然後開始進行ui腳本的建立。
首先是第一個scene也就是主菜單,建立一個名為UI的空物體,在它下面建立三個畫布,再為每個畫布添加各種功能對象,如圖:
建立腳本進行管理,挂在ui上
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class menuui : MonoBehaviour {
public GameObject m_setcanvas;
public GameObject m_Authorcanvas;
public GameObject m_volumeslider;
private void Start()
{
m_setcanvas.SetActive(false);
m_Authorcanvas.SetActive(false);
m_volumeslider.GetComponent<Slider>().value = datamanager.m_volume;
}
private void Update()
{
//音量調節
datamanager.m_volume = m_volumeslider.GetComponent<Slider>().value;
}
//下面的方法全都挂在不同的Button上
public void OnStart()
{
SceneManager.LoadScene(1);
}
public void OnExit()
{
Application.Quit();
}
public void OnSetOpen()
{
m_setcanvas.SetActive(true);
}
public void OnSetClose()
{
m_setcanvas.SetActive(false);
}
public void OnAuthorOpen()
{
m_Authorcanvas.SetActive(true);
}
public void OnAuthorClose()
{
m_Authorcanvas.SetActive(false);
}
}
還建立一個空物體負責播放bgm,也挂一個腳本控制音量,在其他scene中也有這個物體
using UnityEngine;
public class bgm : MonoBehaviour {
void Update ()
{
gameObject.GetComponent<AudioSource>().volume = datamanager.m_volume;
}
}
然後是開始遊戲後的ui,之前在建立武器系統時做了一部分,現在補充完整
建立腳本對其進行管理
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
//遊戲界面狀态
enum PlayUiState
{
BATTLE,
END,
SET
}
public class playui : MonoBehaviour
{
private PlayUiState m_state;//目前界面狀态
private gun m_gun;
private playerhp m_playerhp;
private player m_player;
private gamemanager m_manager;
public GameObject m_hptext;//擷取畫布中的一個text
public GameObject m_bulletText;//子彈數文本
public GameObject m_snipertexture;//瞄準時加載的圖檔
public GameObject m_aimtexture;
public GameObject m_time;
public GameObject m_endcanvas;
public GameObject m_endtext;
public GameObject m_playerstatetext;
public GameObject m_hurtimage;
public GameObject m_warningtext;
public GameObject m_scoretext;
public GameObject m_setcanvas;
public GameObject m_bgm;
public GameObject m_volumeslider;
public GameObject m_mouseslider;
private Color m_flashcolor; //記錄受傷圖檔的色彩值
public float m_flashspeed = 2;
private float m_musictime = 0;//記錄音樂播放位置
private bool m_dead = false;
private float m_finaltime = 0;
void Start()
{
m_state = PlayUiState.BATTLE;
m_player = FindObjectOfType<player>();
m_playerhp = FindObjectOfType<playerhp>();
m_manager = FindObjectOfType<gamemanager>();
m_playerhp.diedelegate += OnDie;//添加委托事件
m_volumeslider.GetComponent<Slider>().value = datamanager.m_volume;
m_mouseslider.GetComponent<Slider>().value = datamanager.m_mosen;
//記錄目前設定好的受傷圖檔的顔色值
m_flashcolor = m_hurtimage.GetComponent<Image>().color;
//将受傷圖檔先設定為透明
m_hurtimage.GetComponent<Image>().color = Color.clear;
m_setcanvas.SetActive(false);
m_endcanvas.SetActive(false);
m_hurtimage.SetActive(true);
m_playerstatetext.SetActive(false);
m_warningtext.SetActive(false);
//若是第一關 為玩家顯示提示
if (datamanager.M_gamelevel == 1)
{
StartCoroutine(FirstWarning());
}
Cursor.visible = false;//隐藏滑鼠
}
void Update()
{
#region 戰鬥界面
if (m_state == PlayUiState.BATTLE)
{
m_gun = FindObjectOfType<gun>();
FreshHpText();
FreshBulletText();
ShowAimImage();
ShowTheTime();
//當玩家處于休息狀态 顯示提示
if (playerstatemanager.m_state == PlayerState.RELAXE)
{
m_playerstatetext.GetComponent<Text>().text = "Relaxing...";
m_playerstatetext.SetActive(true);
}
else m_playerstatetext.SetActive(false);
//将受傷圖檔的顔色漸變為透明
m_hurtimage.GetComponent<Image>().color =
Color.Lerp
(
m_hurtimage.GetComponent<Image>().color,
Color.clear,
m_flashspeed * Time.deltaTime
);
//設定滑鼠靈敏度
datamanager.m_mosen = m_mouseslider.GetComponent<Slider>().value;
m_player.m_mouserate = datamanager.m_mosen * 5;
//狀态轉換
if (datamanager.M_gamelevel == datamanager.m_maxlevel || m_dead) m_state = PlayUiState.END;
if (Input.GetKeyUp(KeyCode.Y)) m_state = PlayUiState.SET;
}
#endregion
#region 結束界面
if (m_state == PlayUiState.END)
{
Cursor.visible = true;//顯示滑鼠
m_gun.enabled = false;
m_player.enabled = false;
m_endcanvas.SetActive(true);
string score = "";
if (datamanager.M_gamelevel == datamanager.m_maxlevel)//勝利
{
m_endtext.GetComponent<Text>().text = "Victory!";
//記錄遊戲時間
if (m_finaltime == 0)
m_finaltime = (int)datamanager.M_playtime;
score =
"殺敵數:" + datamanager.M_gamescore +
"\n目前關卡:" + "final" +
"\n用時:" + m_finaltime + "s";
}
else if (m_dead)//死亡
{
m_endtext.GetComponent<Text>().text = "Game Over";
m_playerhp.diedelegate -= OnDie;//釋放委托事件
//記錄遊戲時間
if (m_finaltime == 0)
m_finaltime = (int)datamanager.M_playtime;
score =
"殺敵數:" + datamanager.M_gamescore +
"\n目前關卡:" + datamanager.M_gamelevel +
"\n用時:" + m_finaltime + "s";
}
m_scoretext.GetComponent<Text>().text = score.ToString();
}
#endregion
#region 設定界面
if (m_state == PlayUiState.SET)
{
m_gun.enabled = false;
//音樂暫停
m_musictime = m_bgm.GetComponent<AudioSource>().time;
m_bgm.GetComponent<AudioSource>().Pause();
Cursor.visible = true;//顯示滑鼠
Time.timeScale = 0;//時間暫停
m_setcanvas.SetActive(true);
//聲音設定
datamanager.m_volume = m_volumeslider.GetComponent<Slider>().value;
}
#endregion
}
void FreshHpText()
{
m_hptext.GetComponent<Text>().text = "HP:" + m_playerhp.M_hp.ToString();
}
void FreshBulletText()
{
m_bulletText.GetComponent<Text>().text = m_gun.Curbulletnum.ToString() + "/"
+ m_gun.Storebulletnum.ToString();
}
void ShowAimImage()
{
if (sniperscope.m_isaiming)
{
m_snipertexture.SetActive(true);
m_aimtexture.SetActive(false);
}
else
{
m_snipertexture.SetActive(false);
m_aimtexture.SetActive(true);
}
}
void OnDie()
{
m_dead = true;
}
void ShowTheTime()
{
int time = (int)m_manager.M_WaitTime;
if (time == 0)
m_time.GetComponent<Text>().text = "The door is open!";
else
m_time.GetComponent<Text>().text = time.ToString();
}
public void HurtEffect()
{
m_hurtimage.GetComponent<Image>().color = m_flashcolor;
}
//下面兩個方法是綁定在Button上的
public void OnSetClose()
{
Cursor.visible = false;
// 繼續播放音樂
m_bgm.GetComponent<AudioSource>().Play();
m_bgm.GetComponent<AudioSource>().time = m_musictime;
Time.timeScale = 1;//時間恢複正常
m_setcanvas.SetActive(false);
m_gun.enabled = true;
m_state = PlayUiState.BATTLE;//轉換狀态
}
public void OnExit()
{
Application.Quit();
}
//顯示警告,延遲消失
IEnumerator FirstWarning()
{
m_warningtext.GetComponent<Text>().text = "Live and get out";
m_warningtext.SetActive(true);
yield return new WaitForSeconds(5f);
m_warningtext.GetComponent<Text>().text = " ";
m_warningtext.SetActive(false);
}
}
因為每個關卡的ui都相同,可以設定為全局ui,在gamemanager中将名為ui的物體DontDestroyOnLoad了就行。
效果如下(結束界面):
ui寫完後,這個小遊戲就基本完成的差不多了,後面可能還會有些改進和補充,現在已經可以愉快的玩耍了,謝謝觀看:)