以下の内容はhttps://www.karvan1230.com/entry/2026/03/03/215057より取得しました。


【Unity】LitMotionを使って好きな方向に回転させる

展示会

出展を狙っていた展示会がスポンサーという名目の高額な出展料でしか出展できないことを知ってガッカリしている清貧な皆さんこんにちは。3日間のBitSummitでさえエントリー料を加えても4万円いかないのに1日1ブースの金額がそれ以上とか流石に手が出せないです。いや、多少無理をすればお金は出せますが、そもそもこういった出展条件になっているいう事は主催側がインディゲームの展示会とは銘打ってはいるものの、個人や少人数サークルが製作する有象無象の作品は排してTGSみたいな企業体が主体の展示会を開催したいように感じられ、わざわざ無理して出展する気になれません。これならBitSummitにエントリーしとけば良かった。

 

濃さが増したゲーム

以前から発売を待ち望んでいたソウルライクの代表的タイトルの最新作を購入しました。

Team NINJAらしいスタイリッシュアクションとソウルライクにハスクラの要素を加えた仕様が特徴なこのシリーズ。ステージ制だった前作から今作は複数マップを行き交うオープンフィールド制に変わり作品全体のボリュームが増しています。
操作キャラが武者スタイル・忍者スタイルといった2パターンの戦闘スタイルを持ち、それぞれで上中下段の構えや忍術を切替えたり、陰陽符と呼ぶ魔法系の攻撃や使役符と呼ぶ召喚魔法、果ては助人といったNPCを使って強敵を倒し、よりレアで強力な装備品を手に入れて高難易度のミッションに挑んでいく、というゲーム仕様。
前作以上にプレイヤーの操作する要素が多いので元々高かった敷居が更に高くなった感がありますが、その敷居を超えると爽快感のあるスタイリッシュアクションを存分に楽しめるようになっていて、アクション面では「文句なしに過去最高の出来!」と評する方が多いのも納得するクオリティです。

ただ、戦国ダークファンタジーという世界観を意識してか複数あるマップのどの場所に行っても鬱蒼として荒廃した風景ばかりであまりメリハリが感じられません。
また、オープンフィールドとは行っても仁王2のマップがシームレスに繋がっているような構成なので、ひたすら広く長く続いているステージの中で延々と戦闘と探索を繰り返しているように感じられ、その分ゲーム体験としては非常に濃いものとなりますが、濃い目の中華料理をずっと食べ続けるのと同じで、人によってクリア前に飽きてしまうかもしれません。
あと個人的には戦闘時のカメラの挙動がRise of Roninを継承していなかった事が非常に残念。

とは言え、オープンフィールド化したことで探索の面白さは前作より増していますし、戦闘の歯ごたえは相変わらずで強敵を倒した時の達成感は高く、何より戦闘を含むアクション面には全く不満はないので攻略の楽しさは値段に見合うものだと思います。

 

LitMotionによる回転

LitMotionはUnity向けに公開されているTween系のアセットでDOTweenやLeanTweenと比べてハイパフォーマンスである事が特徴のアセットです。

github.com

LitMotion は基本的にメソッドチェーンという記法で記述しますがDOTweenとは異なり移動用の関数(DOMove)や回転用の関数(DORotate)などは用意されておらず、基本的に特定の値に変化させるTweenを作ってそれをGameObjectのtransform.positionやtransform.rotationに紐づける(Bindする)ことでGameObjectを動作させます。

LMotion.Create(Vector3.zero, new Vector3(0,5,0), 1f) // (0,0,0)から(0,5,0)まで1f(秒)かけて移動するTweenを作る
    .WithEase(Ease.Line)                             // イージングの指定
    .BindToPosition(this.transform);                 // それをtransform.positioに紐づけ

 

オブジェクトを回転させる場合も同様ですが、Vector3を扱う場合だとEulerAngleに紐づけることになります。

Vector3 StartAngle = new Vector3(0f,0f,0f);
Vector3 EndAngle = new Vector3(0f,0f,90f);

LMotion.Create(StartAngle, EndAngle, 1f)
    .WithEase(Ease.Linear)
    .BindToEulerAngles(this.transform);

transform.rotationに紐づけたい場合はQuaternionを使います。ただQuaternionに直接角度の値を設定するのは難しいので事前にVector3(=オイラー角)からQuaternionに変換する必要があります。

Quaternion StartRot = Quaternion.Euler(StartAngle);
Quaternion EndRot = Quaternion.Euler(EndAngle);

LMotion.Create(StartRot, EndRot, 1f)
            .WithEase(Ease.Linear)
            .BindToRotation(this.transform);

 

半回転以上できない

一見すると何も問題ないように見えますが実は上記の方法では180度以上の回転はできません
何故なら開始角度を0度、終了角度を270度とすると0→90→180→270度の回転より、0→270(=-90)度の回転の方が内積が小さくなるため、そちらの回転方向に補間されて動作するからです。

開始角度0度~終了角度180度を指定した回転

 

開始角度0度~終了角度270度を指定した回転

これを回避する為にVector3.Slerp使って0~270度までの補間値を計算して、その値をthis.transform.eulerAnglesに代入する方法がありますが

LMotion.Create(0f, 1f, 1f)
    .WithEase(Ease.Linear)
    .Bind(value =>
    {
        // Vector3.Slerpを使って開始角度から終了角度まで変化させる
        this.transform.eulerAngles = Vector3.Slerp(StartAngle, EndAngle, value);
    });

この手法を使うと開始角度:-45度~終了角度:45度などの指定パターンでは意図しない動きになります。

あらぬ方向軸の回転が発生する

 

これはTween中にVector3(=オイラー角).Slerpで強引に補間した値をQuaternionに変換する為の不具合でありQuaternion.Slerpを使えば正しい動作を得られますが、そうすると前述のように半回転以上の回転を行うことが出来ません。

本来の正しい動作

 

Quaternionを使い半回転以上したい

問題はQuaternion.Slerpだと必ず内積が小さい方向の回転になるという事で、逆に内積が大きい方向の補間ができれば解決することが出来ます。
幸いに、こじゃら氏のブログ ねこじゃらシティにて遠回り経路の補間処理(LongSlerp)が紹介されているので、こちらが利用できそうです。

nekojara.city

上記の記事内のMathUtil_QuaternionLongSlerp.csを流用してBind内で補間値を求めてtransform.rotationに設定します。

StartRot = Quaternion.Euler(StartAngle);
EndRot = Quaternion.Euler(EndAngle);

LMotion.Create(0f, 1f, 1f)
    .WithEase(Ease.Linear)
    .Bind(value =>
    {
        // LongSlerpを使ってQuaternionを開始角度から終了角度まで変化させる
        this.transform.rotation = MathUtil.LongSlerp(StartRot, EndRot, value);
    });

実際の動作を確認すると270度の回転が出来る事が確認できます。

 

最後に

LitMotionで回転を行う場合は少し面倒かもしれませんが、180度以内の回転なら従来通りの手法、それ以上なら前述のLongSlerpを使うといった感じで実装する事になりそうです。
ただしこれらの手法でもQuaternionの制約により360度以上の回転は出来ないので一つのTweenは0~360度内(実際は359.9度ぐらい)の回転に制限されます。
1回転以上の回転が必要な場合は、一つのTweenが0~360度内に収まるようにSequenceを使って実装する必要があります。

 




以上の内容はhttps://www.karvan1230.com/entry/2026/03/03/215057より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14