全Unity使いはMathfのリファレンスを読め

#本日のメニュー
こんにちは、避雷です。[UTVirtualのアドベントカレンダー](https://qiita.com/advent-calendar/2018/ut-virtual)に勇み足で挑んだ結果何も書く内容がないことに気づいて死体になりました。先週の記事はトバしすぎて気持ちの悪いオタクと化していたので今回は初心者向けの記事です（≒クソ記事）。ログインボーナス。
はい。今回のテーマはUnity.Mathfです。
https://docs.unity3d.com/ScriptReference/Mathf.html
単純に言えば数学関数の詰め合わせなんですけど、案外見落としがちで便利なものとかキモいものとかが多いのでここでサッとおさらいしてみましょう。
#Mathf紹介祭り
##定数編
これらは定数です。

|  定数名 |  説明  |
| ---- | ---- |
|  Deg2Rad  |  デグリーをラジアンに変換できます。便利。  |
|  Epsilon  |  微小量のfloatです。0ではない最も小さい数。それfloatなんですか？  |
|  Infinity  |  無限大を表すfloatです。アルゴリズム組む時には使えそう  |
|  NegativeInfinity  |  マイナス無限大を表すfloatです。最大値探索のアルゴリズムとかには使えそう(まぁそういう組み込み関数があるので実は不要だけど)  |
|  PI  |  円周率です。floatだと7桁までは正確らしい  |
|  Rad2Deg  |  ラジアンをデグリーに変換します。便利。  |
特に使うのはPI,Deg2Rad,Rad2Degあたりだと思う。

##関数編
便利な関数がたくさんあります。うまく使えば簡単なif文を省略できるので見てみましょう。

|  関数名  |  引数  |  説明  |
|  ----  |  ----  |  ----  |
|  Abs  |  float f  |  絶対値を返します  |
|  Acos  |  float f  |  Arccos(f)を返します  |
|  Approximately   |  float a, float b  |  2つのfloatが「だいたい等しいか」をbool値で返します  |
|  Asin  |  float f  |  Arcsin(f)を返します  |
|  Atan  |  float f  |  Arctan(f)を返します  |
|  Atan2  |  float y,float x  |  Atan(y/x)を返します。仰角を求めるのとかに使える。引数の順序に注意  |
|  Ceil/CeilToInt  |  float f  |  fの端数を切り上げた整数をfloat/intで返します  |
|  Floor/FloorToInt  |  float f  |  fの端数を切り捨てた整数をfloat/intで返します  |
|  Clamp  |  float val,float min, float max  |  valを[min,max]の値に押し込めます。詳細は後述。  |
|  Clamp01  |  float f  |  valを[0,1]の値に押し込めます。詳細は後述。  |
|  ClosestPowerOfTwo  |  float f  |  fに最も近い2^nの値を返します  |
|  CorrelatedColorTemperatureToRGB  |  float kelvin  |  ケルビン（温度）に対応した色を返します  |
|  Cos  |  float f  |  cos(f)の値を返します  |
|  DeltaAngle  |  float current, float target  |  引数の二つの角度の差のうち小さい方を返す  |
|  Exp  |  float pow  |  ネイピア数eのpow乗を返します  |
|  GammaToLinearSpace  |  float val  |  引数をガンマからリニアの色空間に変換した値を返します  |
|  InverseLerp  |  float a,float b,float val  |  Lerpの逆です（対応する線形補完用パラメタtを返す）  |
|  IsPowerOfTwo  |  float f  |  fが2のn乗であるときtrueを返します  |
|  Lerp  |  float a,float b,float t  |  区間[a,b]をパラメタtで線形補完した値を返します  |
|  LerpAngle  |  float a,float b,float t  |  Lerpの角度版。360度のギャップをうまいこと補完してくれるらしい  |
|  LerpUnClamped  |  float a,float b,float t  |  基本Lerpと同じだがtの値に制限がない（内分だけじゃなく外分的なこともできる）  |
|  LinearToGammaSpace  |  float val  |  引数をリニアからガンマの色空間へ変換した値を返します  |
|  Log  |  float f,float p  |  logp(f)の値を返します  |
|  Log10  |  float f  |  log10(f)の値を返します  |
|  Max  |  float A1,float A2,...,float An  |  2個以上の引数のうち最大値を算出する  |
|  Min  |  float A1,float A2,...,float An  |  2個以上の引数のうち最小値を算出する  |
|  MoveTowards  |  float current,float max,float maxDelta  |  currentからmaxまでmaxDeltaの値で向かう（max超過分は切り捨てられる）  |
|  MoveTowardsAngle  |  float current,float max, float maxDelta  |  MoveTowardsの角度版です。360度周りのゴタゴタを処理してくれるらしい  |
|  NextPowerOfTwo  |  float f  |  f以上で最も小さい2^nの値を返します  |
|  PerlinNoise  |   float x,float y |  パーリンノイズを生成して、(x,y)における値[0,1]を返します  |
|  PingPong  |  float t,float length  |  tをlengthの値でピンポンのように折りたたんで返します  |
|  Pow  |  float f,float p  |  f^pを返します  |
|  Repeat  |  float t, float length  |  tをlengthの値でループさせて折りたたんで返します  |
|  Round/RoundToInt  |  float f  |  fに最も近い整数をfloat/intで返します  |
|  Sign  |  float f  |  fの符号を返します。 f>= 0で1、f < 0で-1を返します  |
|  Sin  |  float f  |  sin(f)の値を返します  |
|  SmoothDamp  |  float current,float target,ref float currentVelocity,float smoothTime,float maxSpeed,float deltaTime  |  徐々に対象に向かって進みます  |
|  SmoothDampAngle  |  float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed= Mathf.Infinity, float deltaTime= Time.deltaTime  |  SmoothDampの角度版です  |
|  SmoothStep  |  float from,float to,float t  |  Lerpのスムージングがかかったバージョンです  |
|  Sqrt  |  float f  |  f^2を返します  |
|  tan  |  float f  |  tan(f)を返します  |

#解説！
##Approximately
float特有の丸め誤差を補正する機能付きの==関数。
##Clamp
数値を一定の区間に押し込めることができます

```C#:Clamp
float c = Mathf.Clamp(c,a,b);
```
は

```C#:Clamp
if(c > b){
  c = b;
}else if(c < a){
  c = a;
}
```
とほぼ同値です。
例えばキャラのHPなどの実装に使うと可読性の高いコードに出来そうです(基本的に0<HP<MaxHPが成り立つので)
##CorrelatedColorTemperatureToRGB
いや何に使うんだよコレ…
色温度が与えられた引数(1000K~40000K)の時の色を返します。対応はこんな感じ
![578px-Color_temperature.svg.png](https://qiita-image-store.s3.amazonaws.com/0/256231/abf21129-1b43-1207-3801-609e1b7bbed8.png)
https://ja.wikipedia.org/wiki/%E8%89%B2%E6%B8%A9%E5%BA%A6
##GammaToLinearSpace/LinearToGammaSpace
だから何に使うんだよ…
ガンマ色空間とリニア色空間の間で補正を掛ける関数です。Unityにおけるガンマ・リニア色空間についてはこちら
![キャプチャ82.PNG](https://qiita-image-store.s3.amazonaws.com/0/256231/e3a0de17-ff10-58b9-d958-4927791820a9.png)
https://docs.unity3d.com/ja/2017.4/Manual/LinearLighting.html
https://docs.unity3d.com/ja/current/Manual/LinearRendering-LinearOrGammaWorkflow.html
どうやら機械が描写する明暗と人間が認知する明暗の差を補完するシステムらしいですね。
##Lerp/InverseLerp
線形補完です。

```C#:Lerp
float c = Mathf.Lerp(a,b,t);
```
は

```C#:Lerp
float c = a*(1-t) + b*t;
```
と同値です。
逆にInverseLerpはa,b,cを引数としてcに対応するt（パラメタ）を返します。まんまLerpの逆関数ですね。
##PerlinNoise
2次元のパーリンノイズを生成します。
パーリンノイズに関してはこちら
https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%83%AA%E3%83%B3%E3%83%8E%E3%82%A4%E3%82%BA
マイクラの地形生成とかに使われてるらしいよ？
##MoveTowards
第2引数へ第3引数の歩幅で移動します。第二引数を通り越さないように調整してくれます。

```C#:MoveTowards.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveTowards : MonoBehaviour {
    
	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}
    private void OnMouseDown()
    {
        float x = Mathf.MoveTowards(transform.position.x,10,3);
        transform.position = new Vector3(x, 0, 0);
    }
}
```
上の様にコードを打つと下の様に動きます。
![a9d549f3d30d9022273514f79f42ad21.gif](https://qiita-image-store.s3.amazonaws.com/0/256231/32e37da0-94d8-2d0e-783d-16d76c692f14.gif)

##SmoothDamp
> float SmoothDamp(float current,float target,ref float currentVelocity,float smoothTime,float maxSpeed,float deltaTime)

currentからtargetに向かって滑らかに移動するらしいです。currentVelocityは呼び出すたびに変化し、maxspeedは最大速度制限（任意）、deltaTimeにはデフォルトでTime.deltaTimeが入っています（前回と今回の呼び出しの間の時間を代入）。

```C#:SmoothDamp.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmoothDamp : MonoBehaviour {
    public float current = 0;
    public float speed;
	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void FixedUpdate () {
        current = Mathf.SmoothDamp(current,10,ref speed,2f);
        transform.position = new Vector3(current, 0, 0);
	}
}

```
上のように記述すると下のgifのように動きます。なめらか～～～～
![1ed2eaaea0cf7c0c184bdb2a0e12a72d.gif](https://qiita-image-store.s3.amazonaws.com/0/256231/e4b12727-4253-0ce6-3938-65e8315e3552.gif)

**まぁぶっちゃけ使いづらいのでiTweenでも使えばいいと思います!!!!!!!**

#まとめ
Mathfには使える関数と何に使えるのかわからない関数があってとてもよい。
特にCorrelatedColorTemperatureToRGBを活用してる事案があったら教えてください。