Last Updated 2023.11.07
前回 通常投げを実装できたので、今回は相手の背後から投げが成立したら、モーションの内容が変化する仕組みを実装していきたいと思います。
背後からの投げモーションを用意する
通常投げと同様、Blenderのアペンド機能を使って作成しました。
仕組みを考える
最初は投げ判定コライダーの接触位置を [ Collider.ClosestPoint() ]で求めて──……みたいな方法をイメージしていたのですが、精密な位置を求めるには難がある(らしい)ので、投げ成立時にお互いの『向き』で判定する方法を考えてみました。
お互いの向きを判定するスクリプト
▼キャラクター(オブジェクト)の前方は下記で表すことができます
gameObject.transform.forward
▼お互いの向きを判定
float dir = Vector3.Dot(Player1.transform.forward.normalized, Player2.transform.forward.normalized);
Vector3.Dot を使って求めます。
今回の場合、お互いの前方で判定しているので、向かい合ってるなら『dir』の値は「-」、背後からなら「+」の値が返ってきます。
これを投げ成立時にif条件で判断し、0より小さい(負数)なら正面からなので通常投げ、大きい(正数)なら後ろからなので背面からの投げに分岐させればいいですね。
▼投げの成立から判定してAnimatorを遷移させる
IsThrow = true;
_2PAnimator.applyRootMotion = true;
Player2.transform.LookAt(Player1.transform.position);
if (dir < 0)//マイナスなら通常投げに移行
{
_1PAnimator.SetTrigger("Catch");
_2PAnimator.SetBool("Thrown", true);
return;
}
else//プラスなら背後からの投げ
{
_1PAnimator.SetTrigger("BackCatch");
_2PAnimator.SetBool("BackThrown", true);
return;
}
あとはダメージ処理やカメラワークの変更などをスクリプトに追記していきます。
動作確認
今回作ったものがこちらになります。
よくよく見ると掴まれた直後の投げられた側の向きが一瞬おかしいのに気付いたんですが、これはAnimatorの矢印内、TranstionDurationの値が初期設定(0.25)のままで、Idle状態とブレンドされているのが原因でした。
ここを必要最低限に抑えると修正できました。
この分岐条件を使えば、側面がとれたり、背面投げの範囲をシビアにしたり──みたいなことも出来そうですね。さすがにモーション作りが大変すぎるので、側面投げまでは実装しませんが……