Unity勇者の冒険の書

Unityで学んだことや便利なものなど作ったら紹介します

【Unity勇者の奮闘記】Mathf.Clampを使いこなす

こんにちは。

今回はMathf.Clampの使い方等について書いていきたいと思います。

概要

まず、Mathf.Clampの機能ですが「値を指定範囲内に収めてくれるもの」と覚えていいと思います。使い方は、

範囲内に収めた値=Mathf.Clamp(範囲内に指定したい値,最小値,最大値);

という感じで使います。
型はfloat型int型で使えます。

一応リファレンスも載せておきますね。
docs.unity3d.com


言葉では分かりにくいと思うので、使用例などを入れながら説明していきたいと思います。

使用例1(値を制限)

f:id:LightGive:20171101162849p:plain
とりあえずここにHPゲージの付いたシューティングがあります。クリックしたらランダムで1~4のダメージを受けるようにしました。この時、値の制限をかけないとこのようになります。
f:id:LightGive:20171101163145g:plain


見てもらったら分かるように、値に制限をかけていないので、HPがマイナスになっています。

現状はこうなっています。

hp -= Random.Range(1.0f, 4.0f);

これをMathf.Clampを使えば簡単に制限がかけられます。使う方法と使わない方法を書いてみます。

Mathf.Clampを使わない方法

hp -= Random.Range(1.0f, 4.0f);
if(hp < 0)
{
    hp = 0;
}

Mathf.Clampを使う方法

hp = Mathf.Clamp(hp - Random.Range(1.0f, 4.0f), 0.0f, MAX_HP);

これで、マイナスにならず値を制限内に収める事が出来ました。
f:id:LightGive:20171101183004g:plain
こんな感じで使うことが出来ます。

使用例2(座標を制限)

よく使われる例としては、transfom.positionの値に制限をかける事が多いと思います。今回はシューティングで自機が画面内に収まるような処理を作りたいと思います。Colliderで制限をかける方法もありますが、今回は直接座標を移動させる方法で実装していきたいと思います。

f:id:LightGive:20171101154225p:plain
とりあえず3種類の処理を作ってみます。

Mathf.Clampを使わない方法1

//入力を取得
var hor = Input.GetAxis("Horizontal");
var ver = Input.GetAxis("Vertical");

transform.position += new Vector3(hor, ver, 0.0f) * speed * Time.deltaTime;

//画面端から出たら画面内に戻す
if (transform.position.x > limitWidth)
	transform.position = new Vector3(limitWidth, transform.position.y);
else if (transform.position.x < -limitWidth)
	transform.position = new Vector3(-limitWidth, transform.position.y);
if (transform.position.y > limitHeight)
	transform.position = new Vector3(transform.position.x, limitHeight);
else if (transform.position.y < -limitHeight)
	transform.position = new Vector3(transform.position.x, -limitHeight);

Mathf.Clampを使わない方法2

//入力を取得
var hor = Input.GetAxis("Horizontal");
var ver = Input.GetAxis("Vertical");

//現在の座標から足されるベクトル
var addvec = new Vector3(hor, ver, 0.0f) * speed * Time.deltaTime;

//次の座標
var nextPos = transform.position + addvec;
if (nextPos.x > limitWidth || nextPos.x < -limitWidth)
	addvec.x = 0.0f;
if (nextPos.y > limitHeight || nextPos.y < -limitHeight)
	addvec.y = 0.0f;
transform.position += addvec;

Mathf.Clampを使った方法

//入力を取得
var hor = Input.GetAxis("Horizontal");
var ver = Input.GetAxis("Vertical");

transform.position = new Vector3(
	Mathf.Clamp(transform.position.x + (hor * speed * Time.deltaTime), -limitWidth, limitWidth),
	Mathf.Clamp(transform.position.y + (ver * speed * Time.deltaTime), -limitHeight, limitHeight));

という事で、実装しました。下の画像の通り、画面右端より右には移動出来ないようになっています。
f:id:LightGive:20171101152426g:plain

3種類の方法の違いは、こんな感じです。

Mathf.Clampを使わない方法1
f:id:LightGive:20171101155043p:plain
この方法は最初に、入力した方向にとりあえず自機を動かした後、もし画面から出ていた時に画面内へ座標を移動させる方法です。デメリットとしては、処理が重くなってきた時、実際に一度画面外に出ているので、一瞬だけ画面外に出ている瞬間が見えてしまうかもしれないですね。


Mathf.Clampを使わない方法2
f:id:LightGive:20171101155050p:plain
この方法は、次の移動する座標を先に求めておいて、その位置が画面外だった時に移動しない、という方法です。デメリットは、単純に移動距離が大きいときにまだ画面外まで余裕があっても止まってしまう所ですね。

Mathf.Clampを使った方法
f:id:LightGive:20171101155056p:plain
これがMathf.Clampを使用した方法です。うまく1つ目と2つ目のデメリットが無く、指定した画面端ピッタリに移動してくれます。

ざっと座標を制限する時にはこんな感じで使います。

Mathf.Clamp01

あと似ているので一緒に紹介しておきます。
Mathf.Clamp01は、関数の名前の通りMathf.Clampの最小値が0で最大値が1の関数です。ゲームを作る上で結構0~1に制限したい!という事が多いので割と頻繁に使います。

使い方は、Mathf.Clamp01(制限したい値)で使う事が出来ます。

GitHubのリンク

github.com
今回のプロジェクトはまるっとここにあるので、何か分かりにくかったらここからダウンロードして中身を覗いてください。

では。('_')