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

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

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

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

Unity

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

Q&A

解決済

1回答

785閲覧

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

aiueoao

総合スコア146

Unity3D

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

Unity

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

0グッド

0クリップ

投稿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#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.EventSystems; 5using UnityEngine.UI; 6 7 //Groupオブジェクトにつける. 8 public class ClickObject : MonoBehaviour, IPointerDownHandler, IPointerUpHandler 9 { 10 [SerializeField] 11 private RectTransform A; 12 [SerializeField] 13 private RectTransform B; 14 15 //private PointerEventData tempPed; 16 17 //長押し処理用. 18 private Coroutine coroutine; 19 private readonly float time = 1.0f; 20 21 22 private void Start() 23 { 24 GetComponent<DragObject>().MoveAction += CancelLongTap; 25 } 26 27 /// <summary> 28 /// 長押し成立でおこなう処理. 29 /// </summary> 30 /// <returns></returns> 31 private IEnumerator TimerCoroutine() 32 { 33 yield return new WaitForSeconds(time); 34 Debug.Log("Timer End!"); 35 36 //A,Bの親をCanvas直下に変更.Groupを解消. 37 A.SetParent(this.transform.parent); 38 B.SetParent(this.transform.parent); 39 40 //A,Bをさわれるようにする. 41 A.GetComponent<CanvasGroup>().blocksRaycasts = true; 42 B.GetComponent<CanvasGroup>().blocksRaycasts = true; 43 44 ShootRay(); 45 } 46 47 /// <summary> 48 /// Groupオブジェクト(AorBオブジェクトの上)をTapしたときに呼ばれる. 49 /// </summary> 50 /// <param name="eventData"></param> 51 public void OnPointerDown(PointerEventData eventData) 52 { 53 coroutine = StartCoroutine(TimerCoroutine()); //長押し判定開始. 54 //tempPed = eventData; 55 } 56 57 public void OnPointerUp(PointerEventData eventData) 58 { 59 if (coroutine != null) CancelLongTap(); 60 } 61 62 /// <summary> 63 /// 長押し判定コルーチン動作中に動いたらキャンセル. 64 /// </summary> 65 public void CancelLongTap() 66 { 67 if (coroutine != null) StopCoroutine(coroutine); 68 coroutine = null; 69 // tempPed = null; 70 } 71 72 /// <summary> 73 /// /UserがTapした真のTarget(AorB)にray飛ばして取得. 74 /// </summary> 75 private void ShootRay() 76 { 77 //現在のマウスの位置からレイキャストを撃ってヒットしたものを取得します。 78 GraphicRaycaster gr = transform.root.GetComponent<GraphicRaycaster>(); 79 PointerEventData ped = new PointerEventData(EventSystem.current); // = CopyEventData(tempPed); 80 ped.position = Input.mousePosition; 81 List<RaycastResult> rr = new List<RaycastResult>(); 82 gr.Raycast(ped, rr); 83 GameObject target = rr[0].gameObject; //D&Dの対象となるAorBは一番手前の要素のはず. 84 Debug.Log("Target Name:" + target.name); 85 //AorBオブジェクトならそれをそのままDragしたい 86 if (target.name == "A" || target.name == "B") target.GetComponent<DragObject>().MyContinue(ped, rr[0]); 87 } 88 89 90 private PointerEventData CopyEventData(PointerEventData original) 91 { 92 return new PointerEventData(EventSystem.current) 93 { 94 selectedObject = original.selectedObject, 95 hovered = original.hovered, 96 button = original.button, 97 clickCount = original.clickCount, 98 clickTime = original.clickTime, 99 delta = original.delta, 100 dragging = original.dragging, 101 eligibleForClick = original.eligibleForClick, 102 pointerCurrentRaycast = original.pointerCurrentRaycast, 103 pointerDrag = original.pointerDrag, 104 pointerEnter = original.pointerEnter, 105 pointerId = original.pointerId, 106 pointerPress = original.pointerPress, 107 pointerPressRaycast = original.pointerPressRaycast, 108 position = original.position, 109 pressPosition = original.pressPosition, 110 rawPointerPress = original.rawPointerPress, 111 scrollDelta = original.scrollDelta, 112 useDragThreshold = original.useDragThreshold, 113 }; 114 } 115 116 117 } 118 119

c#

1using UnityEngine; 2using UnityEngine.EventSystems; 3using System; 4using System.Collections; 5 6 7public class DragObject : MonoBehaviour, IBeginDragHandler, IDragHandler 8{ 9 public Action MoveAction; 10 private GameObject groupObj; //AorB用 11 12 private void Start() 13 { 14 groupObj = transform.parent.gameObject; 15 } 16 17 public void OnBeginDrag(PointerEventData eventData) 18 { 19 if (MoveAction != null) MoveAction(); //長押し中に動いた 20 } 21 22 public void OnDrag(PointerEventData eventData) 23 { 24 this.transform.position = eventData.position; 25 } 26 27 28 public void MyContinue(PointerEventData eventData,RaycastResult rr) 29 { 30 StartCoroutine(Method(eventData, rr)); 31 } 32 33 private IEnumerator Method(PointerEventData eventData, RaycastResult rr) 34 { 35 Destroy(groupObj); //Groupオブジェクトを削除. 36 Debug.Log("Destroy"); 37 yield return null; 38 GameObject target = this.gameObject; 39 eventData.pointerDrag = target; 40 eventData.pointerCurrentRaycast = rr; 41 eventData.rawPointerPress = target; 42 eventData.pointerPress = target; 43 eventData.pointerDrag = target; 44 eventData.pointerPressRaycast = rr; 45 eventData.selectedObject = target; 46 Debug.Log(eventData.selectedObject.name); 47 ExecuteEvents.Execute(target, eventData, ExecuteEvents.beginDragHandler); 48 } 49} 50

試したこと

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

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

Unity2020.3.30f1
Microsoft Visual Studio Community 2019 Version 16.11.9

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

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

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

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

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

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()を呼ばない)ということです.親子関係は解消します.
guest

回答1

0

自己解決

根本的な解決ではないですが
親オブジェの

  • Image
  • CanvasGroup
  • DragObject

を取り外し、子のDragObjectで親ごと動かすことで解決しました.

投稿2022/03/27 07:50

aiueoao

総合スコア146

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問