本投稿は2024年9月時点の内容になります。アップデートにより変更となる場合があります。また環境によって違いがあると思いますのであくまで参考として、ご了承ください。
様々な書籍、ブログや動画を参考にさせていただきました。多すぎて一つ一つは紹介できませんが感謝です。
初心者の自分がUnity ソフトウエアでゲームを作ってみました。とりあえずシンプルなものということでモグラたたきに挑戦です。ゲーム作ってみるかという感じになったときに、いいタイミングで某ゲームのイベントシナリオ内ミニゲームにモグラたたきが実装されていたのでUIとかエフェクトとか、諸々の仕様をぱくって参考にして作ってみましたよ。様々なHowToの中の選択肢のひとつとして、同じ初心者さんの参考になればよいです。
\ チェック /
目次
モグラたたきのくせにバトルシステムを作ってみる
敵のゲームオブジェクトがだいぶ固まって、前回はプレイヤーも実装しました。
なので今回はクリックでなんちゃってバトルをさせたいと思います。はっきり言ってモグラたたきには冗長ですが、シンプルなゲームに導入することで見えてくるものもあるかもしれません。たぶん。。。
本記事のポイント
- 「BattleManager」を作って、プレイヤーターンと敵ターンを使ったなんちゃってバトルシステムを作って実行してみる
今回の記事を読む前に「Enemy」クラスと「UnitStatus」クラスについて書いているこちらもチェックしてみてください。
BattleManagerを作成する
BattleManagerを作成する
- プロジェクトでスクリプト「BattleManager」を作成。
- ヒエラルキー上に「BattleManager」の名前で「空のオブジェクトを作成」。このスクリプトをアタッチします。
BattleManagerとEnemyControllerクラスにバトル関連のメソッドを書く
今回のバトルの仕様を考えてまとめてみます
この後コーディングしやすいように、モグラたたき的にどのようなバトルにするかまとめてみます。
バトルの仕様
- 敵キャラの状態がPositiveの時はプレーヤーターンの攻撃
- 敵キャラの状態がAngerの時はエネミーターンの攻撃
- バトルのタイミング①クリックされたとき
- バトルのタイミング②クリックされずにしゃがんだとき
- クリックされたときEnemyタイプの敵は状態がPositiveに
- クリックされたときJammerタイプの敵は状態がAngerに
- クリックされなかったときEnemyタイプの敵は状態がAngerに
- クリックされなかったときJammerタイプの敵は状態がPositiveに
- しゃがみ状態になったときはタイプに限らず状態Runawayを付加する
BattleManagerクラスのスクリプト
スクリプトを作成する
- 「using UnityEngine;」以下に下記のようにコーディングしました。
- ゲームオブジェクト「BattleManager」の「BattleManager」スクリプトに「Player」オブジェクトをアサイン。
public class BattleManager : MonoBehaviour
{
[SerializeField] Player player;
PlayerStatus _player;
//playerStatusをセット
public void SetPlayer()
{
_player = player.playerStatus;
}
//戦闘
public void Battle(Enemy enemy)
{
EnemyStatus _enemy = enemy.enemyStatus;
//_PlayerにplayerStatusをセット
SetPlayer();
//バトルの仕様1
//enemyの状態がPositiveならPlayerターンの戦闘
if (_enemy.Status.HasFlag(Statuses.Positive))
{
PlayerTurn(enemy);
}
//バトルの仕様2
//enemyの状態がAngerならEnemyターンの戦闘
else if (_enemy.Status.HasFlag(Statuses.Anger))
{
EnemyTurn(enemy);
}
}
//Playerターンの戦闘
public void PlayerTurn(Enemy enemy)
{
EnemyStatus _enemy = enemy.enemyStatus;
//UnitStatusクラスのメソッド
_player.Attack(_enemy);
//確認用のログ
Debug.Log("プレーヤーの攻撃:" +_enemy.Name+"のライフ"+_enemy.CurrentHp);
if (_enemy.Status.HasFlag(Statuses.Dead))
{
//EnemyがDeadのステータスを持っていたらPlayerのスコア加算、今回はEnemyの経験値Expをスコアとして加算
_player.UpdateScore((int)_enemy.Exp);
}
}
//Enemyターンの戦闘
public void EnemyTurn(Enemy enemy)
{
int playerHp;
playerHp=_player.CurrentHp;
EnemyStatus _enemy = enemy.EnemyStatus;
_enemy.Attack(_player);
if (playerHp > _player.CurrentHp)
{
CheckPlayerDead()
}
}
public void CheckPlayerDead()
{
if (_player.Status.HasFlag(Statuses.Dead))
{
}
}
}
スクリプトざっくり解説
- (7-10)_playerにplayerStayusをセット
- (13-32)バトルのメインです。上記のバトルの仕様の1と2を実装してます
- (35-47)プレーヤーターンの攻撃処理 敵がDeadになったら経験値を獲得(今回はモグラたたきなので、スコアに反映させています)
- (49-59)エネミーターンの攻撃処理
- (61-67)プレーヤーの死亡判定処理
//Playerスコアにscore分加算
public void UpdateScore(int score)
{
Score += score;
}
スクリプトざっくり解説
- Playerクラスにスコア加算のメソッドを追加
//生死判定
public void CheckLife()
{
if (CurrentHp == 0)
{
//HPが0なら状態にDeadを加える
AddStatus(Statuses.Dead);
}
}
スクリプトざっくり解説
- UnitStatusクラスに生死判定を追加
EnemyControllerクラスのスクリプトへの追加です
スクリプトを作成する
- 「OnPointerDown」に下記のコードを追加。
- ゲームオブジェクト「Unitychan」の「Enemy」スクリプトに「BattleManager」オブジェクトをアサイン。
public void OnPointerDown(PointerEventData eventData)
{
//アニメーターにトリガーを渡す
enemyMove.SetTrigger("HasClicked");
//クリックされたときのアクション
ClickedEnemyAction();
}
public void ClickedEnemyAction()
{
EnemyStatus _enemy=enemy.EnemyStatus;
switch (_enemy.UnitType)
{
case UnitType.enemy:
//enemyタイプなら状態Positiveを加える
_enemy.AddStatus(Statuses.Positive);
break;
case UnitType.jammer:
//jammerタイプなら状態Angerを加える
_enemy.AddStatus(Statuses.Anger);
break;
default:
Debug.Log("enemyタイプエラー");
break;
}
//戦闘開始
BattleManager.Battle(enemy);
}
スクリプトざっくり解説
- (1-7)クリックイベント。
- (6,9-33)クリックされたときのアクション
- (15-18)バトルの仕様5を実装。
- (20-23)バトルの仕様6を実装。
- (31)バトルの仕様3を実装
スクリプトの実行確認
ここで一旦ゲーム再生して仕様通りに動作するか確認します。
実行確認
- ゲーム再生してUnitychanをクリック。コンソールを確認。
- ScriptableObject「CharacterStatusDB」のUnitychanのUnitTypeを「Jammer」に変更。再度ゲーム再生してUnitychanをクリック。コンソールを確認。
仕様通りの結果がコンソールに出ていればOKです。
\ 「Enemy」クラス「UnitStatus」クラスについてはこちらをチェック /
\ ScriptableObjectについてはこちらをチェック /
問題点
さて、実はこのスクリプトですが問題点があります。気づいた方もいると思うのですが、実は何回も叩けてしまいます。この問題点はフラグで管理すれば解決できるのですが、今回の場合はもっとシンプルで強力な方法があります。
それはアニメーションクリップのタイムラインの中で処理する方法、アニメーションイベントです。
タイミングが難しそうなバトルの仕様4、7、8、9もアニメーションイベントと組ませると簡単です。というわけで次回のアニメーションイベントの解説につづきます。
まとめ
まとめ
- 複雑そうなコードもしっかり書き出して整理すれば怖くない。。。たぶん
\ Unityのスクリプトを書くのに役立ちます /
もっと早く教えてほしかった!Unity C#入門
MARU
おすすめ記事
Unity ソフトウエアでゲーム制作#1モグラたたき編(28.ゲームに効果音…
Unity ソフトウエアでゲーム制作#1モグラたたき編(27.エフェクト2パ…
Unity ソフトウエアでゲーム制作#1モグラたたき編(26.エフェクトその1)
Unity ソフトウエアでゲーム制作#1モグラたたき編(25.プレハブバリア…
Unity ソフトウエアでゲーム制作#1モグラたたき編(24.Buttonで…
Unity ソフトウエアでゲーム制作#1モグラたたき編(23.シンプルなアニ…