オイラー角
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 42/71。
transform.eulerAnglesは、オブジェクトの回転をx、y、z軸まわりの度数で表した3つの角度です。Unityは回転をクォータニオン(次のレッスンで説明します)として保存し、角度を読み取るたびに3つの角度を計算し直します。その値は常に0から360までです。板をz軸まわりに-10度傾けて、値を読み取ってみましょう。
transform.rotation = Quaternion.Euler(0, 0, -10);
Debug.Log(transform.eulerAngles.z); // 350-10を設定したのに、コードが読み取る値は350なので、if (transform.eulerAngles.z < -5)が真になることはありません。読み取った値は3つすべて変わることがあります。(100, 0, 0)を設定すると、同じ向きを別の表し方にした(80, 180, 180)が読み取られます。Quaternion.Euler(x, y, z)は逆方向に働き、どんな角度でも受け取ります。-10、350、710は同じ回転を作ります。そのため、角度は自分で用意したfloatに保持し、そこで変更や制限を行ってから、その値を使って回転全体を設定しましょう。このシーソーは矢印キーで傾き、どちらの方向にも20度で止まります。
public float speed = 40f;
float tilt;
void Update()
{
tilt += Input.GetAxisRaw("Horizontal") * speed * Time.deltaTime;
tilt = Mathf.Clamp(tilt, -20f, 20f);
transform.rotation = Quaternion.Euler(0, 0, tilt);
}読み取った角度の一部だけを変更しないでください。transform.eulerAngles.x = 110;はコンパイルできません(position.xと同様にCS1612が発生します)。また、eulerAnglesをコピーしてxを変更し、そのコピーを代入し直すと、Unityが持つ角度の値をもとに処理が始まります。(100, 0, 0)を設定した後、そのコピーは(80, 180, 180)です。xに10を加えると(90, 180, 180)になり、オブジェクトは110度まで回転するのではなく、90度に戻ります。
チャレンジ
中級カメラの旋回を修正しましょう。45で折り返しますが、-45では折り返しません。これは、eulerAngles.y が-45を315として読み取るためです。
- フィールド
float angle;を追加し、Update()の最初の2行をangle += direction * speed * Time.deltaTime;に置き換えます。 - 2つの
if行はそのままにして、回転全体を次のように設定します。transform.rotation = Quaternion.Euler(tilt, angle, 0);
「プレイ」を押すと、カメラは下向きに傾きながら45から-45まで旋回し、戻ります。その後、「確認」を押します。
自分で試してみよう
using UnityEngine;
public class Sweep : MonoBehaviour
{
public float speed = 30f;
public float limit = 45f;
public float tilt = 20f; // x軸を中心に下向きに回転する角度(度)
float direction = 1f;
void Update()
{
transform.Rotate(0, direction * speed * Time.deltaTime, 0, Space.World);
float angle = transform.eulerAngles.y;
if (angle > limit) direction = -1f;
if (angle < -limit) direction = 1f;
}
}
物理演算とゲームプレイのすべてのレッスン
自分で練習してみよう: Unityプレイグラウンド