前提
以下の様な親子構造になっているオブジェクトの「子」を選択して動かせるようにする機能を実装しています.
親である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
回答1件
あなたの回答
tips
プレビュー