こういったウインドウを見たことがあると思いますが、これは AnimationCurve 型のメンバ変数を持つことで、インスペクタから設定することができます。
AnimationCurve - Unity スクリプトリファレンス
public class AnimationCurveForRandom : MonoBehaviour { [SerializeField] AnimationCurve curve;
今回はこれを使った小技を紹介します。
アニメーションをなめらかに
"アニメーション"カーブなのでとりあえずアニメーションに使ってみましょう。
例えば
void Update () { transform.position = new Vector3(5, 0, 0) * curve.Evaluate (Time.timeSinceLevelLoad); }
とすることで、 座標(0, 0, 0)から(5, 0, 0)まで、カーブに沿った速度で移動していきます。
この方法の利点は、「ココからココまで速度変えながら移動。X秒間でぴったり到着」というような、時間ベースでの移動が可能なところです。
たとえばさっきの移動を8秒間でおこないたい場合、コードを以下のようになおします。
void Update () { transform.position = new Vector3(5, 0, 0) * (curve.Evaluate (Time.timeSinceLevelLoad / 8)); }
これで、シーンロードから8秒間ぴったりで座標(5, 0, 0)まで移動します。
重み付きランダム
例えばガチャで100枚のカードが排出されるとして、1番のカードは出やすく、100番に向かって出づらくするという表現が可能です。
やりかたは簡単で、Rand関数で出てきた値にAnimationCurve#Evaluate をかけて、範囲の値(ここでは 0 〜 99)に変換するだけ。
float seed = curve.Evaluate(Random.value); int index = (int)(seed * 99); // index : 0 〜 99 のどれ か
カーブは下のようなかんじにしておきます。
Unity公式でも紹介されているやりかたです。
ランダムなゲームプレイ要素の追加 - Unity マニュアル
数値の補正(根性値)
0に向かっていくアニメーションカーブを使えば、体力が少なくなるにつれダメージを与えにくくなる敵(いわゆる根性値)などが表現できます。
public class AnimationCurveForDamage : MonoBehaviour { [SerializeField] AnimationCurve curve; const int MaxHP = 100; int HP = MaxHP; void Update () { if (Input.GetMouseButtonDown (0)) { Damage (10); } } void Damage(int damage) { // HPが少ないほどダメージも少ない HP -= (int)(curve.Evaluate ((float)HP / MaxHP) * damage); } }
アニメーションカーブの最小値は0.5くらいにします。
0にしてしまうと絶対に死なない敵になるので注意。