Mathf(UnityのMathライブラリ)
| 対応: | C# 1.0(2002) |
|---|
Unity 専用の数学関数ライブラリ『Mathf』の使い方です。C# の『Math』クラスと似ていますが、Mathf は float 型に特化しており、ゲーム開発でよく使う補間・クランプ・三角関数などを提供します。
構文
using UnityEngine; // 絶対値を返します(float 特化版)。 float abs = Mathf.Abs(float f); // 値を min 以上 max 以下に制限します。 float clamped = Mathf.Clamp(float value, float min, float max); // a から b へ t(0〜1)の割合で線形補間します。 float interpolated = Mathf.Lerp(float a, float b, float t); // 三角関数(引数はラジアン)。 float sin = Mathf.Sin(float f); float cos = Mathf.Cos(float f); // 度数をラジアンに変換します。 float rad = degrees * Mathf.Deg2Rad; // ラジアンを度数に変換します。 float deg = radians * Mathf.Rad2Deg;
メソッド一覧
| メソッド / 定数 | 概要 |
|---|---|
| Mathf.Abs(f) | f の絶対値を返します。 |
| Mathf.Clamp(value, min, max) | value を min 以上 max 以下の範囲に収めて返します。 |
| Mathf.Clamp01(value) | value を 0 以上 1 以下に収めます。正規化された値のクランプに便利です。 |
| Mathf.Lerp(a, b, t) | a と b の間を t(0〜1)で線形補間します。t が 0 なら a、1 なら b を返します。 |
| Mathf.LerpUnclamped(a, b, t) | Lerp と同様ですが t を 0〜1 に制限しません。t < 0 や t > 1 も使えます。 |
| Mathf.Sin(f) / Mathf.Cos(f) | f(ラジアン)のサイン・コサインを返します。 |
| Mathf.Sqrt(f) | f の平方根を返します。 |
| Mathf.Pow(f, p) | f の p 乗を返します。 |
| Mathf.Floor(f) / Mathf.Ceil(f) | 切り捨て・切り上げた整数値を float で返します。 |
| Mathf.Round(f) | 最も近い整数に丸めます。 |
| Mathf.PI | 円周率 π(3.14159265...)の定数です。 |
| Mathf.Deg2Rad | 度数をラジアンに変換する係数(π / 180)です。 |
| Mathf.Rad2Deg | ラジアンを度数に変換する係数(180 / π)です。 |
| Mathf.Infinity | 正の無限大を表す定数です。 |
サンプルコード
Clamp・Lerp・三角関数を組み合わせた Unity MonoBehaviour サンプルです。
MathfSample.cs
using UnityEngine;
public class MathfSample : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
[SerializeField] private Transform target;
void Start()
{
// Mathf.Clamp() で体力を 0〜100 の範囲に制限します。
float hp = 120f;
hp = Mathf.Clamp(hp, 0f, 100f);
Debug.Log($"体力(制限後): {hp}"); // 100
// Mathf.Abs() で距離差の絶対値を取得します。
float diff = -3.5f;
Debug.Log($"絶対値: {Mathf.Abs(diff)}"); // 3.5
// 三角関数で Sin 波アニメーションを計算します。
float wave = Mathf.Sin(Time.time) * 2f;
Debug.Log($"Sin 値: {wave:F4}");
// 度数からラジアンへの変換です。
float degrees = 45f;
float radians = degrees * Mathf.Deg2Rad;
Debug.Log($"Sin(45°) = {Mathf.Sin(radians):F4}"); // 0.7071
}
void Update()
{
// Mathf.Lerp() でターゲットに向かって滑らかに移動します。
if (target != null)
{
float t = moveSpeed * Time.deltaTime;
transform.position = Vector3.Lerp(transform.position, target.position, t);
}
// Mathf.Clamp01() で入力を 0〜1 に正規化します。
float input = Input.GetAxis("Horizontal");
float normalized = Mathf.Clamp01(Mathf.Abs(input));
}
}
実践パターン: Sin 波を使ったアニメーション
Mathf.Sin を使ってオブジェクトを上下に揺らす、よくある「浮遊アニメーション」パターンです。
FloatingAnimation.cs
using UnityEngine;
public class FloatingAnimation : MonoBehaviour
{
[SerializeField] private float amplitude = 0.5f; // 振れ幅
[SerializeField] private float frequency = 1f; // 周波数
[SerializeField] private float rotateSpeed = 30f; // 回転速度
private Vector3 startPosition;
void Start()
{
startPosition = transform.position;
}
void Update()
{
// Sin 波で Y 軸方向に往復運動させます。
float yOffset = Mathf.Sin(Time.time * frequency) * amplitude;
transform.position = startPosition + new Vector3(0f, yOffset, 0f);
// Y 軸を中心に回転させます。
transform.Rotate(Vector3.up, rotateSpeed * Time.deltaTime);
// 高さに応じてスケールを変化させます(上にあるほど大きく)。
float scale = Mathf.Lerp(0.8f, 1.2f, (yOffset / amplitude + 1f) / 2f);
transform.localScale = Vector3.one * scale;
Debug.Log($"Y offset: {yOffset:F3}, Scale: {scale:F3}");
}
}
実践パターン: SmoothStep と MoveTowards
SmoothStep は Lerp より滑らかなイージングを、MoveTowards はオーバーシュートなしの一定速度移動を提供します。
SmoothMovement.cs
using UnityEngine;
public class SmoothMovement : MonoBehaviour
{
[SerializeField] private Transform destination;
[SerializeField] private float speed = 2f;
private float elapsedTime = 0f;
private Vector3 startPos;
void Start()
{
startPos = transform.position;
}
void Update()
{
if (destination == null) return;
elapsedTime += Time.deltaTime;
// SmoothStep: 始点・終点でゆっくり、中間で速い S カーブ補間
float t = Mathf.Clamp01(elapsedTime / 3f);
float smoothT = Mathf.SmoothStep(0f, 1f, t);
transform.position = Vector3.Lerp(startPos, destination.position, smoothT);
// MoveTowards: 最大移動量を指定して一定速度で移動
// transform.position = Vector3.MoveTowards(
// transform.position, destination.position, speed * Time.deltaTime);
// 現在の進行度を出力します。
float distance = Vector3.Distance(transform.position, destination.position);
Debug.Log($"残り距離: {distance:F2}m, 進行度: {t:P0}");
}
}
よくあるミス
よくあるミス1: 三角関数に度数をそのまま渡す
Mathf.Sin / Mathf.Cos はラジアンで指定します。度数をそのまま渡すと意図しない値になります。
using UnityEngine;
// NG: 90度のサインを求めたいが、90ラジアンが渡されます。
float wrongSin = Mathf.Sin(90f);
Debug.Log($"NG: {wrongSin:F4}"); // 0.8940(90°のSin(1.0)とは異なる)
// OK: Deg2Rad で変換してから渡します。
float correctSin = Mathf.Sin(90f * Mathf.Deg2Rad);
Debug.Log($"OK: {correctSin:F4}"); // 1.0000
よくあるミス2: Update() での毎フレーム magnitude 計算
magnitude は内部で Mathf.Sqrt(平方根計算)を行うため高コストです。距離の大小比較だけなら sqrMagnitude と二乗値の比較が高速です。
using UnityEngine;
public class MagnitudeNG : MonoBehaviour
{
[SerializeField] private Transform target;
private float attackRange = 5f;
void Update()
{
if (target == null) return;
// NG: magnitude は Sqrt を含むため毎フレーム呼ぶと負荷が高い
if ((target.position - transform.position).magnitude < attackRange)
Debug.Log("攻撃範囲内(低速)");
// OK: sqrMagnitude と二乗値で比較すると Sqrt を省略できます。
if ((target.position - transform.position).sqrMagnitude < attackRange * attackRange)
Debug.Log("攻撃範囲内(高速)");
}
}
概要
『Mathf』の関数はすべて float 型を扱います。C# の Math クラスは double 型なので、Unity では基本的に Mathf を使います。三角関数の引数は度数(degree)ではなくラジアン(radian)です。度数で指定したい場合は Mathf.Deg2Rad を掛けてから渡してください。
Lerp() を Update() 内で使う場合、t に Time.deltaTime を掛けることでフレームレートに依存しないスムーズな補間が実現できます。ベクトル演算についてはVector2 / Vector3を、コルーチンを使った時間制御についてはCoroutine / IEnumeratorをご確認ください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。