今回は戦闘中に味方キャラクターのターンになった時にその味方キャラクターの頭上にアイコンを表示する事と、
味方キャラクターが攻撃やアイテム、魔法等を行う時の対象者を選択している時にその対象者の頭上にアイコンを表示する機能を作成していきたいと思います。
前回は戦闘開始時にユニティちゃんが装備している武器のオブジェクトをインスタンス化して装備させる機能を作成しました。

ユニティちゃんのRPGを作ってみようの他の記事は

から見ることが出来ます。
戦闘用キャラクターの子要素にアイコンを作成する
まずは戦闘用キャラクタープレハブの子要素にアイコンを作成していきます。
Assets/RPG/Prefabs/Characters/Ally/BattleUnityChanを選択しインスペクタのOpen Prefabボタンを押します。
BattleUnityChanを選択した状態で右クリックからUI→Canvasを選択し、名前をMarkerとします。
MarkerのインスペクタでCanvasのRender ModeをWorld Spaceにし、RectTransformのPosYを1.87(アイコンを表示する位置に調整)、WidthとHeightを100、RotationのZを180(Imageの向きによって変わる)、ScaleのXYZを全て0.005とします。
Render ModeをWorld Spaceにしたことで他のゲームオブジェクトとおなじようにUIを扱えます。
Markerには新しくRotateCameraDirectionスクリプトを作成し取り付けます。
RotateCameraDirectionはAssets/RPG/Scripts/Battleフォルダに置きます。
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 RotateCameraDirection : MonoBehaviour { // Start is called before the first frame update void Start() { transform.rotation = Quaternion.Euler(Camera.main.transform.eulerAngles.x, Camera.main.transform.eulerAngles.y, 180f); } // Update is called once per frame void Update() { transform.rotation = Quaternion.Euler(Camera.main.transform.eulerAngles.x, Camera.main.transform.eulerAngles.y, 180f); } } |
RotateCameraDirectionはカメラの向きにアイコンを表示します。
Markerを選択した状態で右クリックからUI→Imageを選択し、インスペクタのImageにAssets/StandardAssets/CrossPlatformInput/SpritesのButtonAcceleratorOverSpriteを設定します。
RectTransformのAnchor Presetsでstretch stretchを選びます。
ヒエラルキー上のImageゲームオブジェクトを選択した状態でCtr+Dキーを押し複製したら名前をImage2とします。
Image2をドラッグしImageの上に持っていきます。
これはImage2は現在ターンが回ってきているキャラクターのアイコンで、Imageは攻撃等の対象者のアイコンとして使いますが、アイテム使用者とアイテム使用対象者が同じ場合に手前にImageを表示する為です。
ヒエラルキー上で上にある方が画面上で奥に表示されるのでこのようにしています。
Image2のインスペクタでColorを赤色にします。
アイコンは最初は表示させないのでImageとImage2のインスペクタで名前の横のチェックを外し最初は見えないようにしておきます。
BattleUnityChanと同じようにBattleYujiにも作成します。
Assets/RPG/Prefabs/Characters/Enemyフォルダの戦闘用の敵キャラクターはMarker子要素にはImageだけを作成します。
これは敵の行動時にはImage2は使わないからです。
選択中のキャラクターアイコンを表示するスクリプト
現在行動中の味方キャラクターのアイコンと攻撃等の対象者のキャラクターのアイコンを表示する処理を記述します。
現在行動中の味方キャラクターのアイコンを表示・非表示をする
現在行動中の味方キャラクターの頭上のアイコン(Image2)を表示する為の処理を追加します。
まずは味方キャラクターのターンが回ってきた時にアイコンを表示する必要があるので、BattleManagerスクリプトのAllyAttackメソッドに処理を追加します。
AllyAttackメソッドの最初に処理を追加します。
1 2 3 4 5 6 | // 味方の攻撃処理 public void AllyAttack(GameObject character) { character.transform.Find("Marker/Image2").gameObject.SetActive(true); |
引数で受け取った攻撃者のゲームオブジェクトの子要素のMarker/Image2ゲームオブジェクトを取得し、SetActiveメソッドでアクティブにします。
後は起こす行動を選択した後にこのゲームオブジェクトを非アクティブにする必要があります。
逃げるを選択した時はBattleManagerスクリプトで処理が完結しているのでBattleManagerスクリプトのGetAwayメソッドに処理を追加します。
1 2 3 4 5 | // 逃げる public void GetAway(GameObject character) { character.transform.Find("Marker/Image2").gameObject.SetActive(false); |
逃げる以外の行動はそれぞれのキャラクターのCharacterBattleScriptのChooseAttackOptionsメソッドを呼び出しているので、そこでアイコンを非表示にします。
1 2 3 4 5 6 7 8 9 | // 選択肢から選んだモードを実行 public void ChooseAttackOptions(BattleState selectOption, GameObject target, Skill skill = null, Item item = null) { if(characterStatus as AllyStatus != null) { transform.Find("Marker/Image2").gameObject.SetActive(false); } } |
ChooseAttackOptionsメソッドは敵の行動処理でも呼ばれるのでAllyStatusにキャスト出来るかどうかを判定し、キャスト出来ればアイコンを非表示にしています。
CharacterBattleScriptのGuardメソッドにも処理を追加します。
1 2 3 4 5 6 7 | // 防御 public void Guard() { if (characterStatus as AllyStatus != null) { transform.Find("Marker/Image2").gameObject.SetActive(false); } |
行っていることは同じです。
攻撃等の対象者のキャラクターアイコンを表示する
攻撃等の対象者を選択している時にアイコンを表示する場合は現在選択している対象者がわからないといけません。
つまりSelectCharacterPanelの子要素に作成したキャラクター選択ボタンを選択したら、そのボタンのキャラクターの頭上のアイコンを表示します。
なのでSelectCharacterPanelに作成するボタンであるBattleCharacterButtonプレハブに新しくCharacterSelectionスクリプトを作成し取り付けます。
BattleCharacterButtonプレハブはAssets/RPG/Prefabs/UI/BattleCommandフォルダにあります。
CharacterSelectionスクリプトはAssets/RPG/Scripts/Battleフォルダに置いておきます。
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 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class CharacterSelection : MonoBehaviour, ISelectHandler, IDeselectHandler, ISubmitHandler, IPointerDownHandler { private GameObject characterMarker; private void Start() { characterMarker = GameObject.Find("Characters" + transform.Find("Text").GetComponent<Text>().text).transform.Find("Marker/Image").gameObject; if(EventSystem.current.currentSelectedGameObject == this.gameObject) { characterMarker.SetActive(true); } } private void OnDestroy() { // characterMarkerがnullでなければマーカーを非表示 if (characterMarker != null) { characterMarker.SetActive(false); } } public void OnSelect(BaseEventData eventData) { characterMarker.SetActive(true); } public void OnDeselect(BaseEventData eventData) { if (characterMarker != null) { characterMarker.SetActive(false); } } public void OnSubmit(BaseEventData eventData) { characterMarker.SetActive(false); } public void OnPointerDown(PointerEventData eventData) { characterMarker.SetActive(false); } } |
CharacterSelectionスクリプトではインタフェースを継承してボタンが選択されたり(OnSelect)、選択解除されたり(OnDeselect)、オブジェクトが押された時(OnPointerDown)ボタンが押された時(OnSubmit)、のメソッドを実装しています。
OnDestroyはスクリプトが設定されたゲームオブジェクト(キャラクター選択のボタン)が削除された時に呼ばれるメソッドでアイコンがまだ存在していればアイコンを非表示にしています。
OnDestroyは対象者のキャラクターを選択しているSelectCharacterPanelからMagicOrItemPanelやCommandPanelに戻った時にアイコンを非表示にする必要がある為に処理を記述しています。
Startメソッドでこのボタンの子要素のTextに入っている戦闘中のキャラクター名でCharactersゲームオブジェクトの子要素からゲームオブジェクトを探し出し、そのゲームオブジェクトの子要素のMarker/Imageゲームオブジェクトを取得します。
OnDeselectメソッドでは既にcharacterMakerが削除されているというエラーが出たのでnullかどうかを確認しています。
これでSelectCharacterPanelにボタンが生成されたらそのボタンにはCharacterSelectionスクリプトが設定されているので、選択や選択解除等をすると指定したゲームオブジェクトのアイコンがオン・オフされます。
これで機能が出来ましたので、実際に試してみましょう。
上のようになりました。
終わりに
現在どのキャラらクターに対して攻撃やアイテム使用をしているかがアイコンでわかりやすくなりましたね。

この作品はユニティちゃんライセンス条項の元に提供されています