Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Unity3D UNET 模仿局域網游戲(二)

Unity3D UNET 模仿局域網游戲(二)

編輯:關於Android編程

緊接著上一篇博客,上一篇博客中,我們已經能夠分別移動角色,並且控制他射擊了,而且還稍微區分了一下不同的角色。這篇博客中我們繼續講解後面的內容。

既然角色都已經可以射擊了,那肯定還得需要一個血量對吧,所以現在我們就添加血量。給Player添加Health腳本並編輯:

using UnityEngine;

using System.Collections;

public class Health : MonoBehaviour {

public const int maxHealth = 100; //最大血量

public int currentHealth = maxHealth; //當前血量

//當玩家和子彈碰撞時調用的方法

public void TakeDamage(int damage)

{

currentHealth -= damage;

if (currentHealth <= 0) //如果當前血量小於等於0

{

currentHealth = maxHealth; //就讓他回復滿血狀態,方便後面我們讓他重生時需要

}

}

}

然後需要給Player添加一個Tag 名字為”Player”,給子彈也就是Bullet 添加一個腳本Bullet,並編輯:

using UnityEngine;

using System.Collections;

public class Bullet : MonoBehaviour {

//當子彈與物體碰撞時

void OnCollisionEnter(Collision other)

{

//如果碰撞的物體的Tag 是Player

if (other.collider.tag == "Player")

{

//調用碰撞物體的TakeDamage,傳遞一個參數是10

other.collider.SendMessage("TakeDamage", 10);

Destroy(gameObject); //銷毀子彈

}

}

}

既然有了血量,我們是不是就應該給他添加一個血條,現在我們就添加血條。新建UI–>Slider,然後把slider下的Handle Slide Area刪掉,把Fill 移動到Background的子物體,再把Fill Area刪掉。

 

這裡寫圖片描述

 

把 Fill 選擇填充父背景,也就是Background,保證他們兩個一樣大。修改顏色成綠色,Bbackgroud修改顏色成紅色。Fill 選擇這個

 

這裡寫圖片描述

 

然後這是效果圖

 

這裡寫圖片描述

 

最後,我們要把這個血條添加到角色身上去。選中Canvas,Render Mode改為World Space,讓攝像機渲染這個UI。把Canvas拖到Player的子物體。做如下改變:

 

這裡寫圖片描述

 

拖動Slider到角色頭頂,然後效果圖

 

這裡寫圖片描述

 

血條就添加好了,現在我們讓他能夠隨著生命值改變。修改Health類

using UnityEngine;

using System.Collections;

using UnityEngine.UI;

public class Health : MonoBehaviour {

public const int maxHealth = 100; //最大血量

public int currentHealth = maxHealth; //當前血量

public Slider healthSlider;

//當玩家和子彈碰撞時調用的方法

public void TakeDamage(int damage)

{

currentHealth -= damage;

if (currentHealth <= 0) //如果當前血量小於等於0

{

currentHealth = maxHealth; //就讓他回復滿血狀態,方便後面我們讓他重生時需要

}

healthSlider.value = (float)currentHealth / maxHealth; //修改Slider的比例

}

}

這時我們發現當角色旋轉時,血條也會旋轉,看起來不美觀,我們讓他只”看著攝像機”。

給Canvas添加一個腳本LookAtCamera並編輯

using UnityEngine;

using System.Collections;

public class LookAtCamera : MonoBehaviour {

// Update is called once per frame

void Update () {

transform.LookAt(Camera.main.transform);

}

}

這樣血條就會一直對著攝像機了。現在運行游戲,是可以使用的,

 

這裡寫圖片描述

 

但是!!細心的你會發現,他們的血條有可能不同步。這是因為,血量的判斷在客戶端和服務端都進行了判斷,相當於各自計算各自的,但是!!當服務端的子彈碰撞到Player時,會計算生命值,然後銷毀子彈,而當服務端的子彈銷毀時,客戶端的子彈也會跟著一起消失,而服務端已經計算了,而客戶端沒有計算(就像網絡游戲有延遲一樣),就會導致不同步。現在我們來讓子彈同步。要解決這個問題,我們就要讓血量的檢測在服務端進行,然後同步到客戶端就行了。修改Health類繼承NetworkBehaviour,

using UnityEngine;

using System.Collections;

using UnityEngine.UI;

using UnityEngine.Networking;

public class Health : NetworkBehaviour {

public const int maxHealth = 100; //最大血量

//檢測一個屬性,當服務端改變值時,會同步到客戶端

//當值改變時,會調用一個方法 如:OnChangeHealth

[SyncVar(hook = "OnChangeHealth")]

public int currentHealth = maxHealth; //當前血量

public Slider healthSlider;

//當玩家和子彈碰撞時調用的方法

public void TakeDamage(int damage)

{

if (!isServer) //如果不是服務端

{

return;

}

currentHealth -= damage;

if (currentHealth <= 0) //如果當前血量小於等於0

{

currentHealth = maxHealth; //就讓他回復滿血狀態,方便後面我們讓他重生時需要

}

}

//當服務端檢測的屬性值改變時調用的方法

//health:改變後的值

void OnChangeHealth (int health)

{

healthSlider.value = (float)health / maxHealth; //修改Slider的比例

}

}

 

這裡寫圖片描述

 

這時候就同步了。。接下來我們設置當角色生命值為0時重生。修改Health類,這裡修改的地方比較少,我就直接放修改的圖片,大家對應著修改就行了。

 

這裡寫圖片描述

 

 

這裡寫圖片描述

 

這時候運行,你會發現,只有當客戶端攻擊時角色死亡位置才會重置,服務端攻擊不會。這是因為一開始我們設置了,

 

這裡寫圖片描述

 

這代表只有客戶端才有權限,而服務端的攻擊然後重置位置,這是沒有權限的,所以現在我們要讓它能夠在服務端也重置位置,修改Health類

using UnityEngine;

using System.Collections;

using UnityEngine.UI;

using UnityEngine.Networking;

public class Health : NetworkBehaviour {

public const int maxHealth = 100; //最大血量

//檢測一個屬性,當服務端改變值時,會同步到客戶端

//當值改變時,會調用一個方法 如:OnChangeHealth

[SyncVar(hook = "OnChangeHealth")]

public int currentHealth = maxHealth; //當前血量

public Slider healthSlider;

//當玩家和子彈碰撞時調用的方法

public void TakeDamage(int damage)

{

if (!isServer) //如果不是服務端

{

return;

}

currentHealth -= damage;

if (currentHealth <= 0) //如果當前血量小於等於0

{

currentHealth = maxHealth; //就讓他回復滿血狀態,方便後面我們讓他重生時需要

RpcRespawn(); //調用一個方法,設置重生的位置

}

}

//當服務端檢測的屬性值改變時調用的方法

//health:改變後的值

void OnChangeHealth (int health)

{

healthSlider.value = (float)health / maxHealth; //修改Slider的比例

}

//遠程調用,表示調用這個方法時就會在客戶端調用,方法名必須以Rpc開頭

[ClientRpc]

void RpcRespawn()

{

if (!isLocalPlayer)

{

return;

}

transform.position = Vector3.zero; //把位置設置到0,0,0

}

}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved