回転方向が右向きか左向きか判別する処理

  • 5
    Like
  • 0
    Comment
More than 1 year has passed since last update.

自分用覚書
Unity以外でも使える
というかUnityならAnimatorとか使えば、特に考える必要なし? ワカンネ

例えばキャラクターが30度の方向を向いていて
300度の位置にゆっくり振り向かせたいとする

Main.cs
private Vector3 _next;

void Start()
{
    // キャラクターY軸 30度
    // キャラクターにゆっくり向いてほしい角度 300度
    character.rotation = Quaternion.Euler(new Vector3(0f, 30f, 0f));
    _next              = new Vetor3(0f, 300f, 0f);
}

private void _update()
{
    // 差分角度   = 現在の角度 - 振り向かせたい角度;
    // 現在の角度 = 現在の角度 - (差分角度 * イージング調整);
    Vector3 diff       = character.rotation.eulerAngles - _next;
    character.rotation = Quaternion.Euler(
        character.rotation.eulerAngles - diff*0.9f
    );
}

これだとぐるっと遠回りな回転をしてしまう
明らかに違和感がある
こういう時は左回転させたい 反時計回りに60度回転してほしい
でもよくワカンネ
どうしよう?

コード

とりあえずキャラクターをどっちに回転させるか判別するところから始める

Util.cs
/// <summary>
/// 回転方向左右判別
/// </summary>
/// <param name="current">現時点での角度</param>
/// <param name="target">最終的な角度</param>
/// <returns>true:時計回り false:反時計周り</returns>
private bool _checkClockwise(float current, float target)
{
    return target>current ? !( target  - current > 180f)
                          :    current - target  > 180f;
}

なんかこれで右回転のほうが目的の角度に近いかどうかがわかる
頭痛いんでもう考えたくない
引数はUnityなら
_checkClockwise(character.rotation.eulerAngles.y, _next.y)
になる
UnityはrotationにQuaternionの値が入ってる
Quaternionの取り扱いとかシラネ eulerつかえ euler
あとはこの判別した値を元に、更新するときに値をちょい直す

Main.cs
private bool _isClockwize; // _checkClockwise の結果を保存しておく

private void _update()
{
    // 差分角度 = 現在の角度 - 振り向かせたい角度;
    Vector3 diff = character.rotation.eulerAngles - _next;

    // 正規化(今回はY軸のみでいい)
    // 例で挙げた値を当てはめると、 diff.y は -300 になる
    // その時は360度足すと、60度になり、反時計周り60度になる
    // %360 は、例えば480度とかの値を120度に直すための処理
    diff.y = (diff.y+(_isClockwise?-360f:360f))%360f;

    // 現在の角度 = 現在の角度 - (差分角度 * イージング調整);
    character.rotation = Quaternion.Euler(
        character.rotation.eulerAngles - diff*0.9f
    );
}

あとはアナログスティック動かした時とかに当てはめてればいいんでないかと思う