Corgi Engine覚書(1)〜ワンボタンですり抜け床を降りる〜
Corgi Engineってなに?
アクションゲーム制作特化のUnity Assets
2Dと2.5Dに対応
横スクかトップダウンで色々作れる
”完璧な2Dアクションゲームアセット”と言われるだけあって便利
有名どころなので日本語での紹介記事、解説記事も多くて助かる
One-Way Platformの扱い
いわゆるすり抜け床のこと
下からジャンプですり抜けて登ることができる足場
上に乗って↓方向に入力すると降りることもできる
One-Way Platformを降りるには
Corgi EngineのOne-Way Platformは降りることができない?
↓方向に入力しても反応なし
登るしかできないのか…ちょっと移動性が落ちるな…
できるじゃねえかよ
↓方向の入力とともにジャンプボタンも必要だった
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;
}
}
}
}
}
とりあえずこれで動く
もっとスマートなやり方があるかもしれんが妥協する
この記事が気に入ったらサポートをしてみませんか?