Corgi Engine覚書(1)〜ワンボタンですり抜け床を降りる〜

Corgi Engineってなに?

  • アクションゲーム制作特化のUnity Assets

  • 2Dと2.5Dに対応

  • 横スクかトップダウンで色々作れる

  • ”完璧な2Dアクションゲームアセット”と言われるだけあって便利

  • 有名どころなので日本語での紹介記事、解説記事も多くて助かる


One-Way Platformの扱い


下からだとぶつからないが上からだと着地できる
  • いわゆるすり抜け床のこと

    • 下からジャンプですり抜けて登ることができる足場

    • 上に乗って↓方向に入力すると降りることもできる

One-Way Platformを降りるには

  • Corgi EngineのOne-Way Platformは降りることができない?

    • ↓方向に入力しても反応なし

  • 登るしかできないのか…ちょっと移動性が落ちるな…

ソイツはCharacterJumpの中にいた…

できるじゃねえかよ

しゃがんでからジャンプで降りる
  • ↓方向の入力とともにジャンプボタンも必要だった

    • S+Spaceキーでいけた

    • ドキュメントに書いてなかったんだが???

    • もしかしてこっちの操作が一般的なのか…?

    • ジャンプで登る場合が多いから、降りるのもジャンプということなのか

  • 登る時は1つのキーだけでいけるのに、降りる時に2つのキーを押さないといけないってややこしくないか?

  • 個人的には↓入力だけで降りたい

    • カービィシリーズの操作感っぽく

One-Way Platformを降りるだけのAbilityを自作する

  • 勉強がてらCharacterAbilityを自作してみる

  • CharacterJumpのJumpdown周りの処理を参考にした

  • ↓完成品

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		private bool steppedDownThrough = false;

		protected override void HandleInput()
		{
			// 地面に着地している場合
			if (_controller.State.IsGrounded)
			{
				// 下方向に入力している場合
				if (_verticalInput < -_inputManager.Threshold.y)
				{
					bool DownThrough = true;
					// すり抜け直後なら拒否する
					if (steppedDownThrough)
					{
						DownThrough = false;
					}
					else
					{
						// プレイヤーが立っているPlatformをチェック
						foreach (GameObject obj in _controller.StandingOnArray)
						{
							if (obj == null)
							{
								continue;
							}
							// OneWayPlatformかStairsじゃない場合はすり抜け失敗
							if (!_controller.OneWayPlatformMask.MMContains(obj.layer) &&
								!_controller.MovingOneWayPlatformMask.MMContains(obj.layer) &&
								!_controller.StairsMask.MMContains(obj.layer))
							{
								DownThrough = false;
							}
						}
					}

					// すり抜け可能なら実行
					if (DownThrough)
					{
						// ジャンプ中扱いにする
						_movement.ChangeState(CharacterStates.MovementStates.Jumping);
						// 横方向の移動をリセットする
						_characterHorizontalMovement.ResetHorizontalSpeed();
						// OneWayPlatformの衝突判定を一瞬だけ解除 解除する時間を指定する
						StartCoroutine(_controller.DisableCollisionsWithOneWayPlatforms(0.3f));
						// MovingPlatformの慣性を解除
						_controller.DetachFromMovingPlatform();
						// すり抜け直後のフラグを立てる
						steppedDownThrough = true;
					}
				}
				// 下方向への入力してない場合
				else
				{
					// すり抜け直後のフラグをリセット
					steppedDownThrough = false;
				}
			}

		}

	}

}

ツールを追加

  • まずはツールを追加しなくては始まらない

    • MoreMountainsはCorgi Engineの開発元のことらしい

using UnityEngine;
using MoreMountains.Tools;

名前空間を設定

  • 名前空間もCorgiEngineを追加しないと始まらない

    • 公式ドキュメントで任意の名前を追加していいってあったので、自作Abilityだと見分けるために名前を追加しておく

    • CorgiEngineの後ろに.〇〇で追加できる

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{

}

クラスを継承

  • クラス継承はCharacterAbility

    • 他のAbilityもこれがベースになっている

  • クラス名は自由に

    • CharacterDownThroughPlatform にしてみたけど、長ったらしいな

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{

    }
}

HandleInputを上書き

  • 各AbilityではHendleInputメソッドを上書きして入力を監視してる模様

  • この中に処理を書いていく

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		protected override void HandleInput()
		{

        }
    }
}

着地判定を追加する

  • 前提として地面に着地している状態で操作を受け付けることにする

  • _controllerで操作キャラクターを取得

    • 今回はプレイヤーのみを想定

  • Stateはキャラクターの状態、IsGroundedが着地しているかどうかの判定

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		protected override void HandleInput()
		{
			// 地面に着地している場合
			if (_controller.State.IsGrounded)
			{

            }
        }
    }
}

↓方向の入力をチェックする

  • ↓方向に閾値以上の入力がされているかを検知

    • ジョイスティックとかのアナログ入力を想定しているらしい

  • _verticalInputが縦方向の入力値、_inputManager.Threshold.yが縦方向に入力されたと判断する閾値

    • ↓方向の判定なので -1 * _inputManager.Threshold.yになっている

  • 着地判定と&&で繋げてもいいが、後でelseを入れるので別々にしておく

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		protected override void HandleInput()
		{
			// 地面に着地している場合
			if (_controller.State.IsGrounded)
			{
				// 下方向に入力している場合
				if (_verticalInput < -_inputManager.Threshold.y)
				{

                }
            }
        }
    }
}

立っているPlatformをチェック

  • キャラクターが立っているPlatformがOne-Wayかどうかを判定する

    • 判定方法はCharacterJumpからの引用

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		protected override void HandleInput()
		{
			// 地面に着地している場合
			if (_controller.State.IsGrounded)
			{
				// 下方向に入力している場合
				if (_verticalInput < -_inputManager.Threshold.y)
				{
					bool DownThrough = true;

					// プレイヤーが立っているPlatformをチェック
					foreach (GameObject obj in _controller.StandingOnArray)
					{
						if (obj == null)
						{
							continue;
						}
						// OneWayPlatformかStairsじゃない場合はすり抜け失敗
						if (!_controller.OneWayPlatformMask.MMContains(obj.layer) &&
							!_controller.MovingOneWayPlatformMask.MMContains(obj.layer) &&
							!_controller.StairsMask.MMContains(obj.layer))
						{
							DownThrough = false;
						}
					}

                }
            }
        }
    }
}

すり抜け処理を行う

  • One-Way Platformに乗ってるならすり抜け処理を行う

    • Platformの衝突判定を一瞬だけ無効にしているらしい

      • 今回はデフォルト値の0.3fを直接指定

      • 調整したい場合はpublic変数とか指定しておく

    • ここもCharacterJumpからの引用

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		protected override void HandleInput()
		{
			// 地面に着地している場合
			if (_controller.State.IsGrounded)
			{
				// 下方向に入力している場合
				if (_verticalInput < -_inputManager.Threshold.y)
				{
					bool DownThrough = true;

					// プレイヤーが立っているPlatformをチェック
					foreach (GameObject obj in _controller.StandingOnArray)
					{
						if (obj == null)
						{
							continue;
						}
						// OneWayPlatformかStairsじゃない場合はすり抜け失敗
						if (!_controller.OneWayPlatformMask.MMContains(obj.layer) &&
							!_controller.MovingOneWayPlatformMask.MMContains(obj.layer) &&
							!_controller.StairsMask.MMContains(obj.layer))
						{
							DownThrough = false;
						}
					}

					// すり抜け可能なら実行
					if (DownThrough)
					{
						// ジャンプ中扱いにする
						_movement.ChangeState(CharacterStates.MovementStates.Jumping);
						// 横方向の移動をリセットする
						_characterHorizontalMovement.ResetHorizontalSpeed();
						// OneWayPlatformの衝突判定を一瞬だけ解除 解除する時間を指定する
						StartCoroutine(_controller.DisableCollisionsWithOneWayPlatforms(0.3f));
						// MovingPlatformの慣性を解除
						_controller.DetachFromMovingPlatform();
					}

                }
            }
        }
    }
}

連続落下を無効にする

  • ここで完成でもいいが、これだと↓方向入力したままだと2段以降のPlatformを連続ですり抜けてしまう

    • 1段ずつ降りるようにしたい

  • すり抜けした直後のフラグを設定して監視する

    • private bool steppedDownThroughを設定

    • if(DownThrough){ } の中でtrueにする

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		private bool steppedDownThrough = false;

		protected override void HandleInput()
		{
			// 地面に着地している場合
			if (_controller.State.IsGrounded)
			{
				// 下方向に入力している場合
				if (_verticalInput < -_inputManager.Threshold.y)
				{
					bool DownThrough = true;

					// プレイヤーが立っているPlatformをチェック
					foreach (GameObject obj in _controller.StandingOnArray)
					{
						if (obj == null)
						{
							continue;
						}
						// OneWayPlatformかStairsじゃない場合はすり抜け失敗
						if (!_controller.OneWayPlatformMask.MMContains(obj.layer) &&
							!_controller.MovingOneWayPlatformMask.MMContains(obj.layer) &&
							!_controller.StairsMask.MMContains(obj.layer))
						{
							DownThrough = false;
						}
					}

					// すり抜け可能なら実行
					if (DownThrough)
					{
						// ジャンプ中扱いにする
						_movement.ChangeState(CharacterStates.MovementStates.Jumping);
						// 横方向の移動をリセットする
						_characterHorizontalMovement.ResetHorizontalSpeed();
						// OneWayPlatformの衝突判定を一瞬だけ解除 解除する時間を指定する
						StartCoroutine(_controller.DisableCollisionsWithOneWayPlatforms(0.3f));
						// MovingPlatformの慣性を解除
						_controller.DetachFromMovingPlatform();

						// すり抜け直後のフラグを立てる
						steppedDownThrough = true;
					}

                }
            }
        }
    }
}
  • すり抜け直後ならPlatformのチェックをせずにすり抜けを拒否

    • Platformのチェックをforeachでやってるから、素通りしたほうが処理が早いかも?

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		private bool steppedDownThrough = false;

		protected override void HandleInput()
		{
			// 地面に着地している場合
			if (_controller.State.IsGrounded)
			{
				// 下方向に入力している場合
				if (_verticalInput < -_inputManager.Threshold.y)
				{
					bool DownThrough = true;

					// すり抜け直後なら拒否する
					if (steppedDownThrough)
					{
						DownThrough = false;
					}
					else
					{
						// プレイヤーが立っているPlatformをチェック
						foreach (GameObject obj in _controller.StandingOnArray)
						{
							if (obj == null)
							{
								continue;
							}
							// OneWayPlatformかStairsじゃない場合はすり抜け失敗
							if (!_controller.OneWayPlatformMask.MMContains(obj.layer) &&
								!_controller.MovingOneWayPlatformMask.MMContains(obj.layer) &&
								!_controller.StairsMask.MMContains(obj.layer))
							{
								DownThrough = false;
							}
						}
					}

					// すり抜け可能なら実行
					if (DownThrough)
					{
						// ジャンプ中扱いにする
						_movement.ChangeState(CharacterStates.MovementStates.Jumping);
						// 横方向の移動をリセットする
						_characterHorizontalMovement.ResetHorizontalSpeed();
						// OneWayPlatformの衝突判定を一瞬だけ解除 解除する時間を指定する
						StartCoroutine(_controller.DisableCollisionsWithOneWayPlatforms(0.3f));
						// MovingPlatformの慣性を解除
						_controller.DetachFromMovingPlatform();

						// すり抜け直後のフラグを立てる
						steppedDownThrough = true;
					}

                }
            }
        }
    }
}
  • 着地後に↓方向の入力がなければフラグをリセット

using UnityEngine;
using MoreMountains.Tools;

namespace MoreMountains.CorgiEngine.zephilie
{
    public class CharacterDownThroughPlatform : CharacterAbility
	{
		private bool steppedDownThrough = false;

		protected override void HandleInput()
		{
			// 地面に着地している場合
			if (_controller.State.IsGrounded)
			{
				// 下方向に入力している場合
				if (_verticalInput < -_inputManager.Threshold.y)
				{
					bool DownThrough = true;
					// すり抜け直後なら拒否する
					if (steppedDownThrough)
					{
						DownThrough = false;
					}
					else
					{
						// プレイヤーが立っているPlatformをチェック
						foreach (GameObject obj in _controller.StandingOnArray)
						{
							if (obj == null)
							{
								continue;
							}
							// OneWayPlatformかStairsじゃない場合はすり抜け失敗
							if (!_controller.OneWayPlatformMask.MMContains(obj.layer) &&
								!_controller.MovingOneWayPlatformMask.MMContains(obj.layer) &&
								!_controller.StairsMask.MMContains(obj.layer))
							{
								DownThrough = false;
							}
						}
					}

					// すり抜け可能なら実行
					if (DownThrough)
					{
						// ジャンプ中扱いにする
						_movement.ChangeState(CharacterStates.MovementStates.Jumping);
						// 横方向の移動をリセットする
						_characterHorizontalMovement.ResetHorizontalSpeed();
						// OneWayPlatformの衝突判定を一瞬だけ解除 解除する時間を指定する
						StartCoroutine(_controller.DisableCollisionsWithOneWayPlatforms(0.3f));
						// MovingPlatformの慣性を解除
						_controller.DetachFromMovingPlatform();
						// すり抜け直後のフラグを立てる
						steppedDownThrough = true;
					}
				}
				// 下方向への入力してない場合
				else
				{
					// すり抜け直後のフラグをリセット
					steppedDownThrough = false;
				}
			}

		}

	}

}
しゃがみ動作なしで降りられる
  • とりあえずこれで動く

    • もっとスマートなやり方があるかもしれんが妥協する


この記事が気に入ったらサポートをしてみませんか?