UNET連線遊戲(七){原來這就是掛掉的感覺}

本篇使用的是5.3版後有UNET的UNITY
目標:基本連線遊戲機制+陣亡後延遲重生
1.延續前篇(UNET連線遊戲(六){你快掛囉,HUD_UI續})
已經有血條的控制與顯示後,接下來針對陣亡的玩家做一些對應的控制,例如:

  • 不能再發射子彈
  • 不能繼續移動
  • 停留數秒後才重生
  • 畫面變紅的陣亡提示
  • 以及模擬暈眩

2.以上行為可以改寫之前的DamageScript.cs來達成對陣亡人物的行動限制,不能發射子彈的部分可以透過關閉GunController腳本達成(把槍的零件關閉),不能移動則透過關閉FirstPersonController fpsController腳本達成,畫面變紅則需要Image的UI。

using UnityStandardAssets.Characters.FirstPerson;
GunController gunCtrl;
FirstPersonController fpsController;
Image DEAD_BG;

增加上列的引用和宣告,並於Start()處取得相關零件,如下

gunCtrl = GetComponent<GunController> ();
fpsController = GetComponent<FirstPersonController> ();
DEAD_BG = GameObject.Find ("BG").GetComponent<Image> ();


3.為了統一將發射子彈與移動關閉,我們新增一個帶有bool引數的Alive方法作為檢驗

void Alive(bool b){
  gunCtrl.enabled = b;
  fpsController.enabled = b;
}

接下來就可以使用Alive (false); 或 Alive (true);關閉或打開角色控制
4.重生延遲5秒會用到Invoke 配合Go()方法達成,如下:

	[ClientRpc]
	void RpcRebirth(){
		Invoke ("Go",5.0f);
		print ("DIE");
		if (isLocalPlayer)Alive (false);
	}
	void Go(){
		HP = HP_MAX;
		if (isLocalPlayer) {
			Transform spawn = NetworkManager.singleton.GetStartPosition();
			transform.position = spawn.position;
			Alive (true);
		}
	}

把原來重置玩家的功能包入方法後,同時回滿HP
5.以上已經可以限制陣亡角色的行動,但畫面見漸漸變紅的功能必須透過新增UI執行,製作全版紅色UI命名BG然後預設透明
unet-hit-078
unet-hit-079
6.撰寫一個死亡時要執行的void Dead(),並使用InvokeRepeating於Alive()內反覆執行,直到5秒Invoke呼叫Go方法後CancelInvoke (“Dead”)取消Invoke的功能,內容如下

void Alive(bool b){
		gunCtrl.enabled = b;
		fpsCtrl.enabled = b;
		charCtrl.enabled = b;
		rotaSpeed = 270;
		InvokeRepeating ("Dead",0.1f,0.02f);
	}
void Dead (){
		transform.Rotate(Vector3.right * Time.deltaTime * -30);
		transform.Rotate(Vector3.up * Time.deltaTime * rotaSpeed);
		rotaSpeed-=2;
		DEAD_BG.color += new Color (0, 0, 0, 0.003f);
	}

transform.Rotate 用來模擬暈眩並且漸漸降低旋轉速度,以及提高UI的不透明度
7.完整的DamageScript.cs

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.UI;
using UnityStandardAssets.Characters.FirstPerson;
public class DamageScript : NetworkBehaviour {
	AudioSource damageAudio;
	GunController gunCtrl;
	FirstPersonController fpsCtrl;
	CharacterController charCtrl;
	public Image HP_BAR;
	public Image DEAD_BG;
	public const int HP_MAX = 3;
	int rotaSpeed;
	[SyncVar(hook = "HpBar")]public int HP = HP_MAX;
	void Awake()
	{
	}
	void Start (){
		damageAudio = GetComponent<AudioSource>();
		gunCtrl = GetComponent<GunController> ();
		fpsCtrl = GetComponent<FirstPersonController> ();
		charCtrl = GetComponent<CharacterController> ();
		DEAD_BG = GameObject.Find ("BG").GetComponent<Image> ();
	}
	public void TakeDamage(int D){
		if (!isServer) {
			return;
		}
		if (HP > 0) {
			HP -= D;
			if(HP <= 0)RpcRebirth ();
		}
	}
	void HpBar(int h){
		print (h);
		if(HP_BAR)HP_BAR.fillAmount = (float)h / (float)HP_MAX;
	}
	void Alive(bool b){
		gunCtrl.enabled = b;
		fpsCtrl.enabled = b;
		charCtrl.enabled = b;
		rotaSpeed = 270;
		InvokeRepeating ("Dead",0.1f,0.02f);
	}
	void Dead (){
		transform.Rotate(Vector3.right * Time.deltaTime * -30);
		transform.Rotate(Vector3.up * Time.deltaTime * rotaSpeed);
		rotaSpeed-=2;
		DEAD_BG.color += new Color (0, 0, 0, 0.003f);
	}
	[ClientRpc]
	void RpcRebirth(){
		Invoke ("Go",5.0f);
		print ("DIE");
		if (isLocalPlayer)Alive (false);
	}
	void Go(){
		HP = HP_MAX;
		if (isLocalPlayer) {
			DEAD_BG.color = new Color (1, 0, 0, 0);
			Transform spawn = NetworkManager.singleton.GetStartPosition();
			transform.position = spawn.position;
			Alive (true);
			CancelInvoke ("Dead");
		}
	}
}

8.最終的成果
unet-hit-080

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *