【Unity】スライディングをさせてみる

アクション物を作ると言う事で、
いろいろと試行錯誤しているのですが、
通常アクションの、走る、ジャンプ、落下まで作る事ができました。

これで動きができたので、
いよいよ自分好みのアクションを作って行くことになるわけなんですが…


今作っているアクション物は、逃げる系を想定しています。
なので、壁や谷間を上手く越えて逃げ切るようなアクションにしたいなと。

ただ、飛んで越えるだけでは面白くないんで、
隙間なんかを、スライディングで抜けれるとバリエーションも増えるので、
処理を作ってみたいと思います。

まず、スライディングなんですが、
・寝かせるモーション
・床に接触している時だけできる
・モーションは、一定時間で走る動作にもどす

この辺りが課題になりそうです。

まず、寝かせるモーションが必要なので、アニメーションクリップを作成します。

走ってる最中に寝かせるので、少しアングルを作ります。
スライディング①.png
開始0秒

スライディング②.png
0.1秒後

スライディング③.jpg
0.2秒でスライディングの態勢になります。

スライディングの時間をどれくらいに設定するかで、
態勢を何秒キープさせておくかになるんですが、
スライディング④.jpg
長くとりたい処理ができると編集し直す必要がでてくるので、
とりあえず4秒間キープするように設定しました。

これでモーションが出来たので、スクリプトを考えていきます。

まずスライディングは、一定時間で走るモーションに戻す必要があるので、
Updateで監視する必要があります。
ActionTest

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ActionTest : MonoBehaviour
{
private float slidingProgress; //スライディング経過時間
private const float slidingTime = 1.0f; //スライディング時間

// Update is called once per frame
void Update()
{
SlidingAction();
}

//スライディングアクション
private void SlidingAction()
{
slidingProgress += Time.deltaTime;

if (slidingProgress < slidingTime)
AnimationChange(actionNum.sliding);

else
slidingProgress = 0f;
}

前回作った、ActionTestスクリプトに組み込んで行きます。
スライディング以外の処理については、前回記事を参照下さい。

スライディングの時間を1秒とした場合、
こんな処理で切り替えれそうです。

この処理を床に接触している間、キー入力があれば呼び出すように
修正していきます。
ActionTest

private bool sliding; //スライディングフラグ

// Update is called once per frame
void Update()
{
SetLinecast();

if (sliding)
{
SlidingAction();
return;
}


if (bodyUnder)
{
runSpeed = 10f;

if (Input.anyKeyDown)
KeySelect();

AnimationChange(actionNum.run);
}
}

//キー入力判定
private void KeySelect()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
jump = true;

if (Input.GetKeyDown(KeyCode.DownArrow))
sliding = true;
}

//スライディングアクション
private void SlidingAction()
{
slidingProgress += Time.deltaTime;

if (slidingProgress < slidingTime)
AnimationChange(actionNum.sliding);

else
{
sliding = false;
slidingProgress = 0f;
}

床に接触してる必要があるので、bodyUnder判定内でキー操作を確認します。

キー入力があればスライディング開始をさせるのですが、
bodyUnderの判定後にスライディングの処理を入れると、
再度、スライディングしたりスライディングの態勢のままジャンプできてしまうので、
bodyUnder判定の前に処理をします。

また、スライディング処理後にbodyUnder判定まで進むと
結局、キー入力ができてしまうので、returnでUpdateから出るようにしました。

後は、一秒後にスライディングのフラグをOFFにすれば、
bodyUnderの判定まで進むので、走るモーションに切り替わります。

これでスライディングができるようになったかテストしてみます。
スライディング⑤.jpg
キーを入力すると…
宙に浮いてます(;^_^A

これは足元のColliderのせいです。(..*) オハズカシイ・・
スライディング⑥.jpg
足元を安定させる為に入れてるColliderなんですが、
アニメーションを作る際に胴体を少し高い位置に設定したので、
ギャップができてしまいました。

通常ならこのギャップを無くせば問題なくスライディングさせる事ができます。

少し意図がありまして、ギャップを出しています。
この辺りは、上手く作れたら記事にしようと思っています。

このままでは、足元Colliderが邪魔なので、
スライディング中は消す事にします。
ActionTest

private BoxCollider2D playerUnderBC; //足元のBoxCollider取得

// Start is called before the first frame update
void Start()
{
playerUnderBC = GetComponent<BoxCollider2D>();
}

//キー入力判定
private void KeySelect()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
jump = true;

if (Input.GetKeyDown(KeyCode.DownArrow))
{
playerUnderBC.enabled = false;
sliding = true;
}
}

//スライディングアクション
private void SlidingAction()
{
slidingProgress += Time.deltaTime;

if (slidingProgress < slidingTime)
AnimationChange(actionNum.sliding);

else
{
sliding = false;
slidingProgress = 0f;
playerUnderBC.enabled = true;
}
}

キー入力と同時にColliderをOFFにして、
スライディング終了時にONにすれば元に戻ります。

これでスライディングが完成したのでテストPLAYしてみます。

無事にスライディングで隙間を抜ける事ができましたヽ(´▽`)/~♪

キー入力でスライディングさせているので、
時間で処理をつくりましたが、OnTriggerなんかでスライディングさせると
スライディングエリアを作っておけば長い間スライディングさせたりできそうです。

前回のActionTestスクリプトに組み込んだのですが、
落下やジャンプの部分を少しメソッド化したので、
修正部分も含めてスクリプトを書いておきます。
ActionTest

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ActionTest : MonoBehaviour
{
[Header("レイヤーマスク")]
public LayerMask floorLayer;

private Rigidbody2D playerRB; //Rigidbody取得
private BoxCollider2D playerUnderBC; //足元のBoxCollider取得
private Animator motion; //Animator取得

private float runSpeed = 0f; //走るスピード
private bool jump; //ジャンプフラグ
private const float jumpPow = 400f; //ジャンプ力

private bool sliding; //スライディングフラグ
private float slidingProgress; //スライディング経過時間
private const float slidingTime = 1.0f; //スライディング時間

private const string CLIP_KEY="Action"; //Animatorの変数名

//Ray用フラグ
private bool bodyUnder; //体下Ray

//アクションナンバーの設定
private enum actionNum
{
stop = 0,
run = 1,
jump = 2,
fall = 3,
sliding = 4,
wallAttach = 5,
wallJump = 6,
}

// Start is called before the first frame update
void Start()
{
playerRB = GetComponent<Rigidbody2D>();
playerUnderBC = GetComponent<BoxCollider2D>();
motion = GetComponent<Animator>();

}

// Update is called once per frame
void Update()
{
SetLinecast();

if (sliding)
{
SlidingAction();
return;
}


if (bodyUnder)
{
runSpeed = 10f;

if (Input.anyKeyDown)
KeySelect();

AnimationChange(actionNum.run);
}
else
AirMotion();
}

private void FixedUpdate()
{
playerRB.velocity = new Vector2(runSpeed, playerRB.velocity.y);

if (jump)
{
playerRB.AddForce(Vector2.up * jumpPow);
jump = false;
}
}

//キー入力判定
private void KeySelect()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
jump = true;

if (Input.GetKeyDown(KeyCode.DownArrow))
{
playerUnderBC.enabled = false;
sliding = true;
}
}

//アニメーション切り替え
private void AnimationChange(actionNum num)
{
motion.SetInteger(CLIP_KEY, (int)num);
}

//スライディングアクション
private void SlidingAction()
{
slidingProgress += Time.deltaTime;

if (slidingProgress < slidingTime)
AnimationChange(actionNum.sliding);

else
{
sliding = false;
slidingProgress = 0f;
playerUnderBC.enabled = true;
}
}


//落下・上昇チェック
private void AirMotion()
{
//落下中ならFallクリップ再生
if (playerRB.velocity.y < 0)
AnimationChange(actionNum.fall);
//ジャンプ中ならJumpクリップ再生
else if (playerRB.velocity.y > 0)
AnimationChange(actionNum.jump);
}


//Linecastの部分は省略します。
//床との接触はbodyUnderフラグに取得しています。
}

スライディングの処理は、どのタイミングで行うのがいいか
少し悩みましたが、上手く作れたかなと思っています。

操作系で処理するなら、秒数で管理するのが楽ですが、
オープニングなんかの演出にスライディングを入れたいなら、
OnTriggerのStayを使うといいかもしれません。

スライディング処理の参考になれば幸いでっす。(^ё^) ♪♪

もう少しモーションを追加する予定なので、
作れたら記事にしたいと思います。

それでは今回はこの辺で (o・・o)/~マタネェ


この記事へのコメント