2015-02-10 08:03:38 +08:00
/// Credit Chris Trueman
/// Sourced from - http://forum.unity3d.com/threads/use-reticle-like-mouse-for-worldspace-uis.295271/
2020-10-09 00:07:39 +08:00
using UnityEngine.UI.Extensions ;
2015-02-10 08:03:38 +08:00
namespace UnityEngine.EventSystems.Extensions
{
[RequireComponent(typeof(EventSystem))]
2015-10-10 03:26:03 +08:00
[AddComponentMenu("Event/Extensions/Aimer Input Module")]
2015-02-27 04:42:26 +08:00
public class AimerInputModule : PointerInputModule
2015-02-10 08:03:38 +08:00
{
2015-02-27 04:42:26 +08:00
/// <summary>
/// The Input axis name used to activate the object under the reticle.
/// </summary>
2015-08-30 19:58:34 +08:00
public string activateAxis = "Submit" ;
2015-02-27 04:42:26 +08:00
/// <summary>
/// The aimer offset position. Aimer is center screen use this offset to change that.
/// </summary>
public Vector2 aimerOffset = new Vector2 ( 0 , 0 ) ;
/// <summary>
/// The object under aimer. A static access field that lets you know what is under the aimer.
/// This field can return null.
/// </summary>
public static GameObject objectUnderAimer ;
2015-02-10 08:03:38 +08:00
protected AimerInputModule ( ) { }
2015-02-27 04:42:26 +08:00
public override void ActivateModule ( )
2015-02-10 08:03:38 +08:00
{
2015-02-27 04:42:26 +08:00
StandaloneInputModule StandAloneSystem = GetComponent < StandaloneInputModule > ( ) ;
if ( StandAloneSystem ! = null & & StandAloneSystem . enabled )
2015-02-10 08:03:38 +08:00
{
2015-02-27 04:42:26 +08:00
Debug . LogError ( "Aimer Input Module is incompatible with the StandAloneInputSystem, " +
"please remove it from the Event System in this scene or disable it when this module is in use" ) ;
2015-02-10 08:03:38 +08:00
}
}
2015-02-27 04:42:26 +08:00
public override void Process ( )
2015-02-10 08:03:38 +08:00
{
2020-10-09 00:07:39 +08:00
bool pressed = UIExtensionsInputManager . GetButtonDown ( activateAxis ) ;
bool released = UIExtensionsInputManager . GetButtonUp ( activateAxis ) ;
2015-02-27 04:42:26 +08:00
PointerEventData pointer = GetAimerPointerEventData ( ) ;
ProcessInteraction ( pointer , pressed , released ) ;
if ( ! released )
ProcessMove ( pointer ) ;
else
RemovePointerData ( pointer ) ;
2015-02-10 08:03:38 +08:00
}
2015-02-27 04:42:26 +08:00
protected virtual PointerEventData GetAimerPointerEventData ( )
2015-02-10 08:03:38 +08:00
{
2015-02-27 04:42:26 +08:00
PointerEventData pointerData ;
//Not certain on the use of this.
2020-07-09 03:38:28 +08:00
//I know that -1 is the mouse and anything positive would be a finger/touch, 0 being the first finger, 1 being the second and so one till the system limit is reached.
2015-02-27 04:42:26 +08:00
//So that is the reason I choose -2.
GetPointerData ( - 2 , out pointerData , true ) ;
pointerData . Reset ( ) ;
2015-02-10 08:03:38 +08:00
2015-02-27 04:42:26 +08:00
pointerData . position = new Vector2 ( Screen . width * 0.5f , Screen . height * 0.5f ) + aimerOffset ;
eventSystem . RaycastAll ( pointerData , m_RaycastResultCache ) ;
var raycast = FindFirstRaycast ( m_RaycastResultCache ) ;
pointerData . pointerCurrentRaycast = raycast ;
m_RaycastResultCache . Clear ( ) ;
return pointerData ;
}
2015-02-10 08:03:38 +08:00
2015-02-27 04:42:26 +08:00
private void ProcessInteraction ( PointerEventData pointer , bool pressed , bool released )
2015-02-10 08:03:38 +08:00
{
2015-02-27 04:42:26 +08:00
var currentOverGo = pointer . pointerCurrentRaycast . gameObject ;
2015-02-10 08:03:38 +08:00
2015-02-27 04:42:26 +08:00
objectUnderAimer = ExecuteEvents . GetEventHandler < ISubmitHandler > ( currentOverGo ) ; //we only want objects that we can submit on.
2015-02-10 08:03:38 +08:00
2015-02-27 04:42:26 +08:00
if ( pressed )
2015-02-10 08:03:38 +08:00
{
2015-02-27 04:42:26 +08:00
pointer . eligibleForClick = true ;
pointer . delta = Vector2 . zero ;
pointer . pressPosition = pointer . position ;
pointer . pointerPressRaycast = pointer . pointerCurrentRaycast ;
// search for the control that will receive the press
// if we can't find a press handler set the press
// handler to be what would receive a click.
var newPressed = ExecuteEvents . ExecuteHierarchy ( currentOverGo , pointer , ExecuteEvents . submitHandler ) ;
2020-07-09 03:38:28 +08:00
// didn't find a press handler... search for a click handler
2015-02-27 04:42:26 +08:00
if ( newPressed = = null )
2015-02-10 08:03:38 +08:00
{
2015-02-27 04:42:26 +08:00
newPressed = ExecuteEvents . ExecuteHierarchy ( currentOverGo , pointer , ExecuteEvents . pointerDownHandler ) ;
if ( newPressed = = null )
newPressed = ExecuteEvents . GetEventHandler < IPointerClickHandler > ( currentOverGo ) ;
}
else
{
pointer . eligibleForClick = false ;
2015-02-10 08:03:38 +08:00
}
2015-02-27 04:42:26 +08:00
if ( newPressed ! = pointer . pointerPress )
{
pointer . pointerPress = newPressed ;
pointer . rawPointerPress = currentOverGo ;
pointer . clickCount = 0 ;
}
2015-02-10 08:03:38 +08:00
2015-02-27 04:42:26 +08:00
// Save the drag handler as well
pointer . pointerDrag = ExecuteEvents . GetEventHandler < IDragHandler > ( currentOverGo ) ;
2015-02-10 08:03:38 +08:00
2015-02-27 04:42:26 +08:00
if ( pointer . pointerDrag ! = null )
ExecuteEvents . Execute < IBeginDragHandler > ( pointer . pointerDrag , pointer , ExecuteEvents . beginDragHandler ) ;
}
if ( released )
2015-02-10 08:03:38 +08:00
{
2015-02-27 04:42:26 +08:00
//Debug.Log("Executing pressup on: " + pointer.pointerPress);
ExecuteEvents . Execute ( pointer . pointerPress , pointer , ExecuteEvents . pointerUpHandler ) ;
//Debug.Log("KeyCode: " + pointer.eventData.keyCode);
// see if we mouse up on the same element that we clicked on...
var pointerUpHandler = ExecuteEvents . GetEventHandler < IPointerClickHandler > ( currentOverGo ) ;
// PointerClick
if ( pointer . pointerPress = = pointerUpHandler & & pointer . eligibleForClick )
{
float time = Time . unscaledTime ;
if ( time - pointer . clickTime < 0.3f )
+ + pointer . clickCount ;
else
pointer . clickCount = 1 ;
pointer . clickTime = time ;
ExecuteEvents . Execute ( pointer . pointerPress , pointer , ExecuteEvents . pointerClickHandler ) ;
}
else if ( pointer . pointerDrag ! = null )
{
ExecuteEvents . ExecuteHierarchy ( currentOverGo , pointer , ExecuteEvents . dropHandler ) ;
}
pointer . eligibleForClick = false ;
pointer . pointerPress = null ;
pointer . rawPointerPress = null ;
if ( pointer . pointerDrag ! = null )
ExecuteEvents . Execute ( pointer . pointerDrag , pointer , ExecuteEvents . endDragHandler ) ;
2015-02-10 08:03:38 +08:00
2015-02-27 04:42:26 +08:00
pointer . pointerDrag = null ;
2015-02-10 08:03:38 +08:00
}
2015-02-27 04:42:26 +08:00
}
2015-02-10 08:03:38 +08:00
2015-02-27 04:42:26 +08:00
public override void DeactivateModule ( )
{
base . DeactivateModule ( ) ;
ClearSelection ( ) ;
2015-02-10 08:03:38 +08:00
}
}
}