モーション付きで実装するのが難しくて、うまく処理できない。
こんな感じで停滞している毎日なんですが、
少し、おや?って事があったので、調べる事にしました。
コースとしては、高台があって壁登りで上に上がります。
上に上がったら走り出すようにしたいので、
高台はFloorレイヤー(茶色)で作成して、
登り用のWallレイヤーの壁(黒色)を左側にくっ付けて、
登り切った所でFloorレイヤーを読み取って、走り出す設定にしました。
ところが、上に着地しても走りだしのモーションが呼び出されない!
なんで??となりました。
足元に張っているLinecastは、Floorレイヤーに反応するように設定しているのに…
と言う事で、モデルを作って検証してみる事に。
緑のブロックをプレイヤーとして、右方向に動かします。
床面はWallとFloorの二つのレイヤーで作って様子を見ます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LineCastTest : MonoBehaviour
{
private float rightOffset = 0.75f;
private float downOffse = 0.76f;
private RaycastHit2D hit;
public LayerMask floorLayer;
[SerializeField]
private float run;
private Rigidbody2D playerRB;
private Vector2 underStrat;
private Vector2 underEnd;
// Start is called before the first frame update
void Start()
{
playerRB = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
SetLineCast();
if (hit)
Debug.Log("接地してるよ");
}
void FixedUpdate()
{
playerRB.velocity = new Vector2(run, playerRB.velocity.y);
}
//Linecastの設定
private void SetLineCast()
{
underStrat = transform.position - (transform.right * rightOffset) - (transform.up * downOffse);
underEnd = transform.position + (transform.right * rightOffset) - (transform.up * downOffse);
hit = Physics2D.Linecast(underStrat, underEnd,floorLayer);
Debug.DrawLine(underStrat, underEnd, Color.red);
}
}
こんなスクリプトをプレイヤーにアタッチしてログを取ってみます。
Floorに乗ったらログが出力されるはずなんですが…
コンソールは無言です。(T-T) グスッ
なんで??
この原因は、大したことが無くて、
本体下の赤ラインがLinecastなんですが、
プレイヤーのColliderとかなり近い位置に設定していた為、
Floorレイヤーに刺さってなかった事が分かりました。
ColliderとColliderの接触面は、若干の開きがあるようなので、
ギリギリに設定すると上手く刺さらないようです。
これに気付いた時に、なんてマヌケなミスと恥ずかしくなったんですが、
丁度いい機会なんで、少しLinecastの掘り下げ勉強をしてみようかと思いました。
そもそもLinecastって、床や壁の判断に使うけど、他にどんな事ができるの?
そこで、折角モデルも作ったんで、
Linecastでどんな事ができるのか検証してみようと思います。
まず情報を探ってみます。Googleセンセ~ (T人T) オネガイ!
Linecastは、
・接触するCollider情報を取得できる
・特定レイヤーだけ反応させられる
・Colliderが複数接触してる時、始点に近いCollider情報を取得できる
・ビットを使えば、特定レイヤーを複数設定できる
情報は、こんな感じでした。
Colliderが複数接触してる~ が気になるので、
プレイヤーを中間に置いて様子を見てみます。
スクリプトを修正してテストしてみましょう!
// Update is called once per frame
void Update()
{
SetLineCast();
if (hit)
Debug.Log(hit.collider.gameObject.layer);
}
//Linecastの設定
private void SetLineCast()
{
underStrat = transform.position - (transform.right * rightOffset) - (transform.up * downOffse);
underEnd = transform.position + (transform.right * rightOffset) - (transform.up * downOffse);
hit = Physics2D.Linecast(underStrat, underEnd);
Debug.DrawLine(underStrat, underEnd, Color.red);
}
説明すると、
接触するCollider情報からオブジェクトの情報を取得する場合は、
RaycastHit2D変数.collider.gameObjectで取り出す事が出来ます。
今回は、オブジェクトの中のレイヤー情報なので、
デバッグの中の hit.collider.gameObject.layer これでレイヤーナンバーを取得できます。
Linecastのレイヤー指定を無くす事で接触する全てのColliderを取得する事ができます。
これでPLAYするとコンソールに7の数字が…
レイヤーナンバーなんで、どのレイヤーか分かりにくい(T-T) グスッ
って事でレイヤー名を取得します。
// Update is called once per frame
void Update()
{
SetLineCast();
if (hit)
Debug.Log(LayerMask.LayerToName(hit.collider.gameObject.layer));
}
取得したレイヤーナンバーからレイヤー名を取得するのが、
LayerMask.LayerToNameです。
引数にレイヤーナンバーを入力すると設定したレイヤー名が表示されます。
実際にPLAYすと、こんな感じになります。
無事に表示されていますが、Wallですね~
これは、Linecastの設定が
こんな感じで引いてるので、始点寄りのCollider情報を拾ってるからなんです。
と言う事は、始点を右側に変えるとどうなるかと言うと
当然の結果でっす。
これは理解しておく必要がありますね。
二つのレイヤーの間に止まった時、どちらに居るかを調べたいってなったら、
始点の位置で取得するColliderが変わるって事になります。
基本的には、進行方向に合わせて、始点を決めるといいかと思います。
アンドロイド君は、右移動なので始点を右からに修正しないと(;^_^A
折角、覚えたんで少し遊んでみます。
色を変えた床を4つ程並べて、プレイヤーを移動させます。
各床の色を読み取って、床を通過する間、プレイヤーも同じ色にさせてみます。
collider.gameObjectは、ゲームオブジェクトとして読み込むものなので、
当然、GetComponentが使えます。
単純に色を読み取ればできるはずなんですが…
再生できない場合、ダウンロードは🎥こちら
上手く読み取らせる事ができました。ヽ(´▽`)/~♪
プレイヤーの色が変わる時、あれ?って思われたかもしれませんが、
SpriteMaskを使ってます。
最後の遊びはオマケなんで、実際に使いどころはないでしょうが、
Linecastの参考になれば幸いです。
さて、止まっているアクションの処理の続きを作りますかね~ (- .-)ヾ ポリポリ
何か作れたら記事にするので、それまでは
( ^ 0 ^ )/~~~~see you again
この記事へのコメント