今回はユニティちゃんRPGの戦闘シーンで戦闘が開始したらユニティちゃんが装備している武器をユニティちゃんに持たせるようにします。
前回は戦闘シーンでのメッセージ表示機能を作成しました。

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

から見ることが出来ます。
大鳥ゆうじは元々持っていた武器を装備させたので武器の装備を切り替えても持っている武器のオブジェクトは変えないようにします。
ユニティちゃんはずっと素手だったのでユニティちゃんが装備している武器のオブジェクトを戦闘開始時にユニティちゃんの右手に持たせるようにしてみます。
持っている武器のオブジェクトを変更して装備させるのは武器の見た目が変わるので楽しいですが、その分、武器の3Dオブジェクトを用意する必要が出てくるのが大変な所です。
武器の簡易3Dオブジェクトを作成する
武器の3Dオブジェクトを用意するのが大変なので今回はUnityのプリミティブなオブジェクトで武器のオブジェクトを作成します。
既に武器の3Dオブジェクトを用意している場合は特に作る必要はありません。
ただ武器の3Dオブジェクトの持ち手の位置や角度を合わせる時に同じように空のゲームオブジェクトを作成すると個別にデータスクリプトを設定する必要がなくなるかもしれません。
ヒエラルキー上で右クリックからCreate Emptyを選択し、名前をIronSwordとします。
ヒエラルキー上で右クリックから3D Object→Cubeを選択し、CubeのTransformのXとYを0.05、Zを1.2とします。
マニピュレータの方向をLocal表示にした状態でIronSwordとCubeのZ軸(青色の軸)が同じ方向を向くようにします。
IronSwordを選択してマニピュレータで動かしてCubeを剣のオブジェクトと想定して持ち手となる位置に動かします。
位置を動かしたらCubeをドラッグしてIronSwordの子要素にします。
Assets/RPG/Prefabs/Item/Weaponフォルダを作成しそのフォルダにヒエラルキー上のIronSwordをドラッグ&ドロップしてプレハブにします。
ヒエラルキー上のIronSwordは削除します。
Assets/RPG/Prefabs/Item/Weapon/IronSwordを選択しCtrl+Dキーで複製し、名前をBlueSwordとします。
同じフォルダ内で右クリックからCreate→Materialを選択し名前をBlueSwordとし、Albedo横の色を青色にします。
BlueSword子要素のCubeのMaterialsのElement0にBlueSwordマテリアルを設定します。
これでIronSwordとBlueSword用の3Dオブジェクトが出来ました。
Itemデータにオブジェクトデータを追加し武器データでオブジェクトを設定
武器の3Dオブジェクトが出来たのでItemスクリプトにそのアイテムのオブジェクトを設定するフィールドとゲッターを用意します。
Assets/RPG/Scripts/ItemフォルダのItemスクリプトを開き、フィールドとメソッドを追加します。
1 2 3 4 5 6 7 8 9 10 | // アイテムのオブジェクト [SerializeField] private GameObject itemObject = null; // アイテムのオブジェクトを返す public GameObject GetItemObject() { return itemObject; } |
Assets/RPG/Data/ItemData/WeaponフォルダのIronSwordデータとBlueSwordデータのitemObjectに先ほど作成したIronSwordプレハブとBlueSwordプレハブを設定します。
他の武器にオブジェクトを設定していると大変なのでこの二つだけ設定することにします。
これでこの二つの武器のオブジェクトが設定されました。
ユニティちゃんにBlueSwordを装備させる
ユニティちゃんにBlueSwordを装備させます。
Assets/RPG/Data/Status/Ally/UnityChanStatusのEquipWeaponにBlueSwordデータを設定します。
戦闘用ユニティちゃんプレハブの右手に武器を装備する場所を作成
Assets/RPG/Prefabs/Characters/Ally/BattleUnityChanを選択しインスペクタのOpen Prefabボタンを押して、ボーンの階層を辿りCharacter1_RightHandを選択し、右クリックから3D Object→Cubeを選択し名前をEquipとします。
EquipのTransformのScaleのXYZを全て0.1にして、右手の位置に移動させ、マニピュレータをLocal表示にしてZ軸方向(青い軸)が武器の剣先となるように回転させます。
移動と回転が終わったら必ずTransformのScaleのXYZを1に戻します。
戻さない場合は武器の形状が歪んでしまうので注意してください。
EquipのTransform以外のコンポーネントのCube(MeshFilter)、MeshRenderer、BoxColliderは使わないので削除するか名前の横のチェックを外し無効化しておきます。
上のような感じになりました。
戦闘開始時にユニティちゃんの武器を持たせるスクリプトの作成
戦闘開始時にユニティちゃんが装備している武器のオブジェクトをユニティちゃんの右手のEquipにインスタンス化するスクリプトInstantiateWeaponスクリプトを
Assets/RPG/Scripts/Battleフォルダに作成し、Assets/RPG/Prefabs/Characters/Ally/BattleUnityChanプレハブに取り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class InstantiateWeapon : MonoBehaviour { [SerializeField] private Transform equip; // Start is called before the first frame update void Start() { var characterStatus = (AllyStatus)GetComponent<CharacterBattleScript>().GetCharacterStatus(); if (characterStatus.GetEquipWeapon() != null) { if (characterStatus.GetEquipWeapon().GetItemObject() != null) { Instantiate<GameObject>(characterStatus.GetEquipWeapon().GetItemObject(), equip.position, equip.rotation, equip); } else { Debug.LogWarning("装備武器のゲームオブジェクトが設定されていません。"); } } } } |
equipは先ほどBattleUnityChanの右手の子要素に作ったEquipをインスペクタで設定します。
Startメソッドで自身のゲームオブジェクトのCharacterBattleScriptを取得し、GetCharacterStatusメソッドでユニティちゃんのステータスデータを取得し、それをAllyStatusにキャストしてcharacterStatusに入れます。
characterStatus.GetEquipWeapon()がnullでない時はユニティちゃんが武器を装備しているのでcharacterStatus.GetEquipWeapon().GetItemObject()で武器のオブジェクトを取得しそれをインスタンス化しています。
インスタンス化したオブジェクトの位置と回転はEquipゲームオブジェクトと同じにし、インスタンス化したゲームオブジェクトの親はEquipゲームオブジェクトにします。
武器のゲームオブジェクトが設定されていなければコンソールにその旨を表示します。
これで戦闘開始時に武器を装備していたらその武器のオブジェクトをユニティちゃんの持たせることが出来ます。
ただ武器の持ち手の位置や角度は武器事に変わってくると思いますので本来であれば武器をインスタンス化した時の位置や角度データを武器に持たせておいてその位置や角度を設定する事も出来ます。
ここら辺は

や

辺りを参照してみてください。
スクリプト等にデータを保持しなくても、今回プリミティブな形状から武器を作成した時のように空のゲームオブジェクトを使って
武器の3Dオブジェクトの持ち手の位置や角度を合わせれば、個別にデータスクリプトを設定する必要がなくなるかもしれません。
こうすれば武器の実際のゲームオブジェクトSwordの親のゲームオブジェクトの位置と回転を変更するだけで良くなります。
これで機能が出来上がりました。
実行して確認してみましょう。
上のようになりました。
途中で停止し、UnityChanStatusのEquipWeaponをIronSwordにして再び戦闘をして確認しています。
終わりに
装備している武器に合わせて違うオブジェクトが表示されるとちょっとうれしいですね。
武器の総数が多い場合は3Dオブジェクトを作成するのが大変そうですけど・・・・。
今回は戦闘中に武器や防具を変更出来るようにしていませんが、戦闘中もアイテム一覧に武器・防具を表示出来るようにして変更出来るようにし、InstantiateWeponスクリプトで変更した時に現在装備中の武器のインスタンスを削除し、今装備を切り替えた武器のオブジェクトをインスタンス化するようにすると良いと思います。

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