5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity】Joy-Conをポインタデバイスとして使う

Last updated at Posted at 2022-12-21

総コン Advent Calendar 2022 19日目の記事です。

今回目指すもの

tcqqa-odkty.gif
JoyconLibの導入からポインターのUIの表示まで行います。

環境

JoyconLib06 2018.2
Unity 2021.3.8 (2019以降なら問題ない気はします)
MacOS Big Sur ver 11.6

対象読者

Unity初心者

JoyconLibの導入

JoyconLibのダウンロード

Joy-ConをUnityで使えるようにパッケージを製作してくださっている方がいるので、これを用います。上のリンクから、JoyConLibのpackageをダウンロードします。
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f313836353635302f34353531303632372d613062622d386135622d336631362d6236663531623666633338382e706e67.png
スクリーンショット 2022-12-03 16.59.38.png

Unityプロジェクトの作成

UnityHubを開いて3Dプロジェクトを作成します。
スクリーンショット 2022-12-03 17.02.23.png

UnityプロジェクトへPackageの導入

画面左上から Assets -> Import Package -> Custom Package を選択します。
スクリーンショット 2022-12-03 17.08.30.png

先ほどダウンロードしたパッケージファイルを選択して、Openしましょう。
スクリーンショット 2022-12-03 17.10.19.png

Unity側で新しくウィンドウが出るので、Importをクリックします。
スクリーンショット 2022-12-03 17.10.37.png
これでPackageが導入できました。

Joy-ConをPCに接続する

Macのシステム環境設定を開いて、Bluetoothの項目を開きます。
スクリーンショット 2022-12-03 17.24.10.png

Joy-Con側面のペアリングボタンを長押ししてペアリングモードにします。
1667353293627-bCHeB31iZXのコピー.png

出てきたデバイス一覧から「Joy-Con(R)」をクリックして接続します。
「Joy-Con(L)」も同じように接続します。
接続済み表記になれば問題なく接続できていると思います。
スクリーンショット 2022-12-17 17.20.37.png
スクリーンショット 2022-12-17 17.21.01.png

サンプルシーンの起動

ProjectビューからAssets -> ScenesをクリックしてScenesフォルダを開きます。
スクリーンショット 2022-12-03 17.15.34.png

Scene1をクリックして、JoyconLibのサンプルシーンに切り替えます。
スクリーンショット 2022-12-03 17.16.02.png
スクリーンショット 2022-12-17 17.45.35.png

Unityの実行ボタンを押してサンプルシーンを実行します。
このような感じで青いCubeがJoy-Conに連動して動けば問題ないと思われます。
Videotogif.gif

ちょっとした解説

今回動かした青色の立方体を動かしているのは、JoyconDemo.csというスクリプトです。
JoyconDemo.csを見てみましょう。
画面左のCubeオブジェクトをクリックして、画面右のInspectorビューにあるJoyconDemoをダブルクリックする。もしくは画面下のAssetsフォルダ内にあるJoyconDemo.csをダブルクリックすることで、c#ファイルを編集できます。
スクリーンショット 2022-12-18 23.48.16.png

VisualStudioで開くと、このようなコードが書かれています。
静的に定義したJoyconManagerクラスのインスタンスから、接続しているJoy-Conのリストを取得し、Joy-Conの右と左をそれぞれJoyconクラスの変数jに代入して、Joy-Conからの情報を受け取る。のようなコードが書いてあるようです。
JoyconManagerクラスのインスタンスを静的に定義しているので、Hierarchyビューにもあるように、どうやら、JoyconManagerスクリプトを付けたオブジェクトがシーン内に1つ必要そうですね。
今回はこれを参考に進めていきます。
スクリーンショット 2022-12-18 23.57.23.png

ポインタデバイスの実装(この記事の肝)

ポインターを実現するためには、
「あるオブジェクトの向きベクトルと、垂直な平面との交点を求めれば良い」です。
先ほどのサンプルの実行でJoy-Conの傾きが取得できそうなことはわかったと思います。
Joy-Conの傾きを反映させたオブジェクトの向きベクトルを利用して実装します。
IMG_2319.jpg

これから、実際にJoyconをポインタとして使うためのコードと設定を書いていきます。

Sceneの作成

Assets/Sceneフォルダに移動して、右クリック
Create -> Scene をクリックして、新しくSceneを作成します。名前はPointerとしました。
スクリーンショット 2022-12-19 0.13.07.png
Sceneアイコンをダブルクリックして新しく作ったSceneの編集に切り替えます。
スクリーンショット 2022-12-19 0.13.29.png

JoyConManagerオブジェクトの作成

Hierarchyビューの何もないところを右クリックして、CreateEmptyを選択します。
オブジェクト名を「JoyConManager」として、空のオブジェクトを作成します。
スクリーンショット 2022-12-19 0.16.39.png

HierarchyビューにできたJoyConManagerをクリックして、InspectorビューのAddComponentからJoyConManager.csをアタッチします。
スクリーンショット 2022-12-19 0.20.34.png
スクリーンショット 2022-12-19 0.20.44.png
スクリーンショット 2022-12-19 0.28.56.png

Cube,Plane,Sphereオブジェクトの作成

先ほどと同じようにオブジェクトを作成します。
create -> 3DObject -> Cube を選択してCube(JoyConCube)を作成します。
同様にPlane(JoyConPlane), Sphere(JoyConPlane)を作成します。
スクリーンショット 2022-12-19 0.40.20.png

Cubeオブジェクト用のスクリプト JoyConCube.cs を作成

JoyConCubeオブジェクトを選択して、AddComponentをします。
New Scriptをクリックして、名前はJoyConCubeなどにして、スクリプトを作成&アタッチします。
スクリーンショット 2022-12-21 13.01.16.png
スクリーンショット 2022-12-21 13.02.26.png
スクリーンショット 2022-12-21 13.03.27.png

JoyconDemo.csを参考にして、以下のような必要最低限のコードを書きます。
傾きの回転がCubeオブジェクトに反映されればOKです。

JoyConCube.cs
using UnityEngine;
using System.Collections.Generic;

public class JoyConCube : MonoBehaviour
{
	private List<Joycon> joycons;

	// Values made available via Unity
	public float[] stick;
	public Vector3 gyro;
	public Vector3 accel;
	public int jc_ind = 0;
	public Quaternion orientation;

	void Start()
	{
		gyro = new Vector3(0, 0, 0);
		accel = new Vector3(0, 0, 0);
		joycons = JoyconManager.Instance.j;
		if (joycons.Count < jc_ind + 1)
		{
			Destroy(gameObject);
		}
	}

	// Update is called once per frame
	void Update()
	{
		// make sure the Joycon only gets checked if attached
		if (joycons.Count > 0)
		{
			Joycon j = joycons[jc_ind];

			// Bボタンでセンター位置のリセット
			if (j.GetButtonDown(Joycon.Button.DPAD_DOWN))
			{
				j.Recenter();
			}

			gyro = j.GetGyro();
			accel = j.GetAccel();

			orientation = j.GetVector();
			gameObject.transform.rotation = orientation;
		}
	}
}

JoyConSphere.csの作成

Joy-Conのポインターの先で面との交点となるSphereを動かすJoyConSphere.csを作ります。
先ほどと同様にして、JoyConSphereオブジェクトにJoyConSphere.csを作成&アタッチします。
以下の記事を参考にして、コードを書きます。

JoyConSphere.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class JoyConSphere : MonoBehaviour
{
    public GameObject StartPoint;
    public GameObject Plane;

    // Update is called once per frame
    void Update()
    {
        var n = Plane.transform.up;
        var x = Plane.transform.position;
        var x0 = StartPoint.transform.position;
        var m = StartPoint.transform.forward;
        var h = Vector3.Dot(n, x);

        var intersectPoint = x0 + ((h - Vector3.Dot(n, x0)) / (Vector3.Dot(n, m))) * m;

        transform.position = intersectPoint;
    }
}

unityエディタに戻って、JoyConSphereオブジェクトのInspectorビューで、
上のコードでpublicとして定義したStartPointとPlaneを設定します。
StartPointに、JoyConCubeオブジェクトを
Planeに、JoyConPlaneオブジェクトをドラッグ&ドロップしてアタッチします。
スクリーンショット 2022-12-21 13.36.35.png

オブジェクトの位置の微修正

このまま実行するとJoyConCubeオブジェクトはデフォルトで真上を向いているので、それに合わせて各オブジェクトの位置を変えます。

JoyConSphereオブジェクトのtransformのPositionのYの座標を10にします。
スクリーンショット 2022-12-21 13.49.23.png
JoyConPlaneオブジェクトのtransformのPositionのYの座標を10にします。
transformのRotationのXの座標を180にします。
スクリーンショット 2022-12-21 13.51.10.png

実行してみる

ここで一度実行してみましょう。SphereがCubeの向きの延長上に動けばOKです。
317y7-i3shc.gif
次に、Sphereの座標を利用してUIに組み込みます。

UI用の画像の作成と、ポインタに同期して動かす

UIとして画面に表示させるようにします。

UI画像の作成

Hierarchyビューの何もないところで右クリックをして、UI->RawImage を選択してポインタ用の画像を作ります。
スクリーンショット 2022-12-21 14.12.32.png

RawImageのRectTransfromからWidth,Heightをそれぞれ25くらいで、色は赤色などにしましょう。
スクリーンショット 2022-12-21 14.16.05.png

ポインタに同期して動かす

RawImageにPointerImage.csなどのスクリプトを作成・アタッチします。以下のようなコードを書きます。

PointerImage.cs
using UnityEngine;

public class PointerImage : MonoBehaviour
{
    public Transform SphereTransfrom;
    private RectTransform rectTransform;
    // 任意の倍率、大きくすると小さい動きで大きく動く
    private float scale = 50.0f;

    void Start()
    {
        rectTransform = GetComponent<RectTransform>();
    }

    void Update()
    {
        float x = SphereTransfrom.position.x * scale;
        float y = SphereTransfrom.position.z * -scale;
        rectTransform.anchoredPosition = new Vector3(x, y, 0);
    }
}

untiyエディタでPointerImage(Script)のSphereTransform欄に、JoyConSphereオブジェクトをドラッグ&ドロップしてアタッチします。これで全ての工程が終わりました。

完成

ilri2-juse4.gif
こんな感じで上手く動けばポインタデバイスとしての表示までできました。
感度はPointerImage.csのscaleの値をいじるか、JoyConPlaneのy座標をもっと遠くに設定するかなどすれば変えられます。
あとは、ボタンを押して決定できたりすればゲームに組み込めますね!!

おまけ

実はこの記事は僕が作ったゲーム「一限侍」の実装解説でもありました。
ゲーム内では、このような感じでUIボタンを配置してポインタで選択・決定をできるようにしました。
t61c1-718j8.gif
また時間があれば斬る動作の実装の記事も書こうと思います。

参考にした記事

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?