質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

0回答

3134閲覧

Unity: 新しいInput Systemを用いたスワイプとタップ機能の導入 + 常に指の座標を取得し続ける方法について

Kotaro22

総合スコア21

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2021/11/25 11:08

編集2021/11/25 23:48

動作環境
Mac OS Monterey
Unity2020.3.22f
Unity Universal Render Pipeline プロジェクト

インプット機能(スワイプ、タップ)関連初心者です。
現在モバイルアプリを作っているのですが、スマホスクリーンに対しての機能の導入が上手くいっていないので質問を投稿しました。

概要
スマホスクリーンに対して指が触れている間、動的(毎フレーム)に指が触れているポジション(x,y座標)をVector2で取得し、下記のスクリーンショット内に配置されている四角イメージのx,y座標を予めスクリプト内にVector2リストで保存しておいて、指が触れた際に当たり判定を取得する機能を実装しようとしています。

Unityで新しいinput systemが導入されている為、それを利用し2 - 3枚目のスクリーンショットの様にタップとスワイプが出来る様に試みたのですが、指が触れている場所を動的に取り続ける機能の実装が頭の中で上手く組み立てられないので、何方か似たような機能を既に実装された経験のある方居ましたらアドバイスして頂けないでしょうか?? この投稿の最下部に新しいinput systemに対して使用しているスクリプトを記載しておきます。

実装を試みている方法1
指のポジションを常に動的に取得し、スクリプト内で四角イメージの(x,y座標 + 四角イメージの半径をx,yに足し引きし)の合計を用いて、指がそのエリアを通過(スワイプ)した際に当たり判定を取る方法。

実装が出来ていない部分
・新しいinput system上で常に指の座標を取得する方法が分からないという事。(必ずしも新しいinput systemを使わなければいけないという事ではないです。)

下記の動画を参照したのですが、このスクリプトで指の座標をDebug.Logに出力すると常に0 - 1の座標しか表示されません。
スワイプ機能導入参照動画
タップ機能導入参照動画

———————————————
実装を試みている方法2
また上記の実装方法が上手くいかなかった場合に備えて以下の方法も考えています。入力機能に関して知識が浅いので、別に良い方法があったり、これら2つの方法の不備・欠点がある場合は指摘なども同時にして頂けると幸いです。

2dコライダーが付いた透明GameObjectを指が触れた場所にinstantiateして指の動きと共に付随させ、同じく2dコライダーが付いた四角のイメージUIにぶつけて(同じ座標を通過した際に)当たり判定を取る。指が離れたらInstantiateされたGameObjectは破棄。

実装方法が不明な部分
・スワイプの動きに上記のコライダー付きGameObjectを付随させる事。

タップ・スワイプで判定を取りたい四角s

1stContact
1st Contact(中身のBindingはPathがTouch#0/Touch Contact?[Touchscreen], Trigger BehaviourはPress Only)
2nd - 4thと同じ構造です。(Touch#1-3に変わるだけです)

1stPosition

1st Position(中身のBindingはPathがTouch#0/Position[Touchscreen]、以下他の設定はなし)
2nd -4thと同じ構造です。(Touch#1-3に変わるだけです)

Input Systemに使用しているスクリプト

InputManager.cs,
Utils.cs,
SwipeDection.cs

using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.EnhancedTouch; [DefaultExecutionOrder(-1)] public class InputManager : Singleton<InputManager> { #region Events public delegate void SwipeStart(Vector2 position, float time); public event SwipeStart OnSwipeStart; public delegate void SwipeEnd(Vector2 position, float time); public event SwipeEnd OnSwipeEnd; #endregion private TouchControl touchControl; private Camera mainCamera; private void Awake() { touchControl = new TouchControl(); mainCamera = Camera.main; } private void OnEnable() { touchControl.Enable(); TouchSimulation.Enable(); } private void OnDisable() { touchControl.Disable(); TouchSimulation.Disable(); } private void Start() { touchControl.Touch.PrimaryContact.started += ctx => StartTouchPrimary(ctx); touchControl.Touch.PrimaryContact.canceled += ctx => EndTouchPrimary(ctx); } private void StartTouchPrimary(InputAction.CallbackContext context) { if (OnSwipeStart != null) OnSwipeStart(Utils.ScreenToWorld(mainCamera, touchControl.Touch.PrimaryPosition.ReadValue<Vector2>()), (float)context.startTime); } private void EndTouchPrimary(InputAction.CallbackContext context) { if (OnSwipeEnd != null) OnSwipeEnd(Utils.ScreenToWorld(mainCamera, touchControl.Touch.PrimaryPosition.ReadValue<Vector2>()), (float)context.time); } public Vector2 PrimaryPosition() { return Utils.ScreenToWorld(mainCamera, touchControl.Touch.PrimaryPosition.ReadValue<Vector2>()); } }
using UnityEngine; public class Utils : MonoBehaviour { public static Vector3 ScreenToWorld(Camera camera, Vector3 position) { position.z = camera.nearClipPlane; return camera.ScreenToWorldPoint(position); } }
using System.Collections; using UnityEngine; public class SwipeDetection : MonoBehaviour { [SerializeField] private float minimumDistance = .2f; [SerializeField] private float maximumTime = 1f; [SerializeField, Range(0f, 1f)] private float directionThreshhold = .9f; [SerializeField] private GameObject trail; private Coroutine coroutine; private InputManager inputManager; private Vector2 startPosition; private float startTime; private Vector2 endPosition; private float endTime; private void Awake() { inputManager = InputManager.Instance; } private void OnEnable() { inputManager.OnSwipeStart += SwipeStart; inputManager.OnSwipeEnd += SwipeEnd; } private void OnDisable() { inputManager.OnSwipeStart -= SwipeStart; inputManager.OnSwipeEnd -= SwipeEnd; } private void SwipeStart(Vector2 position, float time) { startPosition = position; startTime = time; trail.SetActive(true); trail.transform.position = position; coroutine = StartCoroutine(Trail()); } private IEnumerator Trail() { while (true) { trail.transform.position = inputManager.PrimaryPosition();        //0 - 1の値でしか座標を取得出来ない。 Debug.Log("_M " + inputManager.PrimaryPosition()); yield return null; } } private void SwipeEnd(Vector2 position, float time) { trail.SetActive(false); StopCoroutine(coroutine); endPosition = position; endTime = time; DetectSwipe(); } private void DetectSwipe() { if(Vector3.Distance(startPosition, endPosition) >= minimumDistance && (endTime - startTime) <= maximumTime) { Debug.Log("Swipe Detected"); Debug.DrawLine(startPosition, endPosition, Color.red, 5f); Vector3 direction = endPosition - startPosition; Vector3 direction2D = new Vector2(direction.x, direction.y).normalized; SwipeDirection(direction2D); } } private void SwipeDirection(Vector3 direction) { if(Vector2.Dot(Vector2.up, direction) > directionThreshhold) { Debug.Log("Swipe up"); } else if (Vector2.Dot(Vector2.down, direction) > directionThreshhold) { Debug.Log("Swipe down"); } else if (Vector2.Dot(Vector2.left, direction) > directionThreshhold) { Debug.Log("Swipe left"); } else if (Vector2.Dot(Vector2.right, direction) > directionThreshhold) { Debug.Log("Swipe right"); } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問