オンラインレッスンで受講中の会員様より、タブレットでJoyStickを使ったゲームを開発したい、とのリクエストを頂きました。 2Dゲームなどでよく使用されるジョイスティック、今回は自作で作る方法をご説明します。
1,完成イメージと要件
1.1 完成イメージ
完成イメージは下のような感じです。スティックを傾けた方向にターゲットのサークルが移動、フレームの範囲内で中心からの距離が大きいほど速く移動するようにします。
1.2 要件
今回の要件は以下の通り
JoyStickとFrameで構成され、最初はともに同じ座標(中心位置)に配置される
JoyStickをドラッグして動かし、動かした方向に対象のオブジェクトを動かす
中心からの距離が大きいほど、強い力で移動する
JoyStickをFrame外にドラッグした場合は、中心とマウスの位置を結ぶ直線とFrameの円周が交差する場所にJoyStickが配置される
JoyStickはマウスを離したタイミングで中心位置(元の位置)に戻される
2,素材の準備
2.1 素材の作成
JoyStickの素材となるStick画像とFrame画像はAssetStore「Sci-Fi GUI」よりお借りします。
以下のようにHierarchy上に3つのオブジェクトを用意、取得した素材を活用し以下のように配置します。
Canvas の配下に UI ⇒ Image を取得し以下のように指定。
【JoyStickFrame】 JoyStickの外側のフレームになる部分です。 Anchor を Left-Bottom に指定し、Width 及び Height を それぞれ200、左から100、下から100 の位置に配置します。 画像には取り込んだ素材から「joystick-back」を指定。
【JoyStick】 JoyStickの内部、ドラッグして操作する部分です。 Anchor を Left-Bottom に指定し、Width 及び Height を それぞれ100、左から100、下から100 の位置に配置します。 画像には取り込んだ素材から「joystick」を指定。
実際に動かすオブジェクトはお好みのものを指定してください。 サンプルでは 2D Object からSprites > Circle を選んでみました。
【Circle】 任意の色を指定して、Rigidbody2D コンポーネントを追加します。 BodyType を「Kinematic」に指定し、重力等外部の物理的影響を受けないように指定しておきます。
これで素材の準備は完成です。
3,JoyStick のプログラム
3.1 Stick のプログラム
先にJoyStick本体、マウスでつかんで動かす部分を作成します。 「JoyStickController」などと任意の名前を指定してスクリプトファイルを作成しておきましょう。 まずは以下の変数の宣言、作成した「JoyStickController.cs」に以下の変数を宣言します。 最終的に「Circle」には アクセス修飾子を public で指定した変数「inputDt」を伝えます。
[SerializeField] GameObject joyFrame; //JoyStick オブジェクト
float radius; //フレームの半径
Vector2 stickPos; //JoyStickの座標
Vector2 startPos; //フレームの座標(JoyStickの初期位置)
public Vector2 inputDt; //Joystickが伝える大きさ
Vector2 dir; //JoyStickの中心から見た方向
続いてStart()関数にコードを追加します。ここで行うことは次の2つ 1, 宣言した変数「startPos」にフレームの初期座標を代入する 2, 宣言した変数「radius」にフレームの半径を代入する
void Start()
{
startPos = joyFrame.transform.position;
//radius にFrameの半径を代入
radius = joyFrame.GetComponent<RectTransform>().sizeDelta.x/2;
}
続いて、JoyStickの位置から変数「inputDt」 にデータを代入する動きを作ります。 「inputDt」はVector2型の変数で、x,y それぞれに、-1 ~ 1 までの値が代入されます。 ここでは、JoyStickの座標も管理します。
public void DragStick()
{
stickPos = Input.mousePosition; //stickPosにマウス座標を代入
//inputDt の x の値を決めるコード
if (Mathf.Abs(stickPos.x - startPos.x) < radius) //マウス座標がFrameの内部だったら
{
inputDt.x =( stickPos.x - startPos.x)/radius; //inputDt の x の値を指定
}
else //マウス座標がFrameの外部であれば
{
//inputDt の x の値を中心の左側であれば 1 右側であれば -1 に指定
inputDt.x = Mathf.Abs(stickPos.x - startPos.x) / (stickPos.x - startPos.x);
}
//inputDt の y の値を決めるコード
if (Mathf.Abs(stickPos.y - startPos.y) < radius)
{
inputDt.y = (stickPos.y - startPos.y)/radius;
}
else
{
inputDt.y = Mathf.Abs(stickPos.y - startPos.y) / (stickPos.y - startPos.y);
}
//JoyStick の座標を決めるコード
if (Vector2.Distance(startPos, stickPos) < radius) //stickPos がFrame内に位置していたら
{
transform.position = startPos + inputDt * radius; //JoyStickの座標はマウスの位置
}
else //stickPos がFrameの外にはみ出していたら
{
dir = stickPos - startPos; //中心から見たstickPosの方向を dir に代入
//JoyStickの座標は dir の方向にradius 分だけ進んだ位置
transform.position = startPos + dir / Vector2.Distance(startPos, stickPos)*radius;
}
}
最後はJoyStickをつかんでいるマウスを離したときの動きです。
public void ReleaseStick()
{
transform.position = startPos; //座標を startPos に戻す
}
これでJoyStickに必要な関数が完成しました。
3.2 Stick の 設定
作成したプログラムを「JoyStick」のオブジェクトにアタッチし、[SerializeField] で指定した変数「joyFrame」に「JoyStickFrame」のオブジェクトを指定します。
続いて「EventTriggerコンポーネント」を追加して作成した2つの関数を指定します。
【Drag】(JoyStickをクリックして移動させている間の動き) JoyStick の JoyStickCOntroller クラス、関数:DragStick() を指定 【Pointer Up】(ドラッグ中にマウスのクリックを解除したときの動き) JoyStick の JoyStickCOntroller クラス、関数:ReleaseStick() を指定
これでJoyStick のプログラムは完成です。 JoyStickがマウスの動きに合わせて移動、クリックを解除したときに元の座標に戻ることを確認しておきましょう。
4,Circle のプログラム
続いてJoyStickの動きに合わせて移動するCircleの動きを作成します。 このプログラムでは Rigidbody2D の velocity プロパティを使用して移動を実現します。
4.1 Circle のプログラム
CircleManager のような適当なスクリプトファイルを作成し、Circleにアタッチします。 「CircleManager.cs」を立ち上げて、以下のコードを作成します。
まずは変数の宣言と、宣言した変数に初期値を代入します。 変数は先に作成済みの「StickControllerクラス」にアクセスするための変数「js」、さらに「Rigidbody2D」コンポーネントにアクセスするための変数「rb」の2つです。
JoyStickController js; //JoyStickController を使うための変数
Rigidbody2D rb; //Rigidbody2D を使うための変数
void Start()
{
js = GameObject.FindObjectOfType<JoyStickController>();
rb = GetComponent<Rigidbody2D>();
}
Circle は StickControllerクラスがもつ、変数「inputDt」の大きさに合わせて移動します。Rigidbody2D の Velocity プロパティはVector2型なので、inputDt をそのまま使用することができますね。
void Update()
{
rb.velocity = js.inputDt;
}
これでJoyStickに合わせて移動する動きができました。 では実際に起動させてみて、JoyStickの動きに合わせてCircleオブジェクトが動くのを確認しておきましょう。
今回は簡単な移動プログラムを作りましたが、Vector2型の「inputDt」の値を活用すれば、様々な動きを作ることができます。
ファイブボックスでは実際に通って頂いての授業の他、ちょっとしたお困りごとに対するオンライン授業やオンラインサポートも行っております。
お困りごとのある方、ご興味がある方は、ぜひお問い合わせください。
お問い合わせは こちら から。
体験授業のお申込みは こちら から。
Comments