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

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

新規登録して質問してみよう
ただいま回答率
87.20%
Unity3D

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

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

解決済

親オブジェクトへのタップで子のオブジェクトも触りたい

aiueoao
aiueoao

総合スコア128

Unity3D

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

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

1回答

0評価

0クリップ

240閲覧

投稿2022/03/25 05:32

前提

以下の様な親子構造になっているオブジェクトの「子」を選択して動かせるようにする機能を実装しています.
イメージ説明
親であるGroupオブジェクト
親であるGroupオブジェクト子オブジェ(A,B同じ)子オブジェ
親(Groupオブジェクト)のDragと,AorB各オブジェクトのDragが出来る様にするために親子構造になっています.
子のDragをする際は親子関係を解消してCanvas直下にA,Bが来るようにしています.
親のDragか子のDragかの判定は,子(実際にはGroupオブジェ)の長押し成立でしています.
長押し成立 →親子関係を解消して指定した子を動かせるようにする.
長押し不成立→親子関係は解消せず親を動かせる(=A,B相対位置を変えずに動かせる).

実現したいこと&発生している問題

一度のタップで子のDragまで行いたいのですが,Dragが出来ません.

該当のソースコード

c#

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; //Groupオブジェクトにつける. public class ClickObject : MonoBehaviour, IPointerDownHandler, IPointerUpHandler { [SerializeField] private RectTransform A; [SerializeField] private RectTransform B; //private PointerEventData tempPed; //長押し処理用. private Coroutine coroutine; private readonly float time = 1.0f; private void Start() { GetComponent<DragObject>().MoveAction += CancelLongTap; } /// <summary> /// 長押し成立でおこなう処理. /// </summary> /// <returns></returns> private IEnumerator TimerCoroutine() { yield return new WaitForSeconds(time); Debug.Log("Timer End!"); //A,Bの親をCanvas直下に変更.Groupを解消. A.SetParent(this.transform.parent); B.SetParent(this.transform.parent); //A,Bをさわれるようにする. A.GetComponent<CanvasGroup>().blocksRaycasts = true; B.GetComponent<CanvasGroup>().blocksRaycasts = true; ShootRay(); } /// <summary> /// Groupオブジェクト(AorBオブジェクトの上)をTapしたときに呼ばれる. /// </summary> /// <param name="eventData"></param> public void OnPointerDown(PointerEventData eventData) { coroutine = StartCoroutine(TimerCoroutine()); //長押し判定開始. //tempPed = eventData; } public void OnPointerUp(PointerEventData eventData) { if (coroutine != null) CancelLongTap(); } /// <summary> /// 長押し判定コルーチン動作中に動いたらキャンセル. /// </summary> public void CancelLongTap() { if (coroutine != null) StopCoroutine(coroutine); coroutine = null; // tempPed = null; } /// <summary> /// /UserがTapした真のTarget(AorB)にray飛ばして取得. /// </summary> private void ShootRay() { //現在のマウスの位置からレイキャストを撃ってヒットしたものを取得します。 GraphicRaycaster gr = transform.root.GetComponent<GraphicRaycaster>(); PointerEventData ped = new PointerEventData(EventSystem.current); // = CopyEventData(tempPed); ped.position = Input.mousePosition; List<RaycastResult> rr = new List<RaycastResult>(); gr.Raycast(ped, rr); GameObject target = rr[0].gameObject; //D&Dの対象となるAorBは一番手前の要素のはず. Debug.Log("Target Name:" + target.name); //AorBオブジェクトならそれをそのままDragしたい if (target.name == "A" || target.name == "B") target.GetComponent<DragObject>().MyContinue(ped, rr[0]); } private PointerEventData CopyEventData(PointerEventData original) { return new PointerEventData(EventSystem.current) { selectedObject = original.selectedObject, hovered = original.hovered, button = original.button, clickCount = original.clickCount, clickTime = original.clickTime, delta = original.delta, dragging = original.dragging, eligibleForClick = original.eligibleForClick, pointerCurrentRaycast = original.pointerCurrentRaycast, pointerDrag = original.pointerDrag, pointerEnter = original.pointerEnter, pointerId = original.pointerId, pointerPress = original.pointerPress, pointerPressRaycast = original.pointerPressRaycast, position = original.position, pressPosition = original.pressPosition, rawPointerPress = original.rawPointerPress, scrollDelta = original.scrollDelta, useDragThreshold = original.useDragThreshold, }; } }

c#

using UnityEngine; using UnityEngine.EventSystems; using System; using System.Collections; public class DragObject : MonoBehaviour, IBeginDragHandler, IDragHandler { public Action MoveAction; private GameObject groupObj; //AorB用 private void Start() { groupObj = transform.parent.gameObject; } public void OnBeginDrag(PointerEventData eventData) { if (MoveAction != null) MoveAction(); //長押し中に動いた } public void OnDrag(PointerEventData eventData) { this.transform.position = eventData.position; } public void MyContinue(PointerEventData eventData,RaycastResult rr) { StartCoroutine(Method(eventData, rr)); } private IEnumerator Method(PointerEventData eventData, RaycastResult rr) { Destroy(groupObj); //Groupオブジェクトを削除. Debug.Log("Destroy"); yield return null; GameObject target = this.gameObject; eventData.pointerDrag = target; eventData.pointerCurrentRaycast = rr; eventData.rawPointerPress = target; eventData.pointerPress = target; eventData.pointerDrag = target; eventData.pointerPressRaycast = rr; eventData.selectedObject = target; Debug.Log(eventData.selectedObject.name); ExecuteEvents.Execute(target, eventData, ExecuteEvents.beginDragHandler); } }

試したこと

コードに記したように,親子関係が解消された後にスクリプト上からRayを打ってExecuteEvents.Execute()することでDrag出来る様にならないか試してみましたがダメでした.

補足情報(FW/ツールのバージョンなど)

Unity2020.3.30f1
Microsoft Visual Studio Community 2019 Version 16.11.9

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

bboydaisuke

2022/03/25 07:16

現状とやりたい事がよくわからないのですが、 > 子のDragをする際は親子関係を解消してCanvas直下にA,Bが来るようにしています. > 親のDragか子のDragかの判定は,子(実際にはGroupオブジェ)の長押し成立でしています. > 長押し成立 →親子関係を解消して指定した子を動かせるようにする. > 長押し不成立→親子関係は解消せず親を動かせる(=A,B相対位置を変えずに動かせる). これらは現状ですか?だとしたら、やりたい事ができるようになったらこれらはどう変わりますか?
aiueoao

2022/03/25 14:01

やりたいことは、AorB上でのTapが長押しだった場合にそのTapした状態からAorBをそのままDrag出来る様にすることです. 現状として、親子関係の解消・長押し判定・長押し不成立時の挙動 は出来ています. コード上で言えば、DragObject.Method()が意図した動作になりません. ExecuteEvents.Execute()でdragHandlerも追加してみましたが動きませんでした.
bboydaisuke

2022/03/25 14:44 編集

> 長押し成立 →親子関係を解消して指定した子を動かせるようにする. ↑これが現状で、やりたい事が↓で、 > AorB上でのTapが長押しだった場合にそのTapした状態からAorBをそのままDrag出来る 「そのまま」を「親子関係は解消して単独で」と解釈したら、現状 = やりたい事、に聞こえます。 現状は何で、やりたい事は何で、現状とやりたい事はどう違っていて、「そのまま」とはどういう意味なのかがわかりません。
aiueoao

2022/03/25 14:41

そのままというのは Tapしたまま(=OnPointerUp()を呼ばない)ということです.親子関係は解消します.

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Unity3D

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

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。