マウスカーソルによってゲームオブジェクトがイージングする。
Unityでゲームを作成していると、自分や敵、壁などのGameObjectを動かしたい場面があります。
アニメーションは次のようにUnity搭載のシステムでつけることができます。
このアニメーションはフローチャートで直感的に作成できるため、非常に便利です。
しかしながら、このアニメーションはプラットフォームに依存したシステムであるため、汎用性は低く、挙動を付けたいUIやゲームオブジェクトが矢印とパラメータなどが大量に生成されると、視覚性を損ないます。
また、Unityでアニメーションを実装する際に、
シーン切り替えの演出が重要な要素です。
加えて、UIのマウス操作も有効です。
本記事では、Unity標準規格のアニメーションシステムを使わず、
Vector2を使ったスクリプトでアニメーションを作成します。
- スクリプトでアニメーションを作りたい人
- Vector2やVector3の使い方を知りたい人
- Unityでイージング関数を使いたい人
Vector2・Vector3
初めに、「Vector2」と「Vector3」について紹介します。
「Vector2」は、2次元(X座標、Y座標)で扱うベクトルとその位置を表現する構造体です。
「Vector3」は、3次元(X座標、Y座標、Z座標)の表現をします。
「Vector」を扱う上で、基本となる構造は次のようになります。
using UnityEngine;
public class Vector2_Basis : MonoBehaviour
{
Vector2 Basis = new Vector2(1, 2); //X=1,Y=2に相当
Debug.Log(Basis); //1,2
Debug.Log(Basis.x); //1
Debug.Log(Basis.y); //2
}
int型やfloat型などの見慣れた変数と同様に「Basis」はVector2型の変数となります。
Vectorには、その他にベクトルの長さを取得する「Vector2.magnitude」。
aからbに向けてcだけ移動させた分のベクトルを取得できる「Vector2.MoveTowards(a, b, c)」などがあります。
本記事では、ベクトルa,b間をtで補完する関数「Vector2.Lerp(a, b, t)」を使用します。
Vector2.Lerp()
それでは、関数「Vector2.Lerp()」を使ったプログラミングを紹介します。
「Vector2.Lerp()」のLeapは、Linear interpolation(線形補正)を意味します。
ベクトルa,b(以下、それぞれa,bとします。)の終点の距離を1として、その割合によって内分点を示します。線形補正のこの考えは高校数学のベクトル方程式に相当します。
HierarchyウィンドウからUIあるいは、2DObjectから、GameObjectを追加してください。
さらに、Assetウィンドウで新規スクリプトを作成し、以下のソースコード作成します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public GameObject gameObject;
float MoveTime = 3.0f; // 移動時間
float ElapsedTime = 0f; // 経過時間
float Rate; // 割合
float Fn; // 関数
Vector2 Preposition; // 移動前位置
Vector2 Postposition; // 移動後位置
bool Flag = true;
RectTransform Rect;
void Start()
{
Rect = gameObject.GetComponent<RectTransform>();
Preposition = Rect.anchoredPosition; // 移動前位置1
Preposition = new Vector2(0, 0); // 移動前位置2
Postposition = new Vector2(0, 100); // 移動後位置
}
void Update()
{
if (Flag == false)
{
return;
}
// 経過時間を過ぎた処理
if (ElapsedTime >= MoveTime)
{
Flag = false;
return;
}
ElapsedTime += Time.deltaTime; // 経過時間の加算
Rate = Mathf.Clamp01(ElapsedTime / MoveTime); // 割合
Fn = Rate; // 直線
// 移動
Rect.anchoredPosition = Vector2.Lerp(Preposition, Postposition, Fn);
}
}
GameObject「gameObject」に、Textをそれぞれアタッチしてください。
移動前位置1の「Rect.anchoredPosition」はゲームオブジェクトの現在地になります。
移動前位置2は現在地ではなく、座標からスタート地点を決める場合に使用します。
マウスポインターの位置でゲームオブジェクトを動かす。
マウスポインターの位置でアニメーションを稼働させるプログラミングを作成します。
画面の中心を(0,0)として扱う「RectTransform」を採用して開発をします。
ソースコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public GameObject gameObject;
float MoveTime = 0.5f; // 移動時間
float ElapsedTime = 0f; // 経過時間
float Rate; // 割合
float Fn; // 関数
Vector2 Preposition; // 移動前位置
Vector2 Postposition; // 移動後位置
RectTransform Rect;
void Start()
{
Rect = gameObject.GetComponent<RectTransform>();
Preposition = new Vector2(1163, 0); // 初期位置
Postposition = new Vector2(670, 0); // 移動後の位置
}
void Update()
{
Vector2 MousePosition = Input.mousePosition;
Debug.Log("X座標:::" + MousePosition.x+"\n"+"Y座標:::" + MousePosition.y);
// マウス位置が指定範囲内にあるかを確認
if (MousePosition.x >= 1300)
{
ElapsedTime += Time.deltaTime;
if (ElapsedTime > MoveTime)
{
ElapsedTime = MoveTime; // 移動時間の最大値に設定
}
}
else // マウス位置が指定範囲外にある場合は逆の動きをする
{
ElapsedTime -= Time.deltaTime;
if (ElapsedTime < 0f)
{
ElapsedTime = 0f; // 経過時間を0にする(初期位置に戻す)
}
}
// 割合とイージング計算
Rate = Mathf.Clamp01(ElapsedTime / MoveTime); // 割合計算
Fn = -(Mathf.Cos(Mathf.PI * Rate) - 1) / 2; // イージング計算(OutCubicのような滑らかな動き)
// 現在の位置をイージングを使って更新
Rect.anchoredPosition = Vector2.Lerp(Preposition, Postposition, Fn);
}
}
UdemyでUnityを学習
Udemyは、オンデマンド式の学習講座です。
趣味から実務まで使えるおすすめの講座を紹介します。
ビックセール開催中(12月19日まで)
対象のコースが1500円から(最大95%OFF)
- 【Unity C# ゲーム開発超入門】7つのミニゲームを作っておぼえる!UnityとC#講座
Unityで頻出の機能を実際のゲーム作りで学習。
何か作りたい、今後の開発で役立てたい初心者におすすめ
- 【Unity C# ゲーム開発初心者レベルアップ】7つのトランプゲームを作っておぼえる!UnityとC#講座
トランプやボードゲーム作りに特化している講座。
テーブルゲームを作りたい人におすすめ。
- 【全行程を網羅!最初に学びたい総合学習】Unityワールド制作講座
Unityワールド制作の全工程を学習できる講座。
RPGを作りたい人におすすめ。
- Unity ゲーム開発:インディーゲームクリエイターが教える C#の基礎からゲームリリースまで【スタジオしまづ】
C#の文法やApp StoreとGoogle Playへゲームをリリース方法を解説。
ゲームを出品したい人におすすめ。
解説
初めに変数を定義します。
「gameObject」はGameObjectで、アニメーションの対象を後にアタッチします。
「MoveTime」・「ElapsedTime」・「Rate」・「Fn」はそれぞれfloat型の変数で、「MoveTime」は何秒かけて移動するか、「ElapsedTime」は何秒経過したか、「Rate」は経過した時間(ElapsedTime)が全体の時間(MoveTime)どれほどを占めるかを示す割合であるか、「Fn」はどのような緩急をさせるかを関数で表現する変数です。
「Preposition」・「Postposition」はVector2型の変数で、それぞれどこから出発して、どこに到着するのか表現するものです。
「Flag」はbool型の変数で、True(真)の時はプログラムを稼働させて、False(偽)の時は停止させます。ただし、前ソースコードとは異なり動作を停止させないため今回は不要です。
「Rect」はRectTransform型の変数で、ゲームオブジェクトの位置を表現します。
つづいて、関数「Start()」にコードを書きます。
変数「Rect」にRectTransformの動きを付けるために「gameObject」をcomponentします。
また、Vector型変数「Preposition」は画面外の位置(1163, 0)に「Postposition」は画面内の位置(670,0)に設定します。
最後に、関数「Update()」にコードを書きます。
Vector2型変数 「MousePosition」にマウスポインター(カーソル)の位置つまり座標を取得します。
また、float型変数「ElapsedTime」をif条件で指定したX座標より小さい場合は、Time.deltaTimeで1秒ずつ加算します。
X座標より小さい場合は、Time.deltaTimeで1秒ずつ減算します。この時の挙動は逆再生すると考えてください。
float型変数「Rate」が0になったときは、経過時間を0(初期化)にします。
この処理をしないと、経過時間が最大で移動時間の2倍になります。
folat型変数「Rate」に数学関数Mathf.Clamp01()を使って移動時間と経過時間の割合を出します。Mathf.Clamp01()は割合を0~1で表現するため、後述する線形補間を表現する「Vector2.Lerp」と相性良いです。
folat型変数「Fn」を使ってアニメ―ションの関数を作成します。XYグラフにおいて、XはRate、YはFnに相当します。
Fn=Rate; //y=x
Fn=Rate*Rate; //y=x^2---xの2乗
本ソースコードの関数はこちらを参考にしました。
関数からグラフを作成するソフトを使えば、オリジナルのアニメ―ション緩急をつけることもできます。
「Rect.anchoredPosition」に「Vector2.Leap」を代入して、ゲームオブジェクトを移動させます。
最後に、ゲームオブジェクト内でUIボタンがあり、処理を実装できます。
そのままだと、画面クリックも同時に処理されてしまいます。
UIと画面クリック判定を区別、UIの処理無効にする処理の実装も大切です。
まとめ
スクリプトでゲームオブジェクトを操作(アニメーション)するには、Vector2を使用します。
このとき、稼働時間や経過時間などの割合から座標を決める線形補間を駆使します。
今回扱ったGameObjectについて詳細に解説している記事があります。あわせてご覧ください。