本Chapterでは以下の画像のように頭上にプレイヤー名とHPを表示するUIの作成を行います。
頭上UIの導入方法
この頭上UIを表示するためにはまず頭上UIを表示するタイミングを考えます。
このUIはプレイヤーがログインし、そのPlayerのキャラクターが生成されるのとほぼ同時に生成され、プレイヤーがログアウトするのとほぼ同時に削除される必要があります。
つまり頭上UIのPrefabを作成し、プレイヤーPrefabに頭上UIを生成用のスクリプトを用意し、プレイヤーの生成時に頭上UIを生成することで表示できるようになります。
まとめると頭上UIを生成するための手順は以下の通りです。
- 頭上UIのPrefabを作成
- プレイヤーPrefab内にPlayerManagerのScriptコンポーネントを作成
- HP等のローカル変数格納用ScriptとしてLocalVariablesを作成
- SceneにCanvasオブジェクトを作成(既にCanvasオブジェクトがあれば必要無し)
頭上UIのPrefab作成
頭上UIPrefabの構成は以下のようになっています。
作成手順としては
- SliderのUIオブジェクトを作成し、PlayerUIという名前に変更
- 以下のPlayerUIScriptを作成し、PlayerUIオブジェクトにアタッチ
- TextのUIオブジェクトをPlayerUIオブジェクトの子オブジェクトとして作成し、PlayerNameTextという名前に変更
- それぞれのオブジェクトの設定を以下の画像のように変更
PlayerUIScript.csのソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
using UnityEngine; using UnityEngine.UI; using System.Collections; public class PlayerUIScript : MonoBehaviour { #region Public Properties //キャラの頭上に乗るように調整するためのOffset public Vector3 ScreenOffset = new Vector3(0f, 30f, 0f); //プレイヤー名前設定用Text public Text PlayerNameText; //プレイヤーのHP用Slider public Slider PlayerHPSlider; //プレイヤーのチャット用Text //public Text PlayerChatText; #endregion #region Private Properties //追従するキャラのPlayerManager情報 PlayerManager _target; float _characterControllerHeight; Transform _targetTransform; Vector3 _targetPosition; #endregion #region MonoBehaviour Messages void Awake() { //このオブジェクトはCanvasオブジェクトの子オブジェクトとして生成 this.GetComponent<Transform>().SetParent(GameObject.Find("Canvas").GetComponent<Transform>()); } void Update() { //もしPlayerがいなくなったらこのオブジェクトも削除 if (_target == null) { Destroy(this.gameObject); return; } // 現在のHPをSliderに適用 if (PlayerHPSlider != null) { PlayerHPSlider.value = _target.HP; } // 頭上チャットを表示 //if (PlayerChatText != null) //{ // PlayerChatText.text = _target.ChatText; //} } #endregion void LateUpdate() { //targetのオブジェクトを追跡する if (_targetTransform != null) { _targetPosition = _targetTransform.position; //三次元空間上のtargetの座標を得る _targetPosition.y += _characterControllerHeight; //キャラクターの背の高さを考慮する //targetの座標から頭上UIの画面上の二次元座標を計算して移動させる this.transform.position = Camera.main.WorldToScreenPoint(_targetPosition) + ScreenOffset; } } #region Public Methods public void SetTarget(PlayerManager target) { if (target == null)//targetがいなければエラーをConsoleに表示 { Debug.LogError("<Color=Red><a>Missing</a></Color> PlayMakerManager target for PlayerUI.SetTarget.", this); return; } //targetの情報をこのスクリプト内で使うのでコピー _target = target; _targetTransform = _target.GetComponent<Transform>(); CharacterController _characterController = _target.GetComponent<CharacterController>(); //PlayerManagerの頭上UIに表示したいデータをコピー if (_characterController != null) { _characterControllerHeight = _characterController.height; } if (PlayerNameText != null) { PlayerNameText.text = _target.photonView.owner.NickName; } if (PlayerHPSlider != null) { PlayerHPSlider.value = _target.HP; } //if (PlayerChatText != null) //{ // PlayerChatText.text = _target.ChatText; //} } #endregion } |
PlayerUIのInspectorビュー
PlayerUIの子オブジェクトBackgroundのinspectorビュー
PlayerUIの子オブジェクトのFillAreaのinspectorビュー
PlayerUIの子オブジェクトのFillAreaの子オブジェクトのFillのinspectorビュー
PlayerUIの子オブジェクトPlayerNameTextのinspectorビュー
その他のPlayerUIオブジェクト設定
PlayerUIの子オブジェクトのHandleSlideAreaはSliderのつまみに当たるオブジェクトで、HPバーには必要無いので非表示または削除してください。
PlayerPrefabの変更
PlayerPrefabに必要な手順は以下の通りです。
- HP等のローカル変数を保持しておくためのスクリプトであるLocalVariablesを作成
- 以下の頭上UIを生成するスクリプトであるPlayerManagerを作成
- PlayerPrefabにPlayerManagerをアタッチ
- PlayerPrefabのPlayerManagerのinspectorビューの設定
LocalVariables.csのソースコード
LocalVariablesはHPやMPなどの自分のキャラのステータス等のローカルで持っておく必要がある変数を保存しておくスクリプトです。
どのスクリプトからでも呼ぶことができるので、ダメージを受けたときはこのLocalVariables.currentHPの値を書き換えれば良いように今後設計していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LocalVariables : MonoBehaviour { //現在のHP static public int currentHP = 100; // Use this for initialization void Start() { VariableReset(); } static public void VariableReset() //変数初期化 { currentHP = 100; } } |
PlayerManager.csのソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections; using System; public class PlayerManager : Photon.PunBehaviour, IPunObservable { //頭上のUIのPrefab public GameObject PlayerUiPrefab; //現在のHP public int HP = 100; //Localのプレイヤーを設定 public static GameObject LocalPlayerInstance; //頭上UIオブジェクト GameObject _uiGo; #region プレイヤー初期設定 void Awake() { if (photonView.isMine) { PlayerManager.LocalPlayerInstance = this.gameObject; } } #endregion #region 頭上UIの生成 void Start() { if (PlayerUiPrefab != null) { //Playerの頭上UIの生成とPlayerUIScriptでのSetTarget関数呼出 _uiGo = Instantiate(PlayerUiPrefab) as GameObject; _uiGo.SendMessage("SetTarget", this, SendMessageOptions.RequireReceiver); } else { Debug.LogWarning("<Color=Red><a>Missing</a></Color> PlayerUiPrefab reference on player Prefab.", this); } } #endregion void Update() { if (!photonView.isMine) //このオブジェクトがLocalでなければ実行しない { return; } //LocalVariablesを参照し、現在のHPを更新 HP = LocalVariables.currentHP; } #region OnPhotonSerializeView同期 //プレイヤーのHP,チャットを同期 public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.isWriting) { stream.SendNext(this.HP); //stream.SendNext(this.ChatText); } else { this.HP = (int)stream.ReceiveNext(); //this.ChatText = (string)stream.ReceiveNext(); } } #endregion } |
PlayerPrefabのPlayerManager設定
一度unitychanのPrefabをHierarchyビューに出し、PlayerManagerをCharacterControlScriptの下に来るようにアタッチし、以下の画像のように設定します。
※PhotonViewにPlayerManagerを設定しておかないと頭上UIの変数のリアルタイム同期ができないので忘れないようにしてください。
設定後、Applyボタンを押して保存してからHierarchyビューからunitychanを削除します。
※Prefabを変更する場合はApplyボタンを押さないと変更が保存されないので注意しましょう。
設定は以上で完了です。
実際に動かしてみよう!!
先に「ゆにこ」をログインさせて「ゆにお」でログインしました。
頭上のUIがキャラに追従し、プレイヤーの名前が反映されていることが確認できましたね!!
また一つオンラインゲームっぽさが出てきた感じがしますね!!
次回予告!!
次回はついにオンラインゲームの醍醐味であるチャットを導入してみたいと思います!!
お楽しみに!!!