敵味方の区別【UnityでRTSを作る 4】
今回は戦闘には欠かせない敵味方の区別を行います。
レイヤー
プレイヤー、味方、敵、味方の弾、敵の弾のレイヤーを用意しました。
当たり判定
レイヤーの当たり判定をいじります。
プレイヤー及び味方の弾は敵だけに当たり、
敵の弾はプレイヤー及び味方だけに当たります。
また、弾がぶつかり合うことはありません
レイヤーを変更するための拡張メソッド
スクリプトからレイヤーの一括変更を行うのが結構めんどくさかったので、
そのための拡張メソッドを用意しました。
GameObjectExtension.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public static class GameObjectExtension { public static void SetLayer (this GameObject gameObject,int layer, bool needSetChildrens = true) { if(!gameObject) return; gameObject.layer = layer; if(!needSetChildrens) return; foreach(Transform childTransform in gameObject.transform) SetLayer(childTransform.gameObject,layer,needSetChildrens); } public static void SetLayer (this GameObject gameObject,string layerName,bool needSetChildrens = true) { SetLayer(gameObject,LayerMask.NameToLayer(layerName),needSetChildrens); } }
GameObjectの子要素のレイヤーも一括で変更できるようになります。
陣営を分ける
ここから実際に陣営を分けていきます。
そのために陣営を表す列挙型を用意しました。
public enum Team { Ally, Enemy }
ユニットの陣営分け
PlayerとNPCの基底クラスのCubeKunクラスに陣営を表す抽象プロパティを用意します。
CubeKun.cs
public abstract Team Team { get; set; }
つまりCubeKunを継承しているPlayerとNPCには別々の処理を記述します。
Player.cs
public override Team Team { get { return Team.Ally; } set { throw new NotImplementedException(); } }
Playerは必ず味方陣営に所属します。
NPC.cs
public override Team Team { get { return _Team; } set { gameObject.SetLayer(value.ToString()); _Team = value; } } [SerializeField] private Team _Team = Team.Ally; private void OnValidate () { Team = _Team; }
Setterに自動でレイヤーを変更する処理を用意しました。
陣営変更時に自動でレイヤーも変更してくれるやつ pic.twitter.com/Pt4jkXBbnE
— Macky (@macky_soft) 2017年4月17日
武器の陣営分け
前回の武器のソースコードから変更点があります。
弾の発射は前回ではWeaponクラスのShoot関数で行っていましたが、
今回からはBulletクラスのShot関数を呼ぶことになります。
そこに弾のレイヤーを変更する処理を挿みます。
Bullet.cs
public CubeKun Parent { get; private set; } public void Shot (Transform point,CubeKun parent,int power,float speed,float time) { var ins = Instantiate(this,point.position,point.rotation); Parent = parent; gameObject.SetLayer("Bullet_" + Parent.Team.ToString()); ins.power = power; ins.speed = speed; Destroy(ins.gameObject,time); }
これによりWeaponのShoot関数が簡略化されました。
Weapon.cs
public CubeKun Parent { get; private set; } private void Start () { Parent = GetComponentInParent<CubeKun>(); ShootStart(); } public void Shoot () { for (int i = 0;firingPoints.Length > i;i++) { bullet.Shot(firingPoints[i],Parent,power,speed,time); } }
次回は陣営を分けたNPC同士で戦わせます。