Unityで角度制限付きの回転を行う方法

どうも、久しぶりの更新になってしまいました。
今日は備忘録を兼ねたUnityの使い方です。

Unityを使ってゲーム作りをしていると、回転が難しいという話があると思います。
実際、スクリプトでの回転操作はなかなか難しいですし、感覚がうまくつかめないところがあると思います。
特に、角度に制限を付けて回転をさせるのはネットでもなかなか見つからず、実装に苦戦している方も少なくないのではないでしょうか。

そこで、当方の実装方法を(備忘録を兼ねて)公開しようと思います。
あまり良い方法ではないかもしれませんが、もし参考になれば幸いです。

【方法とプログラム】
では、さっそくソースからどうぞ。
なお、ここでは前提として上下左右(XとY軸)の方向のみの回転

//現在の角度
Vector2 rotateAngle;
//制限する角度量
Vector2 rotateLimit;

void Update()
{
//対応するキー(デフォルトではa,s,w,dキー)を押すと、このスクリプトを付けた自身が回転
rotateProcess(new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")), 10f); //2番目の引数は、好きな値で
}

void rotateProcess(Vector2 delta, float speed)
{
//回転する方向と速度を決定
Vector2 rotVector = delta.normalized * speed * Time.deltaTime;

float rotH = getRotateAngle(rotVector.x, ref rotateAngle.x, rotateLimit.x / 2);
float rotV = getRotateAngle(-rotVector.y, ref rotateAngle.y, rotateLimit.y / 2);

//砲塔を回転
transform.rotation = Quaternion.AngleAxis(rotateAngle.x, transform.up) * Quaternion.AngleAxis(rotateAngle.y, transform.right);
//transform.Rotate(rotV, rotH, 0); //こちらは失敗
}

float getRotateAngle(float rotDelta, ref float angle, float rotMax = 90)
{
float result = rotDelta;

//予定の回転角度
float nextRot = angle + rotDelta;
//回転できる最大角度を超えたら
if (nextRot > rotMax)
{
result = rotMax - angle;
}
//回転できる最低角度を超えたら
else if (nextRot < -rotMax)
{
result = -rotMax - angle;
}

//回転後の角度も渡しておく
angle += result;
return result;
}


主な手順は以下の二つです。
1. 今の回転角度を求める
2. 1. で求めた角度をもとに、Quaternion.AngleAxitメソッドで回転させる

まず、1. は自作メソッドのgetRotateAngleから求めています。
引数は、左から (回転させたい角度量)、(回転前の角度)、(最大/最小角の絶対値) となっています。
ここでは、2番目の回転前の角度に、1番目の角度量を足して回転後の角度を求め、それが角度の制限値を超えていたら制限に収まるように回転量を調整しています。

戻り値は回転の角度量ですが、2番目の引数が参照(ref)となっているため、回転後の角度値も同時に求められます(実は、こちらの回転後の角度値を2.で使います)。

続いて2.の処理(自作のrotateProcessメソッド)ですが、回転量をQuaternionでもとめて、transform.rotationに入れています。
Quaternionは苦手な方もいらっしゃるかもしれませんが、Unity(に限らないかもしれませんが)で少し複雑な回転処理をさせようとすると必要になってきます。

とはいえ、今回使うのはQuaternion.AngleAxisメソッドのみです。
このメソッドは、引数に (回転させたい角度値)、(回転軸) を指定します。回転軸はVector3で指定するので、軸の伸びている方向と考えるとわかりやすいかもしれません。
オブジェクトに突き刺す軸を決めて、その軸を基に何度回転させるかといったイメージです。

今回のスクリプトは、上下と左右それぞれの回転をQuaternion.AngleAxisで求め、それをオブジェクトのrotationに代入して回転させます。AngleAxisメソッドで求められる回転は、上下、あるいは左右のみのものですが、実はQuaternion同士を掛け合わせると、二つの回転を反映した回転(Quaternion)が求められます。

そのため、以下の式で回転を求められるのです。
(オブジェクトのrotation) = (上下方向のQuaternion) * (左右方向のQuaternion)

なので、計算した角度とAngleAxisで求めたQuaternion同士を掛け合わせると角度制限を設けた回転が求められます。
今回は0°を中心に左右対称で角度の制限値を与えていますが、getRotateAngleの処理を少し変えれば非対称に角度の制限を設けることも可能です。

続きを読む

テーマ : ゲーム開発
ジャンル : コンピュータ

01/20のツイートまとめ

Revetronique

昨日、お昼に何を食べるか迷って、秋葉原でローストビーフ丼を食べました。相方よ、すまぬ。 https://t.co/EV3MfjRyTU
01-20 20:47

01/18のツイートまとめ

Revetronique

今更ですが、勤め先のイルミネーション https://t.co/qpo5EycuaA
01-18 01:00

01/13のツイートまとめ

Revetronique

TOKYO ART CITY BY NAKEDを見に渋谷ヒカリエへ。過去の六本木や東京駅でのマッピングがミニチュアで展示されていた。また本物の東京駅で見たいな。 https://t.co/krSF2ZAbJa
01-13 11:19

01/11のツイートまとめ

Revetronique

最終日のSweets by nakedに行ってみた!Parisのイメージかなぁ。壁面にプロジェクションはkinect2で降ってくる飴を人物の画像情報で跳ね返す仕組みかと。かなり前からプロジェクションをやりたかったから、今年は勉強す… https://t.co/rp4jdKthxP
01-11 18:25

プロフィール

Reveちゃん

Author:Reveちゃん
コンビでやってます。
夢担当と技術担当がいます。

大学院卒業 → ロボットベンチャー(漆黒)就職 → 1年で退職 → ベトナムで仕事中(今ここ) → メディアアーティスト(未来☆)

リンクフリーです。

最新記事
最新コメント
月別アーカイブ
カテゴリ
アクセス数
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR