31
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Unity】ポケモンのようなターン制ゲームを作ってみた 〜ターン終了時の処理〜

Last updated at Posted at 2018-02-25

ポケモンのようなターン制のゲームを開発してまして、そこで上手く実装できた部分の書き方を共有します。続いたり続かなかったり。今回はターン終了時の処理です。

#概要

  • ポケモン風ターン制ゲームとは
  • ポケモンにおけるターン終了時の処理
  • StateMachine (ステートマシン)とは
  • Coroutine (コルーチン)とは
  • コードサンプル
  • 解説

#ポケモン風ターン制ゲームとは
以下の特徴を持ったゲームです

  • ターン開始時にお互いがわざ選択を行う
  • キャラクターは素早さ順に行動する
  • わざはダメージを与えたり、特殊効果を持つ
  • キャラクターが先に全滅すると負け

#ポケモンにおけるターン終了時の処理
ざっとこんだけあります

1.天候解除(→ギフト/てんきや)→天候ダメージ/サンパワー/かんそうはだ/あめうけざら/アイスボディ
2.みらいよち/はめつのねがい
3.ねがいごと
4.だっぴ/うるおいボディ/いやしのこころ
 →くろいヘドロ/たべのこし/グラスフィールドの回復
5.アクアリング
6.ねをはる
7.やどりぎのたね 
8.どく/もうどく/ポイズンヒール 
9.やけど 
10.あくむ 
11.呪い 
12.しめつける状態解除
 →しめつける/まきつく/うずしお/マグマストーム/すなじごく/ほのおのうず/からではさむ/まとわりつく
13.あくび 
14.ほろびのうた 
15.ちょうはつ 
16.アンコール 
17.かなしばり 
18.でんじふゆう 
19.かいふくふうじ 
20.さしおさえ 
21.リフレクター 
22.ひかりのかべ 
23.しんぴのまもり 
24.しろいきり 
25.おいかぜ 
26.おまじない 
27.トリックルーム 
28.じゅうりょく 
29.みずあそび/どろあそび 
30.ワンダールーム 
31.マジックルーム 
32.グラスフィールド/エレキフィールド/ミストフィールド 
33.さわぐ
 →ナイトメア/しゅうかく/ものひろい/ムラっけ/どくどくだま/かえんだま/くっつきバリ

引用元

これらの詳しい効果について知る必要はありません。
重要なのは、各処理は行われる場合と行われない場合があり、処理が行われる場合には、「順番に」エフェクトやUI表示を行う必要があるということです。

#ステートマシンとは
ポケモンのようなターン制ゲームの場合、わざを選択するタイミング、わざを出すタイミング、ターン終了時の処理をするタイミングなど、ゲームの状態を見て進行を管理する仕組みが必要です。
そういった仕組みを「ステートマシン」と呼びます。詳しくは割愛するので知らない方は調べてみてください。

#コルーチンとは
簡単に言うと一定時間処理を止められる仕組みです。
今回で言えば、例えば毒状態で毒ダメージを受けている間は処理を止めておき、それが終わったら次は宿り木の種の処理を行う、といった制御が必要です。
そういった制御にピッタリなのがコルーチンで、これを使った実装方法を紹介します。

#コードサンプル
論点でない部分のコードは割愛しています。

TurnStateMachine.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TurnStateMachine : MonoBehaviour
{
	public Pokemon myPokemon;
	public Pokemon enemyPokemon;

	List<Pokemon> SortedPokemons = new List<Pokemon> ();

	/* ターン終了時の処理に関わる部分以外は割愛 ステートマシンで制御します*/

	void StartTurnEndProcessing()
	{
		//コルーチンを開始
		StartCoroutine(TurnEndProcessing());
	}

	//コルーチン処理
	IEnumerator TurnEndProcessing ()
	{
		//1.勝敗判定
		if (CheckAlive()) {
			yield break;
		}

		//2.同速チェックと並び替え
		bool isSame = Sort ();

		//3.天候解除
		if (WeatherProcessing ()) {
			yield return new WaitForSeconds (1f);
		}

		/* 中略 */

		//4.素早さが同じ場合は順番をシャッフルする
		Shuffle (isSame);

		//5.毒ダメージ
		foreach (var item in SortedUnits) {
			if (PoizonProcessing (item)) {
				yield return new WaitForSeconds (0.5f);
			}
		}

		/* 中略 */

		//6.勝敗判定
		if (CheckAlive()) {
			yield break;
		}

		//7.交代の有無を確認
		if(CheckChange()){
			//交代の処理
			CharacterChange();
		} else {
			//ターン開始に移る処理
			TurnStart();
		}
	}

	bool Sort ()
	{
		//myPokemonとenemyPokemonの素早さを比較
		//素早さが高い順にSortedPokemonsにAddする
		//素早さが同じ場合はtrue,それ以外はfalseを返す
	}

	void Shuffle (bool isSame)
	{
		//素早さが同じ場合は順番のシャッフルを行う
		//素早さが同じでない場合は何もしない
	}

	bool WeatherProcessing ()
	{
		//天候解除の有無を判定する
		//天候解除ありの場合はエフェクトやUI表示を更新してtrueを返す
		//それ以外はfalseを返す
	}

	bool PoizonProcessing (Pokemon pokemon)
	{
		//pokemonが瀕死状態ならfalseを返して終了する
		//pokemonが毒状態ならエフェクトと毒ダメージの処理を行う
		//それ以外はfalseを返す
	}

	bool CheckAlive()
	{
		//対戦の勝敗判定を行う
		//勝ちまたは負けの判定が出た場合はtrueを返す
		//それ以外はfalseを返す
	}

	bool CheckChange()
	{
		//交代の有無を判定して交代が必要な場合はtrueを返す
	}

	void CharacterChange()
	{
		//ポケモンの交代の必要があれば交代画面に映る
	}

	void TurnStart()
	{
		//ターン開始時に移る
	}
}

#解説
以下がポイントです。

  • 最初に勝敗判定を行って、勝敗が決する場合は処理を行わない//1.参照

  • 砂嵐ダメージなどポケモン毎に行う処理は、素早さ順で行われる。
     →最初に素早さ順でListに追加しておき、List内の順番に沿って処理する。//2.参照

  • 素早さが同じ場合は処理毎に素早さ順の判定を行う。
     →素早さが同じ場合だけシャッフル処理を行う。//4.参照

  • エフェクト表示やUI更新が必要な時だけ待機時間を設ける
     →個別の処理は処理の有無をbool値で返して、trueの時のみ待機する。//3,5.参照
     →コルーチンの待機時間はyield return new WaitForSeconds (float);で表せます。

  • 毒ダメージなどでターン終了時の処理中にポケモンが瀕死になる場合があるため、最後の方で再度勝敗判定を行う。//6.参照

以上、マニアック気味の内容でした。
他のターン状態を管理する処理については割愛しています。

もし参考になった場合はいいねをお願いします。

31
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?