【Unity】知って得するMathfクラス
こんにちは(ؓؒؒؑؑؖؔؓؒؐؐ⁼̴̀ωؘؙؖؕؔؓؒؑؐؕ⁼̴̀ )
今回はUnityのMathfクラスの紹介をしていきたいと思います。
といっても全部は大変なので、よく使うっぽいやつ&イメージしやすいやつだけ。(アバウト過ぎる…)
具体例はUnityのスクリプトリファレンスからパクってきました!イガ栗⊂( ・∀・) 彡 =͟͟͞͞(✹)`Д´)
・Infinity - 無限大を表す
これはRayがわかりやすいと思います。こんなん。
if(Physics.Raycasat(ray, out hit, Mathf.Infinity) {}
無限大を取得できるので、この場合だとRayの長さが無限になります。
実際に使うときは長さを指定することが多いので、正直自分はあんま使わない変数だったり_(┐「ε:)_ズコー
・NegativeInfinity - 負の無限大を表す
これは、Infinityの負のver.なんですが、なんかイメージしにくい。デバッグで見ると、コンソールには「-Infinity」と出ます。
まあ、正直使わんでしょ!(オイ
・PI - 円周率( 3.14159265358979... )
こっちはもっと使わない!円周率???なにそれ食えんの!?!?!?
float perimeter = 2 * Mathf.PI * radius;
円周の長さは、半径×2×πで求められる例。使わん!
・Abs(a) - 絶対値を返す
これは少し便利。マイナスの符号を取って、正の値を返してくれます。
Debug.Log(Mathf.Abs(-10.5); // 結果 10.5
・Approximately(float a, float b) - 2 つの Float 型の値を比較
使ったことないけど、便利そう。float型でしか使えないので注意。
if (Mathf.Approximately(a, b)) { Debug.Log("aとbは同じよーん"); }
・Clamp(value, min, max) - 最大値と最小値の間で収める
これは便利!値を指定範囲で収めてくれます。int型でも使えます。
transform.position = new Vector3(Mathf.Clamp(Time.time, 1.0F, 3.0F), 0, 0);
この例だと、コードが読み込まれてから1秒未満なら1、1〜3秒の間は1〜3の値、3秒以上経ったら3の値が返ってきます。
できるやつ(⌯꒪͒ ૢ∀ ૢ꒪͒)
・Clamp01(float value) - 0 と 1 の間で収める
Clampの最小値と最大値がそれぞれ0と1に最初から指定されているver.です。もちflaot型オンリー。こいつも便利。
・Ceil(float f) - 小数点以下を切り上げ
小数点以下を切り上げてくれます。(☝ ՞ਊ ՞)☝アゲアゲ
Debug.Log(Mathf.Ceil(10.0F)); // 結果 10 Debug.Log(Mathf.Ceil(10.2F)); // 結果 11 Debug.Log(Mathf.Ceil(10.7F)); // 結果 11 Debug.Log(Mathf.Ceil(-10.0F)); // 結果 -10 Debug.Log(Mathf.Ceil(-10.2F)); // 結果 -10 Debug.Log(Mathf.Ceil(-10.7F)); // 結果 -10
*Ceil関数はたとえ 10.0f でもfloat型のまま10を返しますが、CeilToInt関数を使うと 10.0f はint型の10を返します。つまりCeilToInt関数の場合、計算結果の値はint型に変換されます。
・Floor(float f) - 小数点以下を切捨て
Ceilの逆バージョン。10.2なら10が、-10.2なら-11が返ってきます。これも返された値をint型に変換する、FloorToInt関数があります。
・Lerp(float from, float to, float t) - tの値によってfromからtoまでの中間値を取得
第三引数 t の値が0のとき from の値が、1のとき to の値が得られます。なので、t が0.5のときは from と to の丁度中間の値が得られます。
float min = 10.0F; float max = 20.0F; void Update() { transform.position = new Vector3(Mathf.Lerp(min, max, Time.time), 0, 0); }
値間の補正によく使います。滅茶苦茶できるやつ!多分使用頻度No.1!使い始めればきっと貴方もこの子無しには生きられない身体に・・・
・LerpAngle(float a, float b, float t) - 角度で使うLerp
角度を計算するときに使うならこっちのLerpAngleを使いましょう。
360度で一回転することを考えて良い感じに計算してくれます。
float minAngle = 0.0F; float maxAngle = 90.0F; void Update() { float angle = Mathf.LerpAngle(minAngle, maxAngle, Time.time); transform.eulerAngles = new Vector3(0, angle, 0); }
・MoveTowards(float current, float target, float maxDelta) - current 引数から target 引数まで、maxDelta 引数のスピードで移動
すごく便利そうだけど、調べるまで知らなかったので今まで使ったことのない子。優秀感が漂います・・・!
float currStrength; float maxStrength; float recoveryRate; void Update() { currStrength = Mathf.MoveTowards(currStrength, maxStrength, recoveryRate * Time.deltaTime); }
・MoveTowardsAngle(float current, float target, float maxDelta) - current 引数から target 引数まで、maxDelta 引数のスピードで移動
MoveTowards関数の角度計算向けver.です。
float target = 270.0F; float speed = 45.0F; void Update() { float angle = Mathf.MoveTowardsAngle(transform.eulerAngles.y, target, speed * Time.deltaTime); transform.eulerAngles = new Vector3(0, angle, 0); }
・PingPong(float t, float length) - 0とlengthの間の値を得る
この関数はその名前の通り、ピンポン球のように0と第二引数 length の値の間を、第一引数 t の値を参照して行ったり来たりします。
Debug.Log(Mathf.PingPong(0, 3); // 結果 0 Debug.Log(Mathf.PingPong(3, 3); // 結果 3 Debug.Log(Mathf.PingPong(4, 3); // 結果 2 Debug.Log(Mathf.PingPong(6, 3); // 結果 0
よく使うパターンが、Time.timeを第一引数に入れるやつです。
transform.position = new Vector3(Mathf.PingPong(Time.time, 10), 0, 0);
・Round(float f) - f の値に一番近いint型の値を得る
10.2なら10を、10.7なら11を返します。.5で終わる値の場合、偶数の方の整数を得ます。例えば10.5なら10、11.5なら12といった感じです。
最近これを使ってグリッドベースの移動を再現できました。ポケモンみたいな感じの移動。
これにもRoundToInt関数があります。
・SmoothDamp
(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime) - current から target まで、smoothTimeでスムージング
maxSpeedを指定しなければMath.Infinity、deltaTimeを指定しなければTime.deltaTimeが入ります。
ちょっとややこしいですが、すごく便利な関数です。めちゃくちゃ使います。
例えば、目的のオブジェクトを今の位置から、y 10の位置に1秒かけてスムーズに移動させたいときは、
float yVelocity = 0.0F; void Update() { float newPosition = Mathf.SmoothDamp(transform.position.y, 10, ref yVelocity, 1); transform.position = new Vector3(transform.position.x, newPosition, transform.position.z); }
てな感じです。第三引数の currentVelocity は適当に入れておけばオッケーです。
・SmoothDampAngle
(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime) - 角度ver.
角度計算のときにはこっちを使いましょう。
・Sin(float f) - サイン
・Cos(float f) - コサイン
・Tan(float f) - タンジェント
三角比でお馴染みの文系殺し三人衆です。自分もあまり使うことはないのですが、紹介しないで終わったら怒られそうなので・・・(誰にだ)
Tan関数にいたっては全く使ったことがないのですが、Sin、Cos関数は、カメラをプレイヤーの周りを回るようにしたかったときに使いました。
こんな感じ。
float rotateAngle = 0f; float radius = 5.0f; float height = 10.0f; void Upate() { cameraTransform.position = new Vector3( playerTf.position.x + Mathf.Sin(rotateAngle) * radius, height, playerTf.position.z + Mathf.Cos(rotateAngle) * radius); rotateAngle += .03f; }
解説は面倒くさいので紹介するだけにとどめます( ´ิ(ꈊ) ´ิ)ウェイ
少し長くなってお腹が減ったのでMathfクラスの紹介は以上にします'(<◉>◞౪◟<◉>)'
「へ〜こんなのあるんだー」といった感じで頭の片隅にでも入れていただければ、空腹に耐えてキーボードを叩いた甲斐があります(・:゚д゚:・)ハァハァ
意外と便利なMathfクラス、これで貴方もエリートプログラマー!?!?!?(エリートってなんだ)