Advertisement
The_Oddler

Current AdventureInputModule (not yet complete)

Jan 14th, 2015
401
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.35 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4.  
  5. [AddComponentMenu("Event/Adventure Input Module")]
  6. public class AdventureInputModule : BaseInputModule
  7. {
  8.     [SerializeField]
  9.     AdventureEventData _clickEvent = new AdventureEventData();
  10.  
  11.     [SerializeField]
  12.     bool _deselectOnLookAway = true;
  13.     public bool DeselectOnLookAway {
  14.         get { return _deselectOnLookAway; }
  15.         private set { _deselectOnLookAway = value; }
  16.     }
  17.  
  18.     [SerializeField]
  19.     float _defaultInteractionDistance = float.PositiveInfinity;
  20.     public float DefaultInteractionDistance {
  21.         get { return _defaultInteractionDistance; }
  22.         private set { _defaultInteractionDistance = value; }
  23.     }
  24.    
  25.     private PointerEventData pointerData;
  26.     public PointerEventData PointerData { get { return pointerData; } }
  27.    
  28.     protected override void Awake() {
  29.         pointerData = new PointerEventData(eventSystem);
  30.     }
  31.  
  32.     public override void Process()
  33.     {
  34.         bool usedEvent = SendUpdateEventToSelectedObject();
  35.  
  36.         if (!usedEvent) {
  37.             ProcessPointerEvent();
  38.         }
  39.     }
  40.  
  41.     /// <summary>
  42.     /// Process all mouse events.
  43.     /// </summary>
  44.     void ProcessPointerEvent()
  45.     {
  46.         var pointerEvent = GetPointerEventData();
  47.         _clickEvent.ButtonData = pointerEvent;
  48.  
  49.         LimitInteractionDistance(pointerEvent);
  50.  
  51.         if (_deselectOnLookAway && pointerEvent.pointerCurrentRaycast.gameObject == null) {
  52.             ClearSelection();
  53.         }
  54.  
  55.         // Process the first mouse button fully
  56.         ProcessPointerPress(_clickEvent);
  57.         ProcessMove(_clickEvent.ButtonData);
  58.         ProcessDrag(_clickEvent.ButtonData);
  59.  
  60.         if (!Mathf.Approximately(_clickEvent.ButtonData.scrollDelta.sqrMagnitude, 0.0f))
  61.         {
  62.             var scrollHandler = ExecuteEvents.GetEventHandler<IScrollHandler>(_clickEvent.ButtonData.pointerCurrentRaycast.gameObject);
  63.             ExecuteEvents.ExecuteHierarchy(scrollHandler, _clickEvent.ButtonData, ExecuteEvents.scrollHandler);
  64.         }
  65.     }
  66.  
  67.     void LimitInteractionDistance(PointerEventData pointerEvent) {
  68.         var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject;
  69.         if (currentOverGo != null) {
  70.             InteractionDistance currentOverIntDis = currentOverGo.GetComponentInParent<InteractionDistance>();
  71.  
  72.             float interDist = currentOverIntDis == null ? _defaultInteractionDistance : currentOverIntDis.interactionDistance;
  73.             float pointDist = pointerEvent.pointerCurrentRaycast.distance;
  74.  
  75.             if (pointDist > interDist) {
  76.                 pointerEvent.pointerCurrentRaycast = new RaycastResult(); //empty the raycast as if nothing was hit
  77.             }
  78.         }
  79.     }
  80.  
  81.     /// <summary>
  82.     /// Process the current mouse press.
  83.     /// </summary>
  84.     void ProcessPointerPress(AdventureEventData data)
  85.     {
  86.         var pointerEvent = data.ButtonData;
  87.         var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject;
  88.  
  89.         // PointerDown notification
  90.         if (data.PressedThisFrame())
  91.         {
  92.             pointerEvent.eligibleForClick = true;
  93.             pointerEvent.delta = Vector2.zero;
  94.             pointerEvent.dragging = false;
  95.             pointerEvent.useDragThreshold = true;
  96.             pointerEvent.pressPosition = pointerEvent.position;
  97.             pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast;
  98.  
  99.             DeselectIfSelectionChanged(currentOverGo, pointerEvent);
  100.  
  101.             // search for the control that will receive the press
  102.             // if we can't find a press handler set the press
  103.             // handler to be what would receive a click.
  104.             var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler);
  105.  
  106.             // didnt find a press handler... search for a click handler
  107.             newPressed = newPressed ?? ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
  108.  
  109.             // Debug.Log("Pressed: " + newPressed);
  110.  
  111.             float time = Time.unscaledTime;
  112.  
  113.             if (newPressed == pointerEvent.lastPress)
  114.             {
  115.                 var diffTime = time - pointerEvent.clickTime;
  116.                 if (diffTime < 0.3f)
  117.                     ++pointerEvent.clickCount;
  118.                 else
  119.                     pointerEvent.clickCount = 1;
  120.  
  121.                 pointerEvent.clickTime = time;
  122.             }
  123.             else
  124.             {
  125.                 pointerEvent.clickCount = 1;
  126.             }
  127.  
  128.             pointerEvent.pointerPress = newPressed;
  129.             pointerEvent.rawPointerPress = currentOverGo;
  130.  
  131.             pointerEvent.clickTime = time;
  132.  
  133.             // Save the drag handler as well
  134.             pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);
  135.  
  136.             if (pointerEvent.pointerDrag != null)
  137.                 ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag);
  138.         }
  139.  
  140.         // PointerUp notification
  141.         if (data.ReleasedThisFrame())
  142.         {
  143.             // Debug.Log("Executing pressup on: " + pointer.pointerPress);
  144.             ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler);
  145.  
  146.             // Debug.Log("KeyCode: " + pointer.eventData.keyCode);
  147.  
  148.             // see if we mouse up on the same element that we clicked on...
  149.             var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
  150.  
  151.             // PointerClick and Drop events
  152.             if (pointerEvent.pointerPress == pointerUpHandler && pointerEvent.eligibleForClick)
  153.             {
  154.                 ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler);
  155.             }
  156.             else if (pointerEvent.pointerDrag != null)
  157.             {
  158.                 ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler);
  159.             }
  160.  
  161.             pointerEvent.eligibleForClick = false;
  162.             pointerEvent.pointerPress = null;
  163.             pointerEvent.rawPointerPress = null;
  164.  
  165.             if (pointerEvent.pointerDrag != null && pointerEvent.dragging)
  166.                 ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler);
  167.  
  168.             pointerEvent.dragging = false;
  169.             pointerEvent.pointerDrag = null;
  170.  
  171.             // redo pointer enter / exit to refresh state
  172.             // so that if we moused over somethign that ignored it before
  173.             // due to having pressed on something else
  174.             // it now gets it.
  175.             if (currentOverGo != pointerEvent.pointerEnter)
  176.             {
  177.                 HandlePointerExitAndEnter(pointerEvent, null);
  178.                 HandlePointerExitAndEnter(pointerEvent, currentOverGo);
  179.             }
  180.         }
  181.     }
  182.  
  183.     void ProcessMove(PointerEventData pointerEvent)
  184.     {
  185.         var targetGO = pointerEvent.pointerCurrentRaycast.gameObject;
  186.         HandlePointerExitAndEnter(pointerEvent, targetGO);
  187.     }
  188.  
  189.     void ProcessDrag(PointerEventData pointerEvent)
  190.     {
  191.         if (pointerEvent.pointerDrag != null
  192.             && !pointerEvent.dragging
  193.             && ShouldStartDrag(pointerEvent.pressPosition, pointerEvent.position, eventSystem.pixelDragThreshold, pointerEvent.useDragThreshold) )
  194.         {
  195.             ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.beginDragHandler);
  196.             pointerEvent.dragging = true;
  197.         }
  198.  
  199.         // Drag notification
  200.         if (pointerEvent.dragging && pointerEvent.pointerDrag != null)
  201.         {
  202.             // Before doing drag we should cancel any pointer down state
  203.             // And clear selection!
  204.             if (pointerEvent.pointerPress != pointerEvent.pointerDrag)
  205.             {
  206.                 ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler);
  207.  
  208.                 pointerEvent.eligibleForClick = false;
  209.                 pointerEvent.pointerPress = null;
  210.                 pointerEvent.rawPointerPress = null;
  211.             }
  212.             ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.dragHandler);
  213.         }
  214.     }
  215.  
  216.     static bool ShouldStartDrag(Vector2 pressPos, Vector2 currentPos, float threshold, bool useDragThreshold)
  217.     {
  218.         if (!useDragThreshold)
  219.             return true;
  220.  
  221.         return (pressPos - currentPos).sqrMagnitude >= threshold * threshold;
  222.     }
  223.  
  224.     /// <summary>
  225.     /// Send the update event to the selected object (if any)
  226.     /// Returns whether or not the event is used.
  227.     /// </summary>
  228.     bool SendUpdateEventToSelectedObject()
  229.     {
  230.         if (eventSystem.currentSelectedGameObject == null)
  231.         return false;
  232.  
  233.         var data = GetBaseEventData();
  234.         ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler);
  235.         return data.used;
  236.     }
  237.  
  238.  
  239.  
  240.     void ClearSelection()
  241.     {
  242.         if (eventSystem.currentSelectedGameObject) {
  243.             eventSystem.SetSelectedGameObject(null);
  244.         }
  245.     }
  246.  
  247.     protected void DeselectIfSelectionChanged(GameObject currentOverGo, BaseEventData pointerEvent)
  248.     {
  249.         // Selection tracking
  250.         var selectHandlerGO = ExecuteEvents.GetEventHandler<ISelectHandler>(currentOverGo);
  251.         // if we have clicked something new, deselect the old thing
  252.         // leave 'selection handling' up to the press event though.
  253.         if (selectHandlerGO != eventSystem.currentSelectedGameObject)
  254.             eventSystem.SetSelectedGameObject(null, pointerEvent);
  255.     }
  256.  
  257.  
  258.  
  259.     private PointerEventData GetPointerEventData() {
  260.         Vector2 screenMid;
  261.         screenMid.x = Screen.width / 2f;
  262.         screenMid.y = Screen.height / 2f;
  263.         pointerData.Reset();
  264.         pointerData.delta = Vector2.zero;
  265.         pointerData.position = screenMid;
  266.         pointerData.scrollDelta = Vector2.zero;
  267.         pointerData.useDragThreshold = false;
  268.        
  269.         eventSystem.RaycastAll(pointerData, m_RaycastResultCache);
  270.         pointerData.pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache);
  271.         m_RaycastResultCache.Clear();
  272.        
  273.         return pointerData;
  274.     }
  275.  
  276.  
  277.  
  278.  
  279.     [Serializable]
  280.     private class AdventureEventData
  281.     {
  282.         [SerializeField]
  283.         string _clickAxis = "Fire1";
  284.         string ClickAxis {
  285.             get { return _clickAxis; }
  286.             set { _clickAxis = value; }
  287.         }
  288.  
  289.         public PointerEventData ButtonData { get; set; }
  290.  
  291.         public bool PressedThisFrame()
  292.         {
  293.             return Input.GetButtonDown(_clickAxis);
  294.         }
  295.  
  296.         public bool ReleasedThisFrame()
  297.         {
  298.             return Input.GetButtonUp(_clickAxis);
  299.         }
  300.     }
  301. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement