4DCで触ったinterfaceの話
以前参加したCyberAgentさん主催 『プロトスプリントリーグ』 で知ったIntaerfaceを実際に4DCという4日間でランダムに組んだメンバーとゲームを作ろうというプロジェクトで組み込んだ時の学びを忘れないように記録している記事になります。
1.interfaceって何ぞ?
interfaceとは,クラス間で共通のメソッドを定義するための仕組みの事を表しています。これにより,異なるクラスが同じメソッドを実装することで,共通の動作を保証することができます。interfaceは、特定のクラスの継承関係に影響を与えずに異なるクラスが同じインターフェースを実装できるため,柔軟性のある設計が可能となります。(自分も触り始めなので認識が間違ってたらすみません)
2.仕様とそれに対するアプローチ
Player側がEnemyに触れると1ダメージだけもらうという処理を書いていきます。Player側はHPは5つ分だけ持っていて0になるとゲームオーバーとなる。
2-1.タグ管理のデメリット
今までは触れた判定をタグで管理していたのですが,これに関するデメリットは主に2点ほど存在します。
結合度の高さ: タグが直接コードに埋め込まれるため,オブジェクトの特定のタグに依存した処理がコード内に散在します。これにより,コードの保守性が低下し,変更が困難になることがあります。(今までのプロジェクトがこれでした…チーム開発ではマズイけど対策取れてなかった…)
拡張性の低さ: 新しいオブジェクトタイプを追加する場合,そのオブジェクトに対するダメージ処理のために新たなタグを作成し,コードを変更する必要があります。これが増えると,管理が乱雑になります。後々,大変で後悔する羽目になる!!
2-2.interfaceにするメリット
例えば,すべてのダメージを受ける可能性があるオブジェクトが IDamageable というInterfaceを実装することで,ダメージ処理の一貫性を確保する事ができます。これに関しては簡単に3点ほど挙げられます。
低い結合度: オブジェクトの種類に依存せず,共通のInterfaceを介してダメージ処理が行われるため,コード内の依存関係が減少します。変更が発生しても影響を受ける範囲が狭まります。
柔軟な拡張性: 新しいオブジェクトタイプを追加する場合,そのオブジェクトが IDamageable というInterfaceを実装するだけで,ダメージ処理が可能になります。既存のコードを変更する必要はありません。
コードの一貫性: 同じインターフェースを実装するすべてのオブジェクトに対して,同じ方法でダメージ処理が行われるため,コードの一貫性が保たれます。
要するに,Interfaceを使用するアプローチは,コードの保守性と拡張性を高めるために有利です。特定のタグに依存せず,共通の方法でダメージ処理を行いたい場合にInterfaceは非常に役立つツールです。現段階で知れて良かった。
3.Interfaceの実用
今回使用したコードを基にどの様に活用していくのか紹介できたらと思います。
3-1.Interface部分
IDamageableというスクリプトを書いておいて,いつでも呼び出せるようにしておきます。
public interface IDamageable
{
int AddDamage();
}
3-2.Enemyに搭載するダメージ処理部分
ダメージを1だけ与える処理を書いていきます。これをEnemy側に割り当てていきます。
public class BaseDamage : MonoBehaviour, IDamageable
{
public int AddDamage()
{
return 1;
}
}
3-3.プレイヤー側のHP処理
初期HPを5と定義しておいてダメージ毎に減少していく事と,HP=0のタイミングでゲームオーバーにする処理を書いていきます。
public class PlayerHP : MonoBehaviour
{
private int _hp = 5;
public void LifeGauge(int damage)
{
if (_hp > 0)
{
_hp -= damage;
if (_hp <= 0)
{
Debug.Log("Game Over");
}
}
}
}
3-4.プレイヤー側のダメージ処理
実際にEnemy側から受け取ったダメージ処理をPlayer自身のHPに反映させる処理を書いていきます。
public class PlayerDamage : MonoBehaviour
{
PlayerHP playerHP;
void Start()
{
playerHP = GetComponent<PlayerHP>();
}
private void OnTriggerEnter2D(Collider2D col)
{
var target = col.GetComponent<IDamageable>();
if (target != null)
{
int DamageNum = target.AddDamage();
playerHP.LifeGauge(DamageNum);
Debug.Log("ダメージを与えた");
}
}
}
こんな感じで書いて割り当てると実装できます。
4.まとめ
初めて触ったInterfaceを自分なりにまとめた記事どうでしたか?
自分が書いたコードが間違ってたら教えて下さい。急いで変更します。それとお願いがあるのですが,もしここまで読んでいただいた方の中でUnity触る上でこんな便利なTipsあるよ(UniTask,UI Tool kitとか)という方教えて下さい。泣いて喜びます!!
言い訳にはなりますが,まだまだ勉強途中で解りにくい表現や間違った表現があるかも知れません。これから先その間違えに気付いてコソッとこの記事に変更を加えている可能性がありますが,もし気付いた方は「あっ,あいつ少しは理解できたんだな」ぐらいに思って貰えると幸いです。
5.最後に
改めまして、最後まで読んでくださり、ありがとうございました!
noteを読んだご感想やアドバイス、気軽にコメントください!
今後の勉強や発信の参考にさせていただきます。
確認不足による規約違反が見られた場合は削除対応するので、お手数ですがコメント欄でお知らせください。
この記事が気に入ったらサポートをしてみませんか?