Unity(C#)初心者・入門者向けチュートリアル ひよこのたまご

AndroidやiOS向けアプリを簡単に作れるゲーム開発環境Unity(ユニティ)の使い方を、チュートリアル方式で一緒に学びましょう!

【Unity9】UNETでHPを画面に表示し、Playerへダメージを与える【UNET9】

Unity5.1.1p3 Personal(2015年7月)


前回の続きです〜


前回までで敵Playerの名前を取得するところまでいきました〜

今回はPlayerにHPを付けて、敵Playerへダメージを与えたり自分がダメージを受けるようにします〜



UNET Part 9 - Taking Damage! - YouTube

【目標】HPを画面に表示し、Playerへダメージを与える

①HPを画面に表示する

まずはHPを画面に表示しましょう〜


新しくPlayer_Healthスクリプトを作成し、Playerプレハブに取り付けて下さい〜

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.UI;

public class Player_Health : NetworkBehaviour {
	
	//SyncVar: Clientの変数変更情報をサーバーが受け取り、変更結果を全クライアントへ送る
	[SyncVar] private int health = 100;
	private Text healthText;

	// Use this for initialization
	void Start () {
		//Textオブジェクトをキャッシュ
		healthText = GameObject.Find("Health Text").GetComponent<Text>();
		SetHealthText();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void SetHealthText ()
	{
		if (isLocalPlayer) {
			//現在HPを画面に表示
			healthText.text = "Health " + health.ToString();
		}
	}
	
	//ダメージを受けた時のメソッド
	public void DeductHealth(int dmg)
	{
		health -= dmg;
	}
}

Player_Health.cs


StartメソッドでTextオブジェクトをキャッシュし、SetHealthTextメソッドを呼び出し、画面にHPを表示しています〜

また、DeductHealthメソッドが外部から呼び出し、healthを引数分だけ減らしています〜


これでひとまず、自分のHPを画面に表示させることができました〜


f:id:hiyotama:20150713121626p:plain
画面にHPを表示

②Playerにダメージを与える

続いてPlayerにダメージを与えていきます〜


まずは前回作成したPlayer_Shootingメソッドを修正します〜

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Player_Shooting : NetworkBehaviour {
	
//********** 開始 **********//
	private int damage = 25; //float型→int型
//********** 終了 **********//
	private float range = 200;
	[SerializeField] private Transform camTransform;
	private RaycastHit hit;

	void Update () {
		CheckIfShooting();
	}
	
	void CheckIfShooting ()
	{
		if (!isLocalPlayer) {
			return;
		}
		
		if (Input.GetKeyDown(KeyCode.Mouse0)) {
			Shooting();
		}
	}
	
	void Shooting ()
	{
		if (Physics.Raycast (camTransform.TransformPoint (0, 0, 0.5f), camTransform.forward, out hit, range)) {
			if (hit.transform.tag == "Player") {
				string uIdentity = hit.transform.name;
				CmdTellServerWhoWasShot(uIdentity, damage);
			}
		}
	}
	
	[Command]
	//dmg変数をfloat型→int型
//********** 開始 **********//
	void CmdTellServerWhoWasShot (string uniqueID, int dmg)
	{
//********** 終了 **********//
		GameObject go = GameObject.Find(uniqueID);
//********** 開始 **********//
		//Player_HealthのDeductHealthメソッド呼び出し
		go.GetComponent<Player_Health>().DeductHealth(dmg);
//********** 終了 **********//
	}
}

Player_Shooting.cs


CmdTellServerWhoWasShotメソッド内で、先ほど作成したPlayer_HealthスクリプトのDeductHealthメソッドを呼びだしています〜


続いてPlayer_Healthを修正していきます〜以下ソースです〜

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.UI;

public class Player_Health : NetworkBehaviour {
	
//********** 開始 **********//
	//[Command]メソッド内でhealthが変更された時に指定メソッドを呼び出す
	[SyncVar (hook = "OnHealthChanged")] private int health = 100;
//********** 終了 **********//
	private Text healthText;

	// Use this for initialization
	void Start () {
		healthText = GameObject.Find("Health Text").GetComponent<Text>();
		SetHealthText();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void SetHealthText ()
	{
		if (isLocalPlayer) {
			healthText.text = "Health " + health.ToString();
		}
	}
	
	//[Command]の付いているCmdTellServerWhoWasShotメソッドから呼ばれるので、
	//hookが作動する?
	public void DeductHealth(int dmg)
	{
		//hookが作動するきっかけとなるだけで、この時点ではまだ全クライアントへは送信されていない
		health -= dmg;
	}
	
//********** 開始 **********//
	void OnHealthChanged (int hlth)
	{
		//全クライアントへ変更結果を送信
		health = hlth;
		//HPの表示を変更
		SetHealthText();
	}
//********** 終了 **********//
}

Player_Health.cs


Player_ShootingスクリプトのCmdTellServerWhoWasShotメソッドから DeductHealthメソッドが呼び出されて、SyncVar変数のhealthが変更され、hookが作動してOnHealthChangedメソッドが実行される、という流れです〜


今まではSyncVarが機能するのはSyncVar変数を[Command]がついているメソッド内で変更した時のみだったので少し戸惑いましたが、恐らくDeductHealthメソッドの呼び出し元であるCmdTellServerWhoWasShotメソッドに[Command]がついているから大丈夫ということだと思います〜


とにかくhealthの変更結果を全クライアントへ知らせ、画面上の自分のHPも変更することができました〜

③結果

Playerへ向けて攻撃した結果、無事HPを減らすことができました〜


f:id:hiyotama:20150713124006p:plain
ダメージ!


f:id:hiyotama:20150713124034p:plain
HPが0になったら今のところマイナスになっちゃう


次回以降でHPがマイナスになった時、キャラクターが死んだりといった処理が追加されていくんだと思います〜


それでは今回はここまでです〜

ありがとうございました〜


【Unity9】UNETでマルチプレイヤーなオンラインゲーム開発【UNET1】
【Unity9】UNETでプレイヤーの動きを補間し、なめらかな動きを実現する【UNET1-2】
【Unity9】UNETでネットワーク越しに傾き(Rotation)を同期させる【UNET2】
【Unity9】UNETでオンライン開始時のプレイヤー生成位置を変更する【UNET2-2】
【Unity9】UNETのネットワークトラフィックを軽減し、効率化する【UNET3】
【Unity9】UNETのlatency(遅延時間)を改善する【UNET4】
【Unity9】UNETのlatency(遅延時間)を表示して、ちょっとだけ改善する【UNET4-2】
【Unity9】UNETのSyncVarのhookの使用例と、前時代の同期方法【UNET5】
【Unity9】UNETを使ってRotationを同期させる【UNET6】
【Unity9】UNETで各プレイヤーにPlayerIDを設定する【UNET7】
【Unity9】UNETで敵プレイヤーにダメージを与える!【UNET8】
【Unity9】UNETでHPを画面に表示し、Playerへダメージを与える【UNET9】
【Unity9】UNETでHPが0以下になった時、Playerを破壊する!【UNET10】
【Unity9】UNETで死んだPlayerを生き返らせる!【UNET11】
【Unity9】UNETでゾンビAIを出現させる!【UNET12】
【Unity9】UNETでゾンビ生成時にユニークなIDを付ける!【UNET13】
【Unity9】UNETでゾンビを撃つ!【UNET14】
【Unity9】UNETでゾンビに攻撃させる!【UNET15】
【Unity9】UNETでゾンビの動きをスムーズにシンクロさせる!【UNET16】
【Unity9】UNETでゾンビ発生地点を増やす【UNET17】
【Unity9】UNETで発生したバグを取り除く【UNET18】
【Unity9】Unity MultiPlayerを使ってネットワーク越しにマッチメイキング!【UNET19】
【Unity9】GUIを改善して、Network Managerを見やすくする!【UNET20】
【Unity9】表示したGUI(Network Manager)を機能させる!【UNET20-2】
【Unity9】UNETでAnimationを同期させる!【UNET21】