2017-09-18 15 views
0

IPointerEnter,IPointerExit,IPointerDownIPointerUpを実装しようとしました。それぞれのボックスコライダーでIPointerを動作させるには?

重複が始まるまで、すべてが正常に機能していました。

私の質問は、IPointer...をそれぞれのコライダーで動作させるにはどうすればよいですか?

AおよびBは、BoxCollider2D,BAの内側にあります。どちらも、上記のIPointer...を実装したスクリプトを持っています。以下は私がこの状態で抱えている問題です。

  1. Bの中でマウスをクリックすると、1つのボックスでIPointerDownがトリガーされます。 How to detect multiple/Overlapping GameObjects with the EventSystem?
  2. 私のポインタ(マウス)がAの中にあり、ポインタ(マウス)をBに移動すると、Aがトリガーされます(IPointerExit)。私が達成しようとしているのは、AIPointerExitがそれぞれのコライダーでトリガーされるべきです。

私はその後、「IPointerEnter」AがトリガーとBを入力した場合にする必要があります入力した場合、IPointerEnterBは、トリガされなければなりません。

enter image description here

+0

簡単に言えば、組み込みの「IPointer ...」メカニズムを使用して簡単に実現することはできません。あなたの最善の策は、 'Raycast'を使って各層を別々にチェックすることです。 –

+0

@ m.rogalskiレイキャストはUIオブジェクトですか? – Programmer

+0

@Programmerこの新しいUnityのイベントシステムは、[レイキャスティング](https://docs.unity3d.com/Manual/EventSystem.html)で動作します。私がここで見る唯一の方法は、どのレイがそのレイに当たったのかを区別することです。レイヤーが「下」かどうかを確認します。 –

答えて

0

私はそれは、単純なオーバーラップのために働く、上記の問題のためのスクリプトを作成するために管理します。つまり、別のボックスの内側にある必要があるBoxCollider2Dは、最上位層でなければなりません。ただOverlapEventTriggerを延長してください。

using UnityEngine; 
using UnityEngine.EventSystems; 
using System.Collections.Generic; 
using System.Linq; 

namespace TFTM.Event 
{ 
    public enum EventExecuteType 
    { 
     PointerEnter, 
     PointerExit, 
     PointerDown, 
     PointerUp, 
     PointerDrag, 
    } 

    public abstract class OverlapEventTrigger : EventTrigger, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler, IDragHandler 
    { 
    public virtual void MouseDown(PointerEventData eventData){} 
    public virtual void MouseUp(PointerEventData eventData){} 
    public virtual void MouseEnter(PointerEventData eventData){} 
    public virtual void MouseExit(PointerEventData eventData){} 
    public virtual void MouseDrag(PointerEventData eventData){} 

    List<GameObject> ObjectsInCollider = new List<GameObject>(); 
    public List<RaycastResult> lastTotalRaycastResult = new List<RaycastResult>(); 

    public override void OnPointerDown(PointerEventData eventData) 
    { 
     Debug.Log("Down: " + eventData.pointerCurrentRaycast.gameObject.name); 

     MouseDown(eventData); 

     rethrowRaycast(eventData, eventData.pointerCurrentRaycast.gameObject, EventExecuteType.PointerDown); 
    } 

    public override void OnPointerUp(PointerEventData eventData) 
    { 
     Debug.Log("Up: " + eventData.pointerCurrentRaycast.gameObject.name); 

     MouseUp(eventData); 

     rethrowRaycast(eventData, eventData.pointerCurrentRaycast.gameObject, EventExecuteType.PointerUp); 
    } 

    public override void OnPointerEnter(PointerEventData eventData) 
    { 
     if (IsPointerInsideCollider(eventData) && ObjectsInCollider.Contains(gameObject)) 
      return; 

     Debug.Log("Enter: " + eventData.pointerCurrentRaycast.gameObject.name); 

     MouseEnter(eventData); 

     ObjectsInCollider.Add(gameObject); 
    } 

    public override void OnPointerExit(PointerEventData eventData) 
    { 
     //Debug.Log("Is " + gameObject.name + " inside his respective collider : " + IsPointerInsideCollider(eventData)); 

     if (IsPointerInsideCollider(eventData)) 
      return; 

     Debug.Log("Exit: " + gameObject.name); 

     MouseExit(eventData); 

     ObjectsInCollider.Remove(gameObject); 
    } 

    public override void OnDrag(PointerEventData eventData) 
    { 
     //Debug.Log("Drag: " + eventData.pointerCurrentRaycast.gameObject.name); 

     MouseDrag(eventData); 

     rethrowRaycast(eventData, eventData.pointerCurrentRaycast.gameObject, EventExecuteType.PointerDrag); 
    } 

    bool IsPointerInsideCollider(PointerEventData eventData) 
    { 
     PointerEventData pointerEventData = new PointerEventData(EventSystem.current); 
     pointerEventData.position = eventData.position; 

     List<RaycastResult> raycastResult = new List<RaycastResult>(); 

     EventSystem.current.RaycastAll(pointerEventData, raycastResult); 

     for (int i = 0; i < raycastResult.Count; i++) 
     { 
      if (raycastResult[i].gameObject == gameObject) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 

    void rethrowRaycast(PointerEventData eventData, GameObject excludeGameObject, EventExecuteType eventType) 
    { 
     PointerEventData pointerEventData = new PointerEventData(EventSystem.current); 

     pointerEventData.position = eventData.pressPosition; 
     //pointerEventData.position = eventData 

     //Where to store Raycast Result 
     List<RaycastResult> raycastResult = new List<RaycastResult>(); 

     //Rethrow the raycast to include everything regardless of their Z position 
     EventSystem.current.RaycastAll(pointerEventData, raycastResult); 

     //Debug.Log("Other GameObject hit"); 
     for (int i = 0; i < raycastResult.Count; i++) 
     { 
      //Debug.Log(raycastResult[i].gameObject.name); 

      //Don't Rethrow Raycayst for the first GameObject that is hit 
      if (excludeGameObject != null && raycastResult[i].gameObject != excludeGameObject || eventType == EventExecuteType.PointerDrag) 
      { 
       //Re-simulate OnPointerDown on every Object hit 
       simulateCallbackFunction(raycastResult[i].gameObject, eventType); 
      } 
     } 
    } 

    //This causes functions such as OnPointerDown to be called again 
    void simulateCallbackFunction(GameObject target, EventExecuteType eventType) 
    { 
     PointerEventData pointerEventData = new PointerEventData(EventSystem.current); 
     //pointerEventData.ra 
     RaycastResult res = new RaycastResult(); 
     res.gameObject = target; 
     pointerEventData.pointerCurrentRaycast = res; 
     pointerEventData.position = Input.mousePosition; 

     switch (eventType) { 
      case EventExecuteType.PointerDown: 
       ExecuteEvents.Execute(target, pointerEventData, ExecuteEvents.pointerDownHandler); 
       break; 
      case EventExecuteType.PointerUp: 
       ExecuteEvents.Execute(target, pointerEventData, ExecuteEvents.pointerUpHandler); 
       break; 
      case EventExecuteType.PointerDrag: 
       ExecuteEvents.Execute(target, pointerEventData, ExecuteEvents.dragHandler); 
       break; 
      default: 
       break; 
     } 

    } 


} 
関連する問題