Unity勇者の冒険の書

Unityで学んだことや便利なものなど作ったら紹介します

【Unity勇者の奮闘記】C#のクラスの継承について その2 

前回の続きで、RPGっぽいゲームを作るとしましょう。

そこで敵のプログラムを作ります。

ここで、継承を使うか使わないかで大きく変わってきます!

例えば、継承を使わない方法でやってみましょう

敵の情報は

・HP(体力)
・MP(魔力)
・STR(攻撃力)
・DEF(防御力)
・SPD(速さ)

としましょう


・継承を使わなかった場合

「そうだよ!継承なんて使わなくてもEnemyっていうクラス1つでいいじゃん!」

というAさんがいます。

そんなAさんは、まず、変数を作って、

行動する関数を作って…

using UnityEngine;
using System.Collections;

public class Enemy :MonoBehaviour{

	public string Name;
	public int Hp;
	public int Mp;
	public int Str;
	public int Def;
	public int Spd;

	public enum AttackType
	{
		Physical,
		Magical
	}

	/// <summary>
	/// 開始処理
	/// </summary>
	void Start()
	{
		Init();
	}

	/// <summary>
	/// 初期化
	/// </summary>
	void Init()
	{

	}

	/// <summary>
	/// ダメージを受けたとき
	/// </summary>
	void Damage(int _point,AttackType _attackType)
	{
		Hp -= _point;
		if (Hp <= 0)
			Death();
	}

	/// <summary>
	/// 攻撃するとき
	/// </summary>
	void Attack()
	{

	}

	/// <summary>
	/// 亡くなったとき
	/// </summary>
	void Death()
	{
		Destroy(this.gameObject);
	}
}

こんなかんじでしょうか?

そして、Editor上で編集して…

f:id:LightGive:20151207004502p:plain

f:id:LightGive:20151207004716p:plain

よし、スライムの完成だ!

これでどんどんモンスターを追加する分には問題ありませんが、

ゲームを作るうえで問題が出てきます。

例えば、こんな敵が出てきたとしましょう。

f:id:LightGive:20151207005425p:plain

f:id:LightGive:20151207004834p:plain

見るからに物理が効かなさそうですね…

じゃあこのプログラムを変えようとなりますよね?

Damageの関数を変えてみると…

	/// <summary>
	/// ダメージを受けたとき
	/// </summary>
	void Damage(int _point,AttackType _attackType)
	{
		if (_attackType == AttackType.Physical && Name == "ゴースト")
			_point = 0;

		Hp -= _point;
		if (Hp <= 0)
			Death();
	}


さらにこんな敵も出てきました

f:id:LightGive:20151207010024p:plainf:id:LightGive:20151207010031p:plain
f:id:LightGive:20151207010107p:plainf:id:LightGive:20151207010053p:plainf:id:LightGive:20151207010147p:plain

そうなったとき、こうなりますね?

	/// <summary>
	/// ダメージを受けたとき
	/// </summary>
	void Damage(int _point,AttackType _attackType)
	{
		if (_attackType == AttackType.Physical &&
          ( Name == "ゴースト1") ||
          ( Name == "ゴースト2") ||
          ( Name == "ゴースト3") ||
          ( Name == "おばけ1") ||
          ( Name == "おばけ2") ||
          ( Name == "おばけ3"))
		{
			_point = 0;
		}

		Hp -= _point;
		if (Hp <= 0)
			Death();
	}


いやあああああああああああああ

こうしてスパゲッティソースが出来上がっていきます。

あ、そうだ!変数を作ればいいんだ!

public bool isGhost;

と変数を追加して…

        /// <summary>
	/// ダメージを受けたとき
	/// </summary>
	void Damage(int _point,AttackType _attackType)
	{
		if (_attackType == AttackType.Physical && isGhost
		{
			_point = 0;
		}

		Hp -= _point;
		if (Hp <= 0)
			Death();
	}

「これで問題ないじゃん!」

と、安心したそこのあなた、

RPGをなめてはいけません。

他にもたくさんあります

・空中に浮いている敵
・一定ダメージ以上は効かない敵
・魔法攻撃だとダメージが2分の1になる敵
・魔法攻撃を無効にする敵
・物理攻撃をしたときカウンターをしてくる敵
…etc

などと変数を増やしていくと…

f:id:LightGive:20151207012034p:plain

と、このようにステータスを決める画面はこんな感じで、

Damageの関数はというと…

	/// <summary>
	/// ダメージを受けたとき
	/// </summary>
	void Damage(int _point,AttackType _attackType)
	{
		if (_attackType == AttackType.Physical && isGhost)
			_point = 0;

		if (isFly && _attackType == AttackType.Physical)
			_point = 0;

		if (isAttackInvalid && invalidPoint > _point)
			_point = 0;

		if (isMagicHalf && _attackType == AttackType.Magical)
			_point /= 2;

		if (isMagicInvalid && _attackType == AttackType.Magical)
			_point = 0;

		if (isMagicCounter && _attackType == AttackType.Magical)
			Attack();

		Hp -= _point;
		if (Hp <= 0)
			Death();
	}


いやあああああああああああああ

いや、酷いですね…

大分オーバーにやりましたが、

一体の敵のステータスを決めるだけでもこんなにたくさん

値があるのではどれが何か分からなくなってしまいますね…

これが継承を使うと綺麗になります!

継承をつかった方法は次に!

では('ω')ノ