Added Feel plugin
This commit is contained in:
79
Assets/External/Feel/MMTools/Foundation/MMControls/MMControlsTestInputManager.cs
vendored
Normal file
79
Assets/External/Feel/MMTools/Foundation/MMControls/MMControlsTestInputManager.cs
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using MoreMountains.Tools;
|
||||
|
||||
#if MM_UI
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// This persistent singleton handles the inputs and sends commands to the player in the MMControls demo, its sole purpose is to output debug logs of the various interactions with the demo's inputs
|
||||
/// </summary>
|
||||
public class MMControlsTestInputManager : MonoBehaviour, MMEventListener<MMSwipeEvent>
|
||||
{
|
||||
// on start, we force a high target frame rate for a more fluid experience on mobile devices
|
||||
protected virtual void Start()
|
||||
{
|
||||
Application.targetFrameRate = 300;
|
||||
}
|
||||
|
||||
public virtual void LeftJoystickMovement(Vector2 movement) { MMDebug.DebugOnScreen("left joystick",movement); }
|
||||
public virtual void RightJoystickMovement(Vector2 movement) { MMDebug.DebugOnScreen("right joystick", movement); }
|
||||
public virtual void RepositionableJoystickMovement(Vector2 movement) { MMDebug.DebugOnScreen("Repositionable joystick", movement); }
|
||||
public virtual void FollowerJoystickMovement(Vector2 movement) { MMDebug.DebugOnScreen("Follower joystick", movement); }
|
||||
|
||||
public virtual void APressed() { MMDebug.DebugOnScreen("Button A Pressed"); }
|
||||
public virtual void BPressed() { MMDebug.DebugOnScreen("Button B Pressed"); }
|
||||
public virtual void XPressed() { MMDebug.DebugOnScreen("Button X Pressed"); }
|
||||
public virtual void YPressed() { MMDebug.DebugOnScreen("Button Y Pressed"); }
|
||||
public virtual void RTPressed() { MMDebug.DebugOnScreen("Button RT Pressed"); }
|
||||
|
||||
public virtual void APressedFirstTime() { Debug.LogFormat("Button A Pressed for the first time"); }
|
||||
public virtual void BPressedFirstTime() { Debug.LogFormat("Button B Pressed for the first time"); }
|
||||
public virtual void XPressedFirstTime() { Debug.LogFormat("Button X Pressed for the first time"); }
|
||||
public virtual void YPressedFirstTime() { Debug.LogFormat("Button Y Pressed for the first time"); }
|
||||
public virtual void RTPressedFirstTime() { Debug.LogFormat("Button RT Pressed for the first time"); }
|
||||
|
||||
public virtual void AReleased() { Debug.LogFormat("Button A Released"); }
|
||||
public virtual void BReleased() { Debug.LogFormat("Button B Released"); }
|
||||
public virtual void XReleased() { Debug.LogFormat("Button X Released"); }
|
||||
public virtual void YReleased() { Debug.LogFormat("Button Y Released"); }
|
||||
public virtual void RTReleased() { Debug.LogFormat("Button RT Released"); }
|
||||
|
||||
public virtual void HorizontalAxisPressed(float value) { MMDebug.DebugOnScreen("horizontal movement",value); }
|
||||
public virtual void VerticalAxisPressed(float value) { MMDebug.DebugOnScreen("vertical movement",value); }
|
||||
|
||||
public virtual void LeftPressedFirstTime() { Debug.LogFormat("Button Left Pressed for the first time"); }
|
||||
public virtual void UpPressedFirstTime() { Debug.LogFormat("Button Up Pressed for the first time"); }
|
||||
public virtual void DownPressedFirstTime() { Debug.LogFormat("Button Down Pressed for the first time"); }
|
||||
public virtual void RightPressedFirstTime() { Debug.LogFormat("Button Right Pressed for the first time"); }
|
||||
|
||||
public virtual void LeftReleased() { Debug.LogFormat("Button Left Released"); }
|
||||
public virtual void UpReleased() { Debug.LogFormat("Button Up Released"); }
|
||||
public virtual void DownReleased() { Debug.LogFormat("Button Down Released"); }
|
||||
public virtual void RightReleased() { Debug.LogFormat("Button Right Released"); }
|
||||
|
||||
public virtual void StickDragged() { Debug.LogFormat("On drag"); }
|
||||
public virtual void StickPointerUp() { Debug.LogFormat("On pointer up"); }
|
||||
public virtual void StickPointerDown() { Debug.LogFormat("On pointer down"); }
|
||||
|
||||
public virtual void OnMMEvent(MMSwipeEvent swipeEvent)
|
||||
{
|
||||
Debug.LogFormat("Swipe at a "+ swipeEvent.SwipeAngle+"° angle, and a length of "+ swipeEvent.SwipeLength+" length. Cardinal direction : "+ swipeEvent.SwipeDirection);
|
||||
Debug.LogFormat("Swipe origin : " + swipeEvent.SwipeOrigin+ ", swipe end : " + swipeEvent.SwipeDestination);
|
||||
Debug.LogFormat("Swipe duration : "+swipeEvent.SwipeDuration);
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
this.MMEventStartListening<MMSwipeEvent>();
|
||||
}
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
this.MMEventStopListening<MMSwipeEvent>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMControlsTestInputManager.cs.meta
vendored
Normal file
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMControlsTestInputManager.cs.meta
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9640016db57d1c646a90fa18111eebf0
|
||||
timeCreated: 1462436657
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Foundation/MMControls/MMControlsTestInputManager.cs
|
||||
uploadId: 830868
|
||||
225
Assets/External/Feel/MMTools/Foundation/MMControls/MMSwipeZone.cs
vendored
Normal file
225
Assets/External/Feel/MMTools/Foundation/MMControls/MMSwipeZone.cs
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
#if MM_UI
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible directions a swipe can have
|
||||
/// </summary>
|
||||
public enum MMPossibleSwipeDirections { Up, Down, Left, Right }
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class SwipeEvent : UnityEvent<MMSwipeEvent> {}
|
||||
|
||||
/// <summary>
|
||||
/// An event usually triggered when a swipe happens. It contains the swipe "base" direction, and detailed information if needed (angle, length, origin and destination
|
||||
/// </summary>
|
||||
public struct MMSwipeEvent
|
||||
{
|
||||
public MMPossibleSwipeDirections SwipeDirection;
|
||||
public float SwipeAngle;
|
||||
public float SwipeLength;
|
||||
public Vector2 SwipeOrigin;
|
||||
public Vector2 SwipeDestination;
|
||||
public float SwipeDuration;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MoreMountains.Tools.MMSwipeEvent"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="direction">Direction.</param>
|
||||
/// <param name="angle">Angle.</param>
|
||||
/// <param name="length">Length.</param>
|
||||
/// <param name="origin">Origin.</param>
|
||||
/// <param name="destination">Destination.</param>
|
||||
public MMSwipeEvent(MMPossibleSwipeDirections direction, float angle, float length, Vector2 origin, Vector2 destination, float swipeDuration)
|
||||
{
|
||||
SwipeDirection = direction;
|
||||
SwipeAngle = angle;
|
||||
SwipeLength = length;
|
||||
SwipeOrigin = origin;
|
||||
SwipeDestination = destination;
|
||||
SwipeDuration = swipeDuration;
|
||||
}
|
||||
|
||||
static MMSwipeEvent e;
|
||||
public static void Trigger(MMPossibleSwipeDirections direction, float angle, float length, Vector2 origin, Vector2 destination, float swipeDuration)
|
||||
{
|
||||
e.SwipeDirection = direction;
|
||||
e.SwipeAngle = angle;
|
||||
e.SwipeLength = length;
|
||||
e.SwipeOrigin = origin;
|
||||
e.SwipeDestination = destination;
|
||||
e.SwipeDuration = swipeDuration;
|
||||
MMEventManager.TriggerEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a swipe manager to your scene, and it'll trigger MMSwipeEvents everytime a swipe happens. From its inspector you can determine the minimal length of a swipe. Shorter swipes will be ignored
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[AddComponentMenu("More Mountains/Tools/Controls/MM Swipe Zone")]
|
||||
public class MMSwipeZone : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler, IPointerEnterHandler
|
||||
{
|
||||
/// the minimal length of a swipe
|
||||
[Tooltip("the minimal length of a swipe")]
|
||||
public float MinimalSwipeLength = 50f;
|
||||
/// the maximum press length of a swipe
|
||||
[Tooltip("the maximum press length of a swipe")]
|
||||
public float MaximumPressLength = 10f;
|
||||
|
||||
/// The method(s) to call when the zone is swiped
|
||||
[Tooltip("The method(s) to call when the zone is swiped")]
|
||||
public SwipeEvent ZoneSwiped;
|
||||
/// The method(s) to call while the zone is being pressed
|
||||
[Tooltip("The method(s) to call while the zone is being pressed")]
|
||||
public UnityEvent ZonePressed;
|
||||
|
||||
[Header("Mouse Mode")]
|
||||
[MMInformation("If you set this to true, you'll need to actually press the button for it to be triggered, otherwise a simple hover will trigger it (better for touch input).", MMInformationAttribute.InformationType.Info,false)]
|
||||
/// If you set this to true, you'll need to actually press the button for it to be triggered, otherwise a simple hover will trigger it (better for touch input).
|
||||
[Tooltip("If you set this to true, you'll need to actually press the button for it to be triggered, otherwise a simple hover will trigger it (better for touch input).")]
|
||||
public bool MouseMode = false;
|
||||
|
||||
protected Vector2 _firstTouchPosition;
|
||||
protected float _angle;
|
||||
protected float _length;
|
||||
protected Vector2 _destination;
|
||||
protected Vector2 _deltaSwipe;
|
||||
protected MMPossibleSwipeDirections _swipeDirection;
|
||||
protected float _lastPointerUpAt = 0f;
|
||||
protected float _swipeStartedAt = 0f;
|
||||
protected float _swipeEndedAt = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a swipe event with the correct properties
|
||||
/// </summary>
|
||||
protected virtual void Swipe()
|
||||
{
|
||||
float duration = _swipeEndedAt - _swipeStartedAt;
|
||||
MMSwipeEvent swipeEvent = new MMSwipeEvent (_swipeDirection, _angle, _length, _firstTouchPosition, _destination, duration);
|
||||
MMEventManager.TriggerEvent(swipeEvent);
|
||||
if (ZoneSwiped != null)
|
||||
{
|
||||
ZoneSwiped.Invoke (swipeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the press event
|
||||
/// </summary>
|
||||
protected virtual void Press()
|
||||
{
|
||||
if (ZonePressed != null)
|
||||
{
|
||||
ZonePressed.Invoke ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer down action
|
||||
/// </summary>
|
||||
public virtual void OnPointerDown(PointerEventData data)
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
|
||||
_firstTouchPosition = Mouse.current.position.ReadValue();
|
||||
#else
|
||||
_firstTouchPosition = Input.mousePosition;
|
||||
#endif
|
||||
_swipeStartedAt = Time.unscaledTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer up action
|
||||
/// </summary>
|
||||
public virtual void OnPointerUp(PointerEventData data)
|
||||
{
|
||||
if (Time.frameCount == _lastPointerUpAt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
|
||||
_destination = Mouse.current.position.ReadValue();
|
||||
#else
|
||||
_destination = Input.mousePosition;
|
||||
#endif
|
||||
_deltaSwipe = _destination - _firstTouchPosition;
|
||||
_length = _deltaSwipe.magnitude;
|
||||
|
||||
// if the swipe has been long enough
|
||||
if (_length > MinimalSwipeLength)
|
||||
{
|
||||
_angle = MMMaths.AngleBetween (_deltaSwipe, Vector2.right);
|
||||
_swipeDirection = AngleToSwipeDirection (_angle);
|
||||
_swipeEndedAt = Time.unscaledTime;
|
||||
Swipe ();
|
||||
}
|
||||
|
||||
// if it's just a press
|
||||
if (_deltaSwipe.magnitude < MaximumPressLength)
|
||||
{
|
||||
Press ();
|
||||
}
|
||||
|
||||
_lastPointerUpAt = Time.frameCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer enter action when touch enters zone
|
||||
/// </summary>
|
||||
public virtual void OnPointerEnter(PointerEventData data)
|
||||
{
|
||||
if (!MouseMode)
|
||||
{
|
||||
OnPointerDown (data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer exit action when touch is out of zone
|
||||
/// </summary>
|
||||
public virtual void OnPointerExit(PointerEventData data)
|
||||
{
|
||||
if (!MouseMode)
|
||||
{
|
||||
OnPointerUp(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines a MMPossibleSwipeDirection out of an angle in degrees.
|
||||
/// </summary>
|
||||
/// <returns>The to swipe direction.</returns>
|
||||
/// <param name="angle">Angle in degrees.</param>
|
||||
protected virtual MMPossibleSwipeDirections AngleToSwipeDirection(float angle)
|
||||
{
|
||||
if ((angle < 45) || (angle >= 315))
|
||||
{
|
||||
return MMPossibleSwipeDirections.Right;
|
||||
}
|
||||
if ((angle >= 45) && (angle < 135))
|
||||
{
|
||||
return MMPossibleSwipeDirections.Up;
|
||||
}
|
||||
if ((angle >= 135) && (angle < 225))
|
||||
{
|
||||
return MMPossibleSwipeDirections.Left;
|
||||
}
|
||||
if ((angle >= 225) && (angle < 315))
|
||||
{
|
||||
return MMPossibleSwipeDirections.Down;
|
||||
}
|
||||
return MMPossibleSwipeDirections.Right;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMSwipeZone.cs.meta
vendored
Normal file
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMSwipeZone.cs.meta
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a68e615c17d2bf49a1a082e34fd9b6e
|
||||
timeCreated: 1494336562
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Foundation/MMControls/MMSwipeZone.cs
|
||||
uploadId: 830868
|
||||
181
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchAxis.cs
vendored
Normal file
181
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchAxis.cs
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
#if MM_UI
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
[System.Serializable]
|
||||
public class AxisEvent : UnityEvent<float> {}
|
||||
|
||||
/// <summary>
|
||||
/// Add this component to a GUI Image to have it act as an axis.
|
||||
/// Bind pressed down, pressed continually and released actions to it from the inspector
|
||||
/// Handles mouse and multi touch
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rect))]
|
||||
[RequireComponent(typeof(CanvasGroup))]
|
||||
[AddComponentMenu("More Mountains/Tools/Controls/MM Touch Axis")]
|
||||
public class MMTouchAxis : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler, IPointerEnterHandler
|
||||
{
|
||||
public enum ButtonStates { Off, ButtonDown, ButtonPressed, ButtonUp }
|
||||
[Header("Binding")]
|
||||
/// The method(s) to call when the axis gets pressed down
|
||||
[Tooltip("The method(s) to call when the axis gets pressed down")]
|
||||
public UnityEvent AxisPressedFirstTime;
|
||||
/// The method(s) to call when the axis gets released
|
||||
[Tooltip("The method(s) to call when the axis gets released")]
|
||||
public UnityEvent AxisReleased;
|
||||
/// The method(s) to call while the axis is being pressed
|
||||
[Tooltip("The method(s) to call while the axis is being pressed")]
|
||||
public AxisEvent AxisPressed;
|
||||
|
||||
[Header("Pressed Behaviour")]
|
||||
[MMInformation("Here you can set the opacity of the button when it's pressed. Useful for visual feedback.",MMInformationAttribute.InformationType.Info,false)]
|
||||
/// the new opacity to apply to the canvas group when the axis is pressed
|
||||
[Tooltip("the new opacity to apply to the canvas group when the axis is pressed")]
|
||||
public float PressedOpacity = 0.5f;
|
||||
/// the value to send the bound method when the axis is pressed
|
||||
[Tooltip("the value to send the bound method when the axis is pressed")]
|
||||
public float AxisValue;
|
||||
|
||||
[Header("Mouse Mode")]
|
||||
[MMInformation("If you set this to true, you'll need to actually press the axis for it to be triggered, otherwise a simple hover will trigger it (better for touch input).", MMInformationAttribute.InformationType.Info,false)]
|
||||
/// If you set this to true, you'll need to actually press the axis for it to be triggered, otherwise a simple hover will trigger it (better for touch input).
|
||||
[Tooltip("If you set this to true, you'll need to actually press the axis for it to be triggered, otherwise a simple hover will trigger it (better for touch input).")]
|
||||
public bool MouseMode = false;
|
||||
|
||||
public virtual ButtonStates CurrentState { get; protected set; }
|
||||
|
||||
protected CanvasGroup _canvasGroup;
|
||||
protected float _initialOpacity;
|
||||
|
||||
/// <summary>
|
||||
/// On Start, we get our canvasgroup and set our initial alpha
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_canvasGroup = GetComponent<CanvasGroup>();
|
||||
if (_canvasGroup!=null)
|
||||
{
|
||||
_initialOpacity = _canvasGroup.alpha;
|
||||
}
|
||||
ResetButton();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Every frame, if the touch zone is pressed, we trigger the bound method if it exists
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (AxisPressed != null)
|
||||
{
|
||||
if (CurrentState == ButtonStates.ButtonPressed)
|
||||
{
|
||||
AxisPressed.Invoke(AxisValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// At the end of every frame, we change our button's state if needed
|
||||
/// </summary>
|
||||
protected virtual void LateUpdate()
|
||||
{
|
||||
if (CurrentState == ButtonStates.ButtonUp)
|
||||
{
|
||||
CurrentState = ButtonStates.Off;
|
||||
}
|
||||
if (CurrentState == ButtonStates.ButtonDown)
|
||||
{
|
||||
CurrentState = ButtonStates.ButtonPressed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer down action
|
||||
/// </summary>
|
||||
public virtual void OnPointerDown(PointerEventData data)
|
||||
{
|
||||
if (CurrentState != ButtonStates.Off)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentState = ButtonStates.ButtonDown;
|
||||
if (_canvasGroup!=null)
|
||||
{
|
||||
_canvasGroup.alpha=PressedOpacity;
|
||||
}
|
||||
if (AxisPressedFirstTime!=null)
|
||||
{
|
||||
AxisPressedFirstTime.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer up action
|
||||
/// </summary>
|
||||
public virtual void OnPointerUp(PointerEventData data)
|
||||
{
|
||||
if (CurrentState != ButtonStates.ButtonPressed && CurrentState != ButtonStates.ButtonDown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentState = ButtonStates.ButtonUp;
|
||||
if (_canvasGroup!=null)
|
||||
{
|
||||
_canvasGroup.alpha=_initialOpacity;
|
||||
}
|
||||
if (AxisReleased != null)
|
||||
{
|
||||
AxisReleased.Invoke();
|
||||
}
|
||||
AxisPressed.Invoke(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnEnable, we reset our button state
|
||||
/// </summary>
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
ResetButton();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the button's state and opacity
|
||||
/// </summary>
|
||||
protected virtual void ResetButton()
|
||||
{
|
||||
CurrentState = ButtonStates.Off;
|
||||
_canvasGroup.alpha = _initialOpacity;
|
||||
CurrentState = ButtonStates.Off;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer enter action when touch enters zone
|
||||
/// </summary>
|
||||
public virtual void OnPointerEnter(PointerEventData data)
|
||||
{
|
||||
if (!MouseMode)
|
||||
{
|
||||
OnPointerDown (data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer exit action when touch is out of zone
|
||||
/// </summary>
|
||||
public virtual void OnPointerExit(PointerEventData data)
|
||||
{
|
||||
if (!MouseMode)
|
||||
{
|
||||
OnPointerUp(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchAxis.cs.meta
vendored
Normal file
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchAxis.cs.meta
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc509a62d8e6cfc45a8431d8d586b9f6
|
||||
timeCreated: 1462615497
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Foundation/MMControls/MMTouchAxis.cs
|
||||
uploadId: 830868
|
||||
553
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchButton.cs
vendored
Normal file
553
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchButton.cs
vendored
Normal file
@@ -0,0 +1,553 @@
|
||||
#if MM_UI
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Add this component to a GUI Image to have it act as a button.
|
||||
/// Bind pressed down, pressed continually and released actions to it from the inspector
|
||||
/// Handles mouse and multi touch
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rect))]
|
||||
[RequireComponent(typeof(CanvasGroup))]
|
||||
[AddComponentMenu("More Mountains/Tools/Controls/MM Touch Button")]
|
||||
public class MMTouchButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler, IPointerEnterHandler, ISubmitHandler
|
||||
{
|
||||
[Header("Interaction")]
|
||||
/// whether or not this button can be interacted with
|
||||
public bool Interactable = true;
|
||||
|
||||
/// The different possible states for the button :
|
||||
/// Off (default idle state), ButtonDown (button pressed for the first time), ButtonPressed (button being pressed), ButtonUp (button being released), Disabled (unclickable but still present on screen)
|
||||
/// ButtonDown and ButtonUp will only last one frame, the others will last however long you press them / disable them / do nothing
|
||||
public enum ButtonStates { Off, ButtonDown, ButtonPressed, ButtonUp, Disabled }
|
||||
[Header("Binding")]
|
||||
/// The method(s) to call when the button gets pressed down
|
||||
[Tooltip("The method(s) to call when the button gets pressed down")]
|
||||
public UnityEvent ButtonPressedFirstTime;
|
||||
/// The method(s) to call when the button gets released
|
||||
[Tooltip("The method(s) to call when the button gets released")]
|
||||
public UnityEvent ButtonReleased;
|
||||
/// The method(s) to call while the button is being pressed
|
||||
[Tooltip("The method(s) to call while the button is being pressed")]
|
||||
public UnityEvent ButtonPressed;
|
||||
|
||||
[Header("Sprite Swap")]
|
||||
[MMInformation("Here you can define, for disabled and pressed states, if you want a different sprite, and a different color.", MMInformationAttribute.InformationType.Info,false)]
|
||||
/// the sprite to use on the button when it's in the disabled state
|
||||
[Tooltip("the sprite to use on the button when it's in the disabled state")]
|
||||
public Sprite DisabledSprite;
|
||||
/// whether or not to change color when the button is disabled
|
||||
[Tooltip("whether or not to change color when the button is disabled")]
|
||||
public bool DisabledChangeColor = false;
|
||||
/// the color to use when the button is disabled
|
||||
[Tooltip("the color to use when the button is disabled")]
|
||||
[MMCondition("DisabledChangeColor", true)]
|
||||
public Color DisabledColor = Color.white;
|
||||
/// the sprite to use on the button when it's in the pressed state
|
||||
[Tooltip("the sprite to use on the button when it's in the pressed state")]
|
||||
public Sprite PressedSprite;
|
||||
/// whether or not to change the button color on press
|
||||
[Tooltip("whether or not to change the button color on press")]
|
||||
public bool PressedChangeColor = false;
|
||||
/// the color to use when the button is pressed
|
||||
[Tooltip("the color to use when the button is pressed")]
|
||||
[MMCondition("PressedChangeColor", true)]
|
||||
public Color PressedColor= Color.white;
|
||||
/// the sprite to use on the button when it's in the highlighted state
|
||||
[Tooltip("the sprite to use on the button when it's in the highlighted state")]
|
||||
public Sprite HighlightedSprite;
|
||||
/// whether or not to change color when highlighting the button
|
||||
[Tooltip("whether or not to change color when highlighting the button")]
|
||||
public bool HighlightedChangeColor = false;
|
||||
/// the color to use when the button is highlighted
|
||||
[Tooltip("the color to use when the button is highlighted")]
|
||||
[MMCondition("HighlightedChangeColor", true)]
|
||||
public Color HighlightedColor = Color.white;
|
||||
|
||||
[Header("Opacity")]
|
||||
[MMInformation("Here you can set different opacities for the button when it's pressed, idle, or disabled. Useful for visual feedback.",MMInformationAttribute.InformationType.Info,false)]
|
||||
/// the new opacity to apply to the canvas group when the button is pressed
|
||||
[Tooltip("the opacity to apply to the canvas group when the button is pressed")]
|
||||
public float PressedOpacity = 1f;
|
||||
/// the new opacity to apply to the canvas group when the button is idle
|
||||
[Tooltip("the new opacity to apply to the canvas group when the button is idle")]
|
||||
public float IdleOpacity = 1f;
|
||||
/// the new opacity to apply to the canvas group when the button is disabled
|
||||
[Tooltip("the new opacity to apply to the canvas group when the button is disabled")]
|
||||
public float DisabledOpacity = 1f;
|
||||
|
||||
[Header("Delays")]
|
||||
[MMInformation("Specify here the delays to apply when the button is pressed initially, and when it gets released. Usually you'll keep them at 0.",MMInformationAttribute.InformationType.Info,false)]
|
||||
/// the delay to apply to events when the button gets pressed for the first time
|
||||
[Tooltip("the delay to apply to events when the button gets pressed for the first time")]
|
||||
public float PressedFirstTimeDelay = 0f;
|
||||
/// the delay to apply to events when the button gets released
|
||||
[Tooltip("the delay to apply to events when the button gets released")]
|
||||
public float ReleasedDelay = 0f;
|
||||
|
||||
[Header("Buffer")]
|
||||
/// the duration (in seconds) after a press during which the button can't be pressed again
|
||||
[Tooltip("the duration (in seconds) after a press during which the button can't be pressed again")]
|
||||
public float BufferDuration = 0f;
|
||||
|
||||
[Header("Animation")]
|
||||
[MMInformation("Here you can bind an animator, and specify animation parameter names for the various states.",MMInformationAttribute.InformationType.Info,false)]
|
||||
/// an animator you can bind to this button to have its states updated to reflect the button's states
|
||||
[Tooltip("an animator you can bind to this button to have its states updated to reflect the button's states")]
|
||||
public Animator Animator;
|
||||
/// the name of the animation parameter to turn true when the button is idle
|
||||
[Tooltip("the name of the animation parameter to turn true when the button is idle")]
|
||||
public string IdleAnimationParameterName = "Idle";
|
||||
/// the name of the animation parameter to turn true when the button is disabled
|
||||
[Tooltip("the name of the animation parameter to turn true when the button is disabled")]
|
||||
public string DisabledAnimationParameterName = "Disabled";
|
||||
/// the name of the animation parameter to turn true when the button is pressed
|
||||
[Tooltip("the name of the animation parameter to turn true when the button is pressed")]
|
||||
public string PressedAnimationParameterName = "Pressed";
|
||||
|
||||
[Header("Mouse Mode")]
|
||||
[MMInformation("If you set this to true, you'll need to actually press the button for it to be triggered, otherwise a simple hover will trigger it (better to leave it unchecked if you're going for touch input).", MMInformationAttribute.InformationType.Info,false)]
|
||||
/// If you set this to true, you'll need to actually press the button for it to be triggered, otherwise a simple hover will trigger it (better for touch input).
|
||||
[Tooltip("If you set this to true, you'll need to actually press the button for it to be triggered, otherwise a simple hover will trigger it (better for touch input).")]
|
||||
public bool MouseMode = false;
|
||||
|
||||
public bool PreventLeftClick = false;
|
||||
public bool PreventMiddleClick = true;
|
||||
public bool PreventRightClick = true;
|
||||
|
||||
public virtual bool ReturnToInitialSpriteAutomatically { get; set; }
|
||||
|
||||
/// the current state of the button (off, down, pressed or up)
|
||||
public virtual ButtonStates CurrentState { get; protected set; }
|
||||
|
||||
public event System.Action<PointerEventData.FramePressState, PointerEventData> ButtonStateChange;
|
||||
|
||||
protected bool _zonePressed = false;
|
||||
protected CanvasGroup _canvasGroup;
|
||||
protected float _initialOpacity;
|
||||
protected Animator _animator;
|
||||
protected Image _image;
|
||||
protected Sprite _initialSprite;
|
||||
protected Color _initialColor;
|
||||
protected float _lastClickTimestamp = 0f;
|
||||
protected Selectable _selectable;
|
||||
|
||||
/// <summary>
|
||||
/// On Start, we get our canvasgroup and set our initial alpha
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Initialization ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On init we grab our Image, Animator and CanvasGroup and set them up
|
||||
/// </summary>
|
||||
protected virtual void Initialization()
|
||||
{
|
||||
ReturnToInitialSpriteAutomatically = true;
|
||||
|
||||
_selectable = GetComponent<Selectable> ();
|
||||
|
||||
_image = GetComponent<Image> ();
|
||||
if (_image != null)
|
||||
{
|
||||
_initialColor = _image.color;
|
||||
_initialSprite = _image.sprite;
|
||||
}
|
||||
|
||||
_animator = GetComponent<Animator> ();
|
||||
if (Animator != null)
|
||||
{
|
||||
_animator = Animator;
|
||||
}
|
||||
|
||||
_canvasGroup = GetComponent<CanvasGroup>();
|
||||
if (_canvasGroup!=null)
|
||||
{
|
||||
_initialOpacity = IdleOpacity;
|
||||
_canvasGroup.alpha = _initialOpacity;
|
||||
_initialOpacity = _canvasGroup.alpha;
|
||||
}
|
||||
ResetButton();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Every frame, if the touch zone is pressed, we trigger the OnPointerPressed method, to detect continuous press
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
switch (CurrentState)
|
||||
{
|
||||
case ButtonStates.Off:
|
||||
SetOpacity (IdleOpacity);
|
||||
if ((_image != null) && (ReturnToInitialSpriteAutomatically))
|
||||
{
|
||||
_image.color = _initialColor;
|
||||
_image.sprite = _initialSprite;
|
||||
}
|
||||
if (_selectable != null)
|
||||
{
|
||||
_selectable.interactable = true;
|
||||
if (EventSystem.current.currentSelectedGameObject == this.gameObject)
|
||||
{
|
||||
if ((_image != null) && HighlightedChangeColor)
|
||||
{
|
||||
_image.color = HighlightedColor;
|
||||
}
|
||||
if (HighlightedSprite != null)
|
||||
{
|
||||
_image.sprite = HighlightedSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonStates.Disabled:
|
||||
SetOpacity (DisabledOpacity);
|
||||
if (_image != null)
|
||||
{
|
||||
if (DisabledSprite != null)
|
||||
{
|
||||
_image.sprite = DisabledSprite;
|
||||
}
|
||||
if (DisabledChangeColor)
|
||||
{
|
||||
_image.color = DisabledColor;
|
||||
}
|
||||
}
|
||||
if (_selectable != null)
|
||||
{
|
||||
_selectable.interactable = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonStates.ButtonDown:
|
||||
|
||||
break;
|
||||
|
||||
case ButtonStates.ButtonPressed:
|
||||
SetOpacity (PressedOpacity);
|
||||
OnPointerPressed();
|
||||
if (_image != null)
|
||||
{
|
||||
if (PressedSprite != null)
|
||||
{
|
||||
_image.sprite = PressedSprite;
|
||||
}
|
||||
if (PressedChangeColor)
|
||||
{
|
||||
_image.color = PressedColor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonStates.ButtonUp:
|
||||
|
||||
break;
|
||||
}
|
||||
UpdateAnimatorStates ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// At the end of every frame, we change our button's state if needed
|
||||
/// </summary>
|
||||
protected virtual void LateUpdate()
|
||||
{
|
||||
if (CurrentState == ButtonStates.ButtonUp)
|
||||
{
|
||||
CurrentState = ButtonStates.Off;
|
||||
}
|
||||
if (CurrentState == ButtonStates.ButtonDown)
|
||||
{
|
||||
CurrentState = ButtonStates.ButtonPressed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the ButtonStateChange event for the specified state
|
||||
/// </summary>
|
||||
/// <param name="newState"></param>
|
||||
/// <param name="data"></param>
|
||||
public virtual void InvokeButtonStateChange(PointerEventData.FramePressState newState, PointerEventData data)
|
||||
{
|
||||
ButtonStateChange?.Invoke(newState, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not the specified click is allowed, if in mouse mode
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual bool AllowedClick(PointerEventData data)
|
||||
{
|
||||
if (!MouseMode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (PreventLeftClick && data.button == PointerEventData.InputButton.Left)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (PreventMiddleClick && data.button == PointerEventData.InputButton.Middle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (PreventRightClick && data.button == PointerEventData.InputButton.Right)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer down action
|
||||
/// </summary>
|
||||
public virtual void OnPointerDown(PointerEventData data)
|
||||
{
|
||||
if (!Interactable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AllowedClick(data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Time.unscaledTime - _lastClickTimestamp < BufferDuration)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentState != ButtonStates.Off)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CurrentState = ButtonStates.ButtonDown;
|
||||
_lastClickTimestamp = Time.unscaledTime;
|
||||
InvokeButtonStateChange(PointerEventData.FramePressState.Pressed, data);
|
||||
if ((Time.timeScale != 0) && (PressedFirstTimeDelay > 0))
|
||||
{
|
||||
Invoke ("InvokePressedFirstTime", PressedFirstTimeDelay);
|
||||
}
|
||||
else
|
||||
{
|
||||
ButtonPressedFirstTime.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the ButtonPressedFirstTime event
|
||||
/// </summary>
|
||||
protected virtual void InvokePressedFirstTime()
|
||||
{
|
||||
if (ButtonPressedFirstTime!=null)
|
||||
{
|
||||
ButtonPressedFirstTime.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer up action
|
||||
/// </summary>
|
||||
public virtual void OnPointerUp(PointerEventData data)
|
||||
{
|
||||
if (!Interactable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!AllowedClick(data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (CurrentState != ButtonStates.ButtonPressed && CurrentState != ButtonStates.ButtonDown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentState = ButtonStates.ButtonUp;
|
||||
InvokeButtonStateChange(PointerEventData.FramePressState.Released, data);
|
||||
if ((Time.timeScale != 0) && (ReleasedDelay > 0))
|
||||
{
|
||||
Invoke ("InvokeReleased", ReleasedDelay);
|
||||
}
|
||||
else
|
||||
{
|
||||
ButtonReleased.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the ButtonReleased event
|
||||
/// </summary>
|
||||
protected virtual void InvokeReleased()
|
||||
{
|
||||
if (ButtonReleased != null)
|
||||
{
|
||||
ButtonReleased.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer pressed action
|
||||
/// </summary>
|
||||
public virtual void OnPointerPressed()
|
||||
{
|
||||
if (!Interactable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CurrentState = ButtonStates.ButtonPressed;
|
||||
if (ButtonPressed != null)
|
||||
{
|
||||
ButtonPressed.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the button's state and opacity
|
||||
/// </summary>
|
||||
protected virtual void ResetButton()
|
||||
{
|
||||
SetOpacity(_initialOpacity);
|
||||
CurrentState = ButtonStates.Off;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer enter action when touch enters zone
|
||||
/// </summary>
|
||||
public virtual void OnPointerEnter(PointerEventData data)
|
||||
{
|
||||
if (!Interactable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!AllowedClick(data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!MouseMode)
|
||||
{
|
||||
OnPointerDown (data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer exit action when touch is out of zone
|
||||
/// </summary>
|
||||
public virtual void OnPointerExit(PointerEventData data)
|
||||
{
|
||||
if (!Interactable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!AllowedClick(data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!MouseMode)
|
||||
{
|
||||
OnPointerUp(data);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// OnEnable, we reset our button state
|
||||
/// </summary>
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
ResetButton();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On disable we reset our flags and disable the button
|
||||
/// </summary>
|
||||
private void OnDisable()
|
||||
{
|
||||
bool wasActive = CurrentState != ButtonStates.Off && CurrentState != ButtonStates.Disabled && CurrentState != ButtonStates.ButtonUp;
|
||||
DisableButton();
|
||||
CurrentState = ButtonStates.Off;
|
||||
if (wasActive)
|
||||
{
|
||||
InvokeButtonStateChange(PointerEventData.FramePressState.Released, null);
|
||||
ButtonReleased?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the button from receiving touches
|
||||
/// </summary>
|
||||
public virtual void DisableButton()
|
||||
{
|
||||
CurrentState = ButtonStates.Disabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the button to receive touches
|
||||
/// </summary>
|
||||
public virtual void EnableButton()
|
||||
{
|
||||
if (CurrentState == ButtonStates.Disabled)
|
||||
{
|
||||
CurrentState = ButtonStates.Off;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the canvas group's opacity to the requested value
|
||||
/// </summary>
|
||||
/// <param name="newOpacity"></param>
|
||||
protected virtual void SetOpacity(float newOpacity)
|
||||
{
|
||||
if (_canvasGroup!=null)
|
||||
{
|
||||
_canvasGroup.alpha = newOpacity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates animator states based on the current state of the button
|
||||
/// </summary>
|
||||
protected virtual void UpdateAnimatorStates ()
|
||||
{
|
||||
if (_animator == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (DisabledAnimationParameterName != null)
|
||||
{
|
||||
_animator.SetBool (DisabledAnimationParameterName, (CurrentState == ButtonStates.Disabled));
|
||||
}
|
||||
if (PressedAnimationParameterName != null)
|
||||
{
|
||||
_animator.SetBool (PressedAnimationParameterName, (CurrentState == ButtonStates.ButtonPressed));
|
||||
}
|
||||
if (IdleAnimationParameterName != null)
|
||||
{
|
||||
_animator.SetBool (IdleAnimationParameterName, (CurrentState == ButtonStates.Off));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On submit, raises the appropriate events
|
||||
/// </summary>
|
||||
/// <param name="eventData"></param>
|
||||
public virtual void OnSubmit(BaseEventData eventData)
|
||||
{
|
||||
if (ButtonPressedFirstTime!=null)
|
||||
{
|
||||
ButtonPressedFirstTime.Invoke();
|
||||
}
|
||||
if (ButtonReleased!=null)
|
||||
{
|
||||
ButtonReleased.Invoke ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchButton.cs.meta
vendored
Normal file
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchButton.cs.meta
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87a286771fa86194e979f187a1691a2a
|
||||
timeCreated: 1462399350
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Foundation/MMControls/MMTouchButton.cs
|
||||
uploadId: 830868
|
||||
75
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchControls.cs
vendored
Normal file
75
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchControls.cs
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
[RequireComponent(typeof(CanvasGroup))]
|
||||
[AddComponentMenu("More Mountains/Tools/Controls/MM Touch Controls")]
|
||||
public class MMTouchControls : MonoBehaviour
|
||||
{
|
||||
public enum InputForcedMode { None, Mobile, Desktop }
|
||||
[MMInformation("If you check Auto Mobile Detection, the engine will automatically switch to mobile controls when your build target is Android or iOS. You can also force mobile or desktop (keyboard, gamepad) controls using the dropdown below.\nNote that if you don't need mobile controls and/or GUI this component can also work on its own, just put it on an empty GameObject instead.", MMInformationAttribute.InformationType.Info,false)]
|
||||
/// If you check Auto Mobile Detection, the engine will automatically switch to mobile controls when your build target is Android or iOS.
|
||||
/// You can also force mobile or desktop (keyboard, gamepad) controls using the dropdown below.Note that if you don't need mobile controls
|
||||
/// and/or GUI this component can also work on its own, just put it on an empty GameObject instead.
|
||||
[Tooltip("If you check Auto Mobile Detection, the engine will automatically switch to mobile controls when your build target is Android or iOS." +
|
||||
"You can also force mobile or desktop (keyboard, gamepad) controls using the dropdown below.Note that if you don't need mobile controls " +
|
||||
"and/or GUI this component can also work on its own, just put it on an empty GameObject instead.")]
|
||||
public bool AutoMobileDetection = true;
|
||||
/// Force desktop mode (gamepad, keyboard...) or mobile (touch controls)
|
||||
[Tooltip("Force desktop mode (gamepad, keyboard...) or mobile (touch controls)")]
|
||||
public InputForcedMode ForcedMode;
|
||||
public virtual bool IsMobile { get; protected set; }
|
||||
|
||||
protected CanvasGroup _canvasGroup;
|
||||
protected float _initialMobileControlsAlpha;
|
||||
|
||||
/// <summary>
|
||||
/// We get the player from its tag.
|
||||
/// </summary>
|
||||
protected virtual void Start()
|
||||
{
|
||||
_canvasGroup = GetComponent<CanvasGroup>();
|
||||
|
||||
_initialMobileControlsAlpha = _canvasGroup.alpha;
|
||||
SetMobileControlsActive(false);
|
||||
IsMobile=false;
|
||||
if (AutoMobileDetection)
|
||||
{
|
||||
#if UNITY_ANDROID || UNITY_IPHONE
|
||||
SetMobileControlsActive(true);
|
||||
IsMobile = true;
|
||||
#endif
|
||||
}
|
||||
if (ForcedMode==InputForcedMode.Mobile)
|
||||
{
|
||||
SetMobileControlsActive(true);
|
||||
IsMobile = true;
|
||||
}
|
||||
if (ForcedMode==InputForcedMode.Desktop)
|
||||
{
|
||||
SetMobileControlsActive(false);
|
||||
IsMobile = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this method to enable or disable mobile controls
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public virtual void SetMobileControlsActive(bool state)
|
||||
{
|
||||
if (_canvasGroup!=null)
|
||||
{
|
||||
_canvasGroup.gameObject.SetActive(state);
|
||||
if (state)
|
||||
{
|
||||
_canvasGroup.alpha=_initialMobileControlsAlpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
_canvasGroup.alpha=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchControls.cs.meta
vendored
Normal file
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchControls.cs.meta
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fec2335f22dc84b549dd9dfdeebca3e0
|
||||
timeCreated: 1467025573
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Foundation/MMControls/MMTouchControls.cs
|
||||
uploadId: 830868
|
||||
359
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchFollowerJoystick.cs
vendored
Normal file
359
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchFollowerJoystick.cs
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
#if MM_UI
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Add this component to a UI rectangle and it'll act as a detection zone for a follower joystick.
|
||||
/// Note that this component extends the MMTouchJoystick class so you don't need to add another joystick to it. It's both the detection zone and the stick itself.
|
||||
/// </summary>
|
||||
[AddComponentMenu("More Mountains/Tools/Controls/MM Touch Follower Joystick")]
|
||||
public class MMTouchFollowerJoystick : MMTouchJoystick
|
||||
{
|
||||
[MMInspectorGroup("Follower Joystick", true, 23)]
|
||||
/// the canvas group to use as the joystick's knob - the part that moves under your thumb
|
||||
[Tooltip("the canvas group to use as the joystick's knob - the part that moves under your thumb")]
|
||||
public CanvasGroup KnobCanvasGroup;
|
||||
/// the canvas group to use as the joystick's background
|
||||
[Tooltip("the canvas group to use as the joystick's background")]
|
||||
public CanvasGroup BackgroundCanvasGroup;
|
||||
/// if this is true, the joystick will return back to its initial position when released
|
||||
[Tooltip("if this is true, the joystick will return back to its initial position when released")]
|
||||
public bool ResetPositionToInitialOnRelease = false;
|
||||
/// if this is true, the background will follow its target with interpolation, otherwise it'll be instant movement
|
||||
[Tooltip("if this is true, the background will follow its target with interpolation, otherwise it'll be instant movement")]
|
||||
public bool InterpolateFollowMovement = false;
|
||||
/// if in interpolate mode, this defines the speed at which the backgrounds follows the knob
|
||||
[Tooltip("if in interpolate mode, this defines the speed at which the backgrounds follows the knob")]
|
||||
[MMCondition("InterpolateFollowMovement", true)]
|
||||
public float InterpolateFollowMovementSpeed = 0.3f;
|
||||
/// whether or not to add a spring to the interpolation of the background movement
|
||||
[Tooltip("whether or not to add a spring to the interpolation of the background movement")]
|
||||
[MMCondition("InterpolateFollowMovement", true)]
|
||||
public bool SpringFollowInterpolation = false;
|
||||
/// when in SpringFollowInterpolation mode, the amount of damping to apply to the spring
|
||||
[Tooltip("when in SpringFollowInterpolation mode, the amount of damping to apply to the spring")]
|
||||
[MMCondition("SpringFollowInterpolation", true)]
|
||||
public float SpringDamping = 0.6f;
|
||||
/// when in SpringFollowInterpolation mode, the frequency to apply to the spring
|
||||
[Tooltip("when in SpringFollowInterpolation mode, the frequency to apply to the spring")]
|
||||
[MMCondition("SpringFollowInterpolation", true)]
|
||||
public float SpringFrequency = 4f;
|
||||
|
||||
[MMInspectorGroup("Background Constraints", true, 24)]
|
||||
/// if this is true, the joystick won't be able to travel beyond the bounds of the top level canvas
|
||||
[Tooltip("if this is true, the joystick won't be able to travel beyond the bounds of the top level canvas")]
|
||||
public bool ShouldConstrainBackground = true;
|
||||
/// the rect to consider as a background constraint zone, if left empty, will be auto created
|
||||
[Tooltip("the rect to consider as a background constraint zone, if left empty, will be auto created")]
|
||||
public RectTransform BackgroundConstraintRectTransform;
|
||||
/// the left padding to apply to the background constraint
|
||||
[Tooltip("the left padding to apply to the background constraint")]
|
||||
public float BackgroundConstraintPaddingLeft;
|
||||
/// the right padding to apply to the background constraint
|
||||
[Tooltip("the right padding to apply to the background constraint")]
|
||||
public float BackgroundConstraintPaddingRight;
|
||||
/// the top padding to apply to the background constraint
|
||||
[Tooltip("the top padding to apply to the background constraint")]
|
||||
public float BackgroundConstraintPaddingTop;
|
||||
/// the bottom padding to apply to the background constraint
|
||||
[Tooltip("the bottom padding to apply to the background constraint")]
|
||||
public float BackgroundConstraintPaddingBottom;
|
||||
|
||||
protected Vector3 _initialPosition;
|
||||
protected Vector3 _newPosition;
|
||||
protected RectTransform _rectTransform;
|
||||
protected RectTransform _backgroundRectTransform;
|
||||
protected Vector3[] _innerRectCorners = new Vector3[4];
|
||||
protected Vector3 _newBackgroundPosition;
|
||||
protected Vector3 _backgroundPositionTarget;
|
||||
protected Vector3 _innerRectTransformBottomLeft;
|
||||
protected Vector3 _innerRectTransformTopLeft;
|
||||
protected Vector3 _innerRectTransformTopRight;
|
||||
protected Vector3 _innerRectTransformBottomRight;
|
||||
protected Vector3 _springVelocity;
|
||||
protected Plane _canvasPlane;
|
||||
protected bool _canvasPlaneInitialized = false;
|
||||
|
||||
/// <summary>
|
||||
/// On Start, we instantiate our joystick's image if there's one
|
||||
/// </summary>
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
// we store the detection zone's initial position
|
||||
_rectTransform = GetComponent<RectTransform>();
|
||||
_backgroundRectTransform = BackgroundCanvasGroup.GetComponent<RectTransform>();
|
||||
_initialPosition = _backgroundRectTransform.position;
|
||||
_backgroundPositionTarget = _initialPosition;
|
||||
|
||||
CreateInnerRect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On initialize, we set our knob transform
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SetKnobTransform(KnobCanvasGroup.transform);
|
||||
_canvasGroup = KnobCanvasGroup;
|
||||
_initialOpacity = _canvasGroup.alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On update, we handle movement interpolation
|
||||
/// </summary>
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
HandleMovementInterpolation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the movement of the background relative to the knob
|
||||
/// </summary>
|
||||
protected virtual void HandleMovementInterpolation()
|
||||
{
|
||||
if (!InterpolateFollowMovement)
|
||||
{
|
||||
BackgroundCanvasGroup.transform.position = _backgroundPositionTarget;
|
||||
return;
|
||||
}
|
||||
|
||||
if (SpringFollowInterpolation)
|
||||
{
|
||||
_newBackgroundPosition = BackgroundCanvasGroup.transform.position;
|
||||
MMMaths.Spring(ref _newBackgroundPosition, _backgroundPositionTarget, ref _springVelocity, SpringDamping, SpringFrequency, Time.unscaledDeltaTime);
|
||||
BackgroundCanvasGroup.transform.position = _newBackgroundPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
BackgroundCanvasGroup.transform.position = MMMaths.Lerp(BackgroundCanvasGroup.transform.position, _backgroundPositionTarget, InterpolateFollowMovementSpeed, Time.unscaledDeltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a constraining inner rect
|
||||
/// </summary>
|
||||
protected virtual void CreateInnerRect()
|
||||
{
|
||||
if (!ShouldConstrainBackground)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// we create an inner rect if one wasn't provided
|
||||
if (BackgroundConstraintRectTransform == null)
|
||||
{
|
||||
GameObject innerRect = new GameObject();
|
||||
innerRect.transform.SetParent(this.transform);
|
||||
innerRect.name = "BackgroundConstraintRectTransform";
|
||||
BackgroundConstraintRectTransform = innerRect.AddComponent<RectTransform>();
|
||||
BackgroundConstraintRectTransform.anchorMin = _rectTransform.anchorMin;
|
||||
BackgroundConstraintRectTransform.anchorMax = _rectTransform.anchorMax;
|
||||
BackgroundConstraintRectTransform.position = _rectTransform.position;
|
||||
BackgroundConstraintRectTransform.localScale = _rectTransform.localScale;
|
||||
BackgroundConstraintRectTransform.sizeDelta = new Vector2(_rectTransform.sizeDelta.x - _backgroundRectTransform.sizeDelta.y, _rectTransform.sizeDelta.y - _backgroundRectTransform.sizeDelta.y);
|
||||
}
|
||||
|
||||
// we apply the padding
|
||||
BackgroundConstraintRectTransform.offsetMin += new Vector2(BackgroundConstraintPaddingLeft, BackgroundConstraintPaddingBottom);
|
||||
BackgroundConstraintRectTransform.offsetMax -= new Vector2(BackgroundConstraintPaddingRight, BackgroundConstraintPaddingTop);
|
||||
|
||||
// we store our corners
|
||||
BackgroundConstraintRectTransform.GetWorldCorners(_innerRectCorners);
|
||||
_innerRectTransformBottomLeft = _innerRectCorners[0];
|
||||
_innerRectTransformTopLeft = _innerRectCorners[1];
|
||||
_innerRectTransformTopRight = _innerRectCorners[2];
|
||||
_innerRectTransformBottomRight = _innerRectCorners[3];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the zone is pressed, we move our joystick accordingly
|
||||
/// </summary>
|
||||
/// <param name="data">Data.</param>
|
||||
public override void OnPointerDown(PointerEventData data)
|
||||
{
|
||||
base.OnPointerDown(data);
|
||||
|
||||
if (ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera && TargetCamera != null)
|
||||
{
|
||||
_canvasPlane = new Plane(-TargetCamera.transform.forward, this.transform.position);
|
||||
_canvasPlaneInitialized = true;
|
||||
}
|
||||
|
||||
Vector3 pointerWorldPos = ConvertToWorld(data.position);
|
||||
|
||||
if (_canvasPlaneInitialized)
|
||||
{
|
||||
Ray ray = TargetCamera.ScreenPointToRay(data.position);
|
||||
float enter;
|
||||
if (_canvasPlane.Raycast(ray, out enter))
|
||||
{
|
||||
pointerWorldPos = ray.GetPoint(enter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerWorldPos.z = this.transform.position.z;
|
||||
}
|
||||
|
||||
_newPosition = pointerWorldPos;
|
||||
|
||||
_backgroundPositionTarget = _newPosition;
|
||||
ConstrainBackground();
|
||||
SetNeutralPosition(BackgroundCanvasGroup.transform.position);
|
||||
_knobTransform.position = _newPosition;
|
||||
|
||||
_initialZPosition = _newPosition.z;
|
||||
|
||||
ComputeJoystickValue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On drag, we adjust our target and constrain our background
|
||||
/// </summary>
|
||||
/// <param name="eventData"></param>
|
||||
public override void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
OnDragEvent.Invoke();
|
||||
|
||||
Vector3 pointerWorldPos = ConvertToWorld(eventData.position);
|
||||
|
||||
if (ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera && TargetCamera != null)
|
||||
{
|
||||
Plane canvasPlane = new Plane(-TargetCamera.transform.forward, BackgroundCanvasGroup.transform.position);
|
||||
Ray ray = TargetCamera.ScreenPointToRay(eventData.position);
|
||||
float enter;
|
||||
if (canvasPlane.Raycast(ray, out enter))
|
||||
{
|
||||
pointerWorldPos = ray.GetPoint(enter);
|
||||
}
|
||||
}
|
||||
|
||||
_knobTransform.position = pointerWorldPos;
|
||||
|
||||
float distance = Vector3.Distance(_knobTransform.position, BackgroundCanvasGroup.transform.position);
|
||||
|
||||
if (distance >= ComputedMaxRange)
|
||||
{
|
||||
Vector3 direction = (_knobTransform.position - BackgroundCanvasGroup.transform.position).normalized;
|
||||
_backgroundPositionTarget = BackgroundCanvasGroup.transform.position + direction * (distance - ComputedMaxRange);
|
||||
}
|
||||
|
||||
ConstrainBackground();
|
||||
ComputeJoystickValue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the value of the joystick by computing the
|
||||
/// </summary>
|
||||
protected virtual void ComputeJoystickValue()
|
||||
{
|
||||
Vector3 worldDelta = _knobTransform.position - BackgroundCanvasGroup.transform.position;
|
||||
|
||||
Vector3 localDelta = TransformToLocalSpace(worldDelta);
|
||||
float distance = worldDelta.magnitude;
|
||||
|
||||
if (distance <= ComputedMaxRange)
|
||||
{
|
||||
RawValue.x = EvaluateInputValue(localDelta.x);
|
||||
RawValue.y = EvaluateInputValue(localDelta.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
RawValue.x = Mathf.InverseLerp(0, distance, Mathf.Abs(localDelta.x)) * Mathf.Sign(localDelta.x);
|
||||
RawValue.y = Mathf.InverseLerp(0, distance, Mathf.Abs(localDelta.y)) * Mathf.Sign(localDelta.y);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps the background inside the inner rect
|
||||
/// </summary>
|
||||
protected virtual void ConstrainBackground()
|
||||
{
|
||||
if (!ShouldConstrainBackground)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_newBackgroundPosition = _backgroundPositionTarget;
|
||||
_newBackgroundPosition.x = Mathf.Clamp(_newBackgroundPosition.x , _innerRectTransformTopLeft.x, _innerRectTransformTopRight.x);
|
||||
_newBackgroundPosition.y = Mathf.Clamp(_newBackgroundPosition.y , _innerRectTransformBottomLeft.y, _innerRectTransformTopLeft.y);
|
||||
_backgroundPositionTarget = _newBackgroundPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On pointer up we reset our joystick
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public override void OnPointerUp(PointerEventData data)
|
||||
{
|
||||
base.OnPointerUp(data);
|
||||
|
||||
ResetJoystick();
|
||||
_knobTransform.position = _backgroundPositionTarget;
|
||||
|
||||
if (ResetPositionToInitialOnRelease)
|
||||
{
|
||||
_backgroundPositionTarget = _initialPosition;
|
||||
_knobTransform.position = _initialPosition;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We don't clamp the stick anymore
|
||||
/// </summary>
|
||||
protected override void ClampToBounds()
|
||||
{
|
||||
_newTargetPosition = _newTargetPosition - _neutralPosition;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Draws gizmos to show the constraining box' corners
|
||||
/// </summary>
|
||||
protected override void OnDrawGizmos()
|
||||
{
|
||||
if (!DrawGizmos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Draws max range
|
||||
Handles.color = MMColors.Orange;
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
if (KnobCanvasGroup != null)
|
||||
{
|
||||
Handles.DrawWireDisc(KnobCanvasGroup.transform.position, this.transform.forward, ComputedMaxRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handles.DrawWireDisc(this.transform.position, this.transform.forward, ComputedMaxRange);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Handles.DrawWireDisc(_backgroundRectTransform.position, this.transform.forward, ComputedMaxRange);
|
||||
}
|
||||
|
||||
// Draws corners
|
||||
if (BackgroundConstraintRectTransform != null)
|
||||
{
|
||||
float gizmoSize = 0.3f;
|
||||
MMDebug.DrawGizmoPoint(_innerRectTransformBottomLeft, Color.cyan, gizmoSize);
|
||||
MMDebug.DrawGizmoPoint(_innerRectTransformTopLeft, Color.cyan, gizmoSize);
|
||||
MMDebug.DrawGizmoPoint(_innerRectTransformTopRight, Color.cyan, gizmoSize);
|
||||
MMDebug.DrawGizmoPoint(_innerRectTransformBottomRight, Color.cyan, gizmoSize);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
18
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchFollowerJoystick.cs.meta
vendored
Normal file
18
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchFollowerJoystick.cs.meta
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12f6f90faaf30834980e50fda0c74a9c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Foundation/MMControls/MMTouchFollowerJoystick.cs
|
||||
uploadId: 830868
|
||||
436
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchJoystick.cs
vendored
Normal file
436
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchJoystick.cs
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
#if MM_UI
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.Events;
|
||||
using System;
|
||||
using Unity.Collections;
|
||||
using UnityEngine.UI;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
[System.Serializable]
|
||||
public class JoystickEvent : UnityEvent<Vector2> {}
|
||||
[System.Serializable]
|
||||
public class JoystickFloatEvent : UnityEvent<float> {}
|
||||
|
||||
/// <summary>
|
||||
/// Joystick input class.
|
||||
/// In charge of the behaviour of the joystick mobile touch input.
|
||||
/// Bind its actions from the inspector
|
||||
/// Handles mouse and multi touch
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rect))]
|
||||
[RequireComponent(typeof(CanvasGroup))]
|
||||
[AddComponentMenu("More Mountains/Tools/Controls/MM Touch Joystick")]
|
||||
public class MMTouchJoystick : MMMonoBehaviour, IDragHandler, IEndDragHandler, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
public enum MaxRangeModes { Distance, DistanceToTransform }
|
||||
|
||||
[MMInspectorGroup("Camera", true, 16)]
|
||||
/// The camera to use as the reference for any ScreenToWorldPoint computations
|
||||
[Tooltip("The camera to use as the reference for any ScreenToWorldPoint computations")]
|
||||
public Camera TargetCamera;
|
||||
|
||||
[MMInspectorGroup("Joystick Behaviour", true, 18)]
|
||||
[Tooltip("Determines whether the horizontal axis of this stick should be enabled. If not, the stick will only move vertically.")]
|
||||
/// Is horizontal axis allowed
|
||||
public bool HorizontalAxisEnabled = true;
|
||||
/// Is vertical axis allowed
|
||||
[Tooltip("Determines whether the vertical axis of this stick should be enabled. If not, the stick will only move horizontally.")]
|
||||
public bool VerticalAxisEnabled = true;
|
||||
/// the mode in which to compute the range. Distance will be a flat value, DistanceToTransform will be a distance to a transform you can move around and potentially resize as you wish for various resolutions
|
||||
[Tooltip("the mode in which to compute the range. Distance will be a flat value, DistanceToTransform will be a distance to a transform you can move around and potentially resize as you wish for various resolutions")]
|
||||
public MaxRangeModes MaxRangeMode = MaxRangeModes.Distance;
|
||||
/// The MaxRange is the maximum distance from its initial center position you can drag the joystick to
|
||||
[Tooltip("The MaxRange is the maximum distance from its initial center position you can drag the joystick to.")]
|
||||
[MMEnumCondition("MaxRangeMode", (int)MaxRangeModes.Distance)]
|
||||
public float MaxRange = 1.5f;
|
||||
/// in DistanceToTransform mode, the object whose distance to the center will be used to compute the max range. Note that this is computed once, at init. Call RefreshMaxRangeDistance() to recompute it.
|
||||
[Tooltip("in DistanceToTransform mode, the object whose distance to the center will be used to compute the max range. Note that this is computed once, at init. Call RefreshMaxRangeDistance() to recompute it.")]
|
||||
[MMEnumCondition("MaxRangeMode", (int)MaxRangeModes.DistanceToTransform)]
|
||||
public Transform MaxRangeTransform;
|
||||
|
||||
public float ComputedMaxRange
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
return MaxRangeMode == MaxRangeModes.Distance ? MaxRange : _maxRangeTransformDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MaxRangeMode == MaxRangeModes.Distance)
|
||||
{
|
||||
return MaxRange;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MaxRangeTransform == null)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
RefreshMaxRangeDistance();
|
||||
return _maxRangeTransformDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MMInspectorGroup("Value Events", true, 19)]
|
||||
/// An event to use the raw value of the joystick
|
||||
[Tooltip("An event to use the raw value of the joystick")]
|
||||
public JoystickEvent JoystickValue;
|
||||
/// An event to use the normalized value of the joystick
|
||||
[Tooltip("An event to use the normalized value of the joystick")]
|
||||
public JoystickEvent JoystickNormalizedValue;
|
||||
// An event to use the joystick's amplitude (the magnitude of its Vector2 output)
|
||||
[Tooltip("An event to use the joystick's amplitude (the magnitude of its Vector2 output)")]
|
||||
public JoystickFloatEvent JoystickMagnitudeValue;
|
||||
|
||||
[MMInspectorGroup("Touch Events", true, 8)]
|
||||
/// An event triggered when tapping the joystick for the first time
|
||||
[Tooltip("An event triggered when tapping the joystick for the first time")]
|
||||
public UnityEvent OnPointerDownEvent;
|
||||
/// An event triggered when dragging the stick
|
||||
[Tooltip("An event triggered when dragging the stick")]
|
||||
public UnityEvent OnDragEvent;
|
||||
/// An event triggered when releasing the stick
|
||||
[Tooltip("An event triggered when releasing the stick")]
|
||||
public UnityEvent OnPointerUpEvent;
|
||||
|
||||
[MMInspectorGroup("Rotating Direction Indicator", true, 20)]
|
||||
/// an object you can rotate to show the direction of the joystick. Will only be visible if the movement is above a threshold
|
||||
[Tooltip("an object you can rotate to show the direction of the joystick. Will only be visible if the movement is above a threshold")]
|
||||
public Transform RotatingIndicator;
|
||||
/// the threshold above which the rotating indicator will appear
|
||||
[Tooltip("the threshold above which the rotating indicator will appear")]
|
||||
public float RotatingIndicatorThreshold = 0.1f;
|
||||
|
||||
[MMInspectorGroup("Knob Opacity", true, 17)]
|
||||
/// the new opacity to apply to the canvas group when the button is pressed
|
||||
[Tooltip("the new opacity to apply to the canvas group when the button is pressed")]
|
||||
public float PressedOpacity = 0.5f;
|
||||
/// whether or not to interpolate opacity changes on the knob's canvas group
|
||||
[Tooltip("whether or not to interpolate opacity changes on the knob's canvas group")]
|
||||
public bool InterpolateOpacity = true;
|
||||
/// the speed at which to interpolate opacity
|
||||
[Tooltip("the speed at which to interpolate opacity")]
|
||||
[MMCondition("InterpolateOpacity", true)]
|
||||
public float InterpolateOpacitySpeed = 1f;
|
||||
|
||||
[MMInspectorGroup("Debug Output", true, 5)]
|
||||
/// the raw value of the joystick, from 0 to 1 on each axis
|
||||
[Tooltip("the raw value of the joystick, from 0 to 1 on each axis")]
|
||||
[MMReadOnly]
|
||||
public Vector2 RawValue;
|
||||
/// the normalized value of the joystick
|
||||
[Tooltip("the normalized value of the joystick")]
|
||||
[MMReadOnly]
|
||||
public Vector2 NormalizedValue;
|
||||
/// the magnitude of the stick's vector
|
||||
[Tooltip("the magnitude of the stick's vector")]
|
||||
[MMReadOnly]
|
||||
public float Magnitude;
|
||||
/// whether or not to draw gizmos associated to this stick
|
||||
[Tooltip("whether or not to draw gizmos associated to this stick")]
|
||||
public bool DrawGizmos = true;
|
||||
|
||||
/// the render mode of the parent canvas this stick is on
|
||||
public virtual RenderMode ParentCanvasRenderMode { get; protected set; }
|
||||
|
||||
protected Vector3 _neutralPosition;
|
||||
protected Vector3 _newTargetPosition;
|
||||
protected Vector3 _newJoystickPosition;
|
||||
protected float _initialZPosition;
|
||||
protected float _targetOpacity;
|
||||
protected CanvasGroup _canvasGroup;
|
||||
protected float _initialOpacity;
|
||||
protected Transform _knobTransform;
|
||||
protected bool _rotatingIndicatorIsNotNull = false;
|
||||
protected float _maxRangeTransformDistance;
|
||||
protected Canvas _parentCanvas;
|
||||
|
||||
/// <summary>
|
||||
/// On Start we initialize our stick
|
||||
/// </summary>
|
||||
protected virtual void Start()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the various parts of the stick
|
||||
/// </summary>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual void Initialize()
|
||||
{
|
||||
if ((ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera) && (TargetCamera == null))
|
||||
{
|
||||
throw new Exception("MMTouchJoystick : you have to set a target camera");
|
||||
}
|
||||
|
||||
_canvasGroup = GetComponent<CanvasGroup>();
|
||||
_parentCanvas = GetComponentInParent<Canvas>();
|
||||
_rotatingIndicatorIsNotNull = (RotatingIndicator != null);
|
||||
RefreshMaxRangeDistance();
|
||||
|
||||
SetKnobTransform(this.transform);
|
||||
|
||||
SetNeutralPosition();
|
||||
|
||||
ParentCanvasRenderMode = GetComponentInParent<Canvas>().renderMode;
|
||||
_initialZPosition = _knobTransform.position.z;
|
||||
_initialOpacity = _canvasGroup.alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is used to compute the max range distance when in DistanceToTransform mode
|
||||
/// </summary>
|
||||
public virtual void RefreshMaxRangeDistance()
|
||||
{
|
||||
if (MaxRangeMode == MaxRangeModes.DistanceToTransform)
|
||||
{
|
||||
_maxRangeTransformDistance = Vector2.Distance(this.transform.position, MaxRangeTransform.position);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a new transform as the joystick knob
|
||||
/// </summary>
|
||||
/// <param name="newTransform"></param>
|
||||
public virtual void SetKnobTransform(Transform newTransform)
|
||||
{
|
||||
_knobTransform = newTransform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Update we check for an orientation change if needed, and send our input values.
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
NormalizedValue = RawValue.normalized;
|
||||
Magnitude = RawValue.magnitude;
|
||||
|
||||
if (HorizontalAxisEnabled || VerticalAxisEnabled)
|
||||
{
|
||||
JoystickValue.Invoke(RawValue);
|
||||
JoystickNormalizedValue.Invoke(NormalizedValue);
|
||||
JoystickMagnitudeValue.Invoke(Magnitude);
|
||||
}
|
||||
|
||||
RotateIndicator();
|
||||
HandleOpacity();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes or interpolates the opacity of the knob
|
||||
/// </summary>
|
||||
protected virtual void HandleOpacity()
|
||||
{
|
||||
if (InterpolateOpacity)
|
||||
{
|
||||
_canvasGroup.alpha = MMMaths.Lerp(_canvasGroup.alpha, _targetOpacity, InterpolateOpacitySpeed, Time.unscaledDeltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_canvasGroup.alpha = _targetOpacity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rotates an indicator to match the rotation of the stick
|
||||
/// </summary>
|
||||
protected virtual void RotateIndicator()
|
||||
{
|
||||
if (!_rotatingIndicatorIsNotNull)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RotatingIndicator.gameObject.SetActive(RawValue.magnitude > RotatingIndicatorThreshold);
|
||||
float angle = Mathf.Atan2(RawValue.y, RawValue.x) * Mathf.Rad2Deg;
|
||||
RotatingIndicator.localRotation = Quaternion.AngleAxis(angle, Vector3.forward);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the neutral position of the joystick
|
||||
/// </summary>
|
||||
public virtual void SetNeutralPosition()
|
||||
{
|
||||
_neutralPosition = _knobTransform.position;
|
||||
}
|
||||
|
||||
public virtual void SetNeutralPosition(Vector3 newPosition)
|
||||
{
|
||||
_neutralPosition = newPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles dragging of the joystick
|
||||
/// </summary>
|
||||
public virtual void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
OnDragEvent.Invoke();
|
||||
|
||||
_newTargetPosition = ConvertToWorld(eventData.position);
|
||||
|
||||
Vector3 localDelta = TransformToLocalSpace(_newTargetPosition - _neutralPosition);
|
||||
localDelta = Vector2.ClampMagnitude(localDelta, ComputedMaxRange);
|
||||
|
||||
if (!HorizontalAxisEnabled)
|
||||
{
|
||||
localDelta.x = 0;
|
||||
}
|
||||
if (!VerticalAxisEnabled)
|
||||
{
|
||||
localDelta.y = 0;
|
||||
}
|
||||
|
||||
RawValue.x = EvaluateInputValue(localDelta.x);
|
||||
RawValue.y = EvaluateInputValue(localDelta.y);
|
||||
|
||||
_newTargetPosition = _neutralPosition + TransformToWorldSpace(localDelta);
|
||||
_newJoystickPosition = _newTargetPosition;
|
||||
_newJoystickPosition.z = _initialZPosition;
|
||||
|
||||
_knobTransform.position = _newJoystickPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a world space vector to the canvas/camera local space
|
||||
/// </summary>
|
||||
protected virtual Vector3 TransformToLocalSpace(Vector3 worldVector)
|
||||
{
|
||||
if (ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera && TargetCamera != null)
|
||||
{
|
||||
return Quaternion.Inverse(TargetCamera.transform.rotation) * worldVector;
|
||||
}
|
||||
return worldVector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a local space vector back to world space
|
||||
/// </summary>
|
||||
protected virtual Vector3 TransformToWorldSpace(Vector3 localVector)
|
||||
{
|
||||
if (ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera && TargetCamera != null)
|
||||
{
|
||||
return TargetCamera.transform.rotation * localVector;
|
||||
}
|
||||
return localVector;
|
||||
}
|
||||
|
||||
protected virtual Vector3 ConvertToWorld(Vector3 position)
|
||||
{
|
||||
if (ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera)
|
||||
{
|
||||
float distance = _parentCanvas != null ? _parentCanvas.planeDistance : 0f;
|
||||
position.z = distance;
|
||||
return TargetCamera.ScreenToWorldPoint(position);
|
||||
}
|
||||
else
|
||||
{
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps the position of the new target
|
||||
/// </summary>
|
||||
protected virtual void ClampToBounds()
|
||||
{
|
||||
_newTargetPosition = Vector2.ClampMagnitude(_newTargetPosition - _neutralPosition, ComputedMaxRange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the stick's position and values
|
||||
/// </summary>
|
||||
public virtual void ResetJoystick()
|
||||
{
|
||||
// we reset the stick's position
|
||||
_newJoystickPosition = _neutralPosition;
|
||||
_newJoystickPosition.z = _initialZPosition;
|
||||
_knobTransform.position = _newJoystickPosition;
|
||||
|
||||
RawValue.x = 0f;
|
||||
RawValue.y = 0f;
|
||||
|
||||
// we set its opacity back
|
||||
_targetOpacity = _initialOpacity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We compute the axis value from the interval between neutral position, current stick position (vectorPosition) and max range
|
||||
/// </summary>
|
||||
/// <returns>The axis value, a float between -1 and 1</returns>
|
||||
/// <param name="vectorPosition">stick position.</param>
|
||||
protected virtual float EvaluateInputValue(float vectorPosition)
|
||||
{
|
||||
return Mathf.InverseLerp(0, ComputedMaxRange, Mathf.Abs(vectorPosition)) * Mathf.Sign(vectorPosition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// What happens when the stick stops being dragged
|
||||
/// </summary>
|
||||
public virtual void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// What happens when the stick is released (even if no drag happened)
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public virtual void OnPointerUp(PointerEventData data)
|
||||
{
|
||||
ResetJoystick();
|
||||
OnPointerUpEvent.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// What happens when the stick is pressed for the first time
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public virtual void OnPointerDown(PointerEventData data)
|
||||
{
|
||||
_targetOpacity = PressedOpacity;
|
||||
OnPointerDownEvent.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On enable, we initialize our stick
|
||||
/// </summary>
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
Initialize();
|
||||
_targetOpacity = _initialOpacity;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Draws gizmos if needed
|
||||
/// </summary>
|
||||
protected virtual void OnDrawGizmos()
|
||||
{
|
||||
if (!DrawGizmos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Handles.color = MMColors.Orange;
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Handles.DrawWireDisc(this.transform.position, this.transform.forward, ComputedMaxRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handles.DrawWireDisc(_neutralPosition, this.transform.forward, ComputedMaxRange);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchJoystick.cs.meta
vendored
Normal file
19
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchJoystick.cs.meta
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f6a0577d46b80a4f929e57370c60650
|
||||
timeCreated: 1462403537
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Foundation/MMControls/MMTouchJoystick.cs
|
||||
uploadId: 830868
|
||||
179
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchRepositionableJoystick.cs
vendored
Normal file
179
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchRepositionableJoystick.cs
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
#if MM_UI
|
||||
using UnityEngine.EventSystems;
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Add this component to a UI rectangle and it'll act as a detection zone for a joystick.
|
||||
/// Note that this component extends the MMTouchJoystick class so you don't need to add another joystick to it. It's both the detection zone and the stick itself.
|
||||
/// </summary>
|
||||
[AddComponentMenu("More Mountains/Tools/Controls/MM Touch Repositionable Joystick")]
|
||||
public class MMTouchRepositionableJoystick : MMTouchJoystick, IPointerDownHandler
|
||||
{
|
||||
[MMInspectorGroup("Repositionable Joystick", true, 22)]
|
||||
/// the canvas group to use as the joystick's knob
|
||||
[Tooltip("the canvas group to use as the joystick's knob")]
|
||||
public CanvasGroup KnobCanvasGroup;
|
||||
/// the canvas group to use as the joystick's background
|
||||
[Tooltip("the canvas group to use as the joystick's background")]
|
||||
public CanvasGroup BackgroundCanvasGroup;
|
||||
/// if this is true, the joystick won't be able to travel beyond the bounds of the top level canvas
|
||||
[Tooltip("if this is true, the joystick won't be able to travel beyond the bounds of the top level canvas")]
|
||||
public bool ConstrainToInitialRectangle = true;
|
||||
/// if this is true, the joystick will return back to its initial position when released
|
||||
[Tooltip("if this is true, the joystick will return back to its initial position when released")]
|
||||
public bool ResetPositionToInitialOnRelease = false;
|
||||
|
||||
protected Vector3 _initialPosition;
|
||||
protected Vector3 _newPosition;
|
||||
protected CanvasGroup _knobCanvasGroup;
|
||||
protected RectTransform _rectTransform;
|
||||
|
||||
/// <summary>
|
||||
/// On Start, we instantiate our joystick's image if there's one
|
||||
/// </summary>
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
_rectTransform = GetComponent<RectTransform>();
|
||||
_initialPosition = BackgroundCanvasGroup.GetComponent<RectTransform>().position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On init we set our knob transform
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SetKnobTransform(KnobCanvasGroup.transform);
|
||||
_canvasGroup = KnobCanvasGroup;
|
||||
_initialOpacity = _canvasGroup.alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the zone is pressed, we move our joystick accordingly
|
||||
/// </summary>
|
||||
/// <param name="data">Data.</param>
|
||||
public override void OnPointerDown(PointerEventData data)
|
||||
{
|
||||
_targetOpacity = PressedOpacity;
|
||||
OnPointerDownEvent.Invoke();
|
||||
|
||||
_newPosition = ConvertToWorld(data.position);
|
||||
|
||||
if (!WithinBounds())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BackgroundCanvasGroup.transform.position = _newPosition;
|
||||
SetNeutralPosition(_newPosition);
|
||||
_knobTransform.position = _newPosition;
|
||||
|
||||
_initialZPosition = _newPosition.z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override OnDrag to handle repositionable joystick with rotated camera
|
||||
/// </summary>
|
||||
public override void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
OnDragEvent.Invoke();
|
||||
|
||||
_newTargetPosition = ConvertToWorld(eventData.position);
|
||||
|
||||
Vector3 localDelta = TransformToLocalSpace(_newTargetPosition - _neutralPosition);
|
||||
|
||||
localDelta = Vector2.ClampMagnitude(localDelta, ComputedMaxRange);
|
||||
|
||||
if (!HorizontalAxisEnabled)
|
||||
{
|
||||
localDelta.x = 0;
|
||||
}
|
||||
if (!VerticalAxisEnabled)
|
||||
{
|
||||
localDelta.y = 0;
|
||||
}
|
||||
|
||||
RawValue.x = EvaluateInputValue(localDelta.x);
|
||||
RawValue.y = EvaluateInputValue(localDelta.y);
|
||||
|
||||
_newTargetPosition = _neutralPosition + TransformToWorldSpace(localDelta);
|
||||
_newJoystickPosition = _newTargetPosition;
|
||||
_newJoystickPosition.z = _initialZPosition;
|
||||
|
||||
_knobTransform.position = _newJoystickPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the joystick's new position is within the bounds of the top level canvas
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual bool WithinBounds()
|
||||
{
|
||||
if (!ConstrainToInitialRectangle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector2 screenPoint = _newPosition;
|
||||
if (ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera && TargetCamera != null)
|
||||
{
|
||||
screenPoint = TargetCamera.WorldToScreenPoint(_newPosition);
|
||||
}
|
||||
|
||||
return RectTransformUtility.RectangleContainsScreenPoint(_rectTransform, screenPoint, TargetCamera);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the player lets go of the stick, we restore our stick's position if needed
|
||||
/// </summary>
|
||||
/// <param name="eventData">Event data.</param>
|
||||
public override void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
base.OnPointerUp(eventData);
|
||||
|
||||
if (ResetPositionToInitialOnRelease)
|
||||
{
|
||||
BackgroundCanvasGroup.transform.position = _initialPosition;
|
||||
_knobTransform.position = _initialPosition;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Draws gizmos if needed
|
||||
/// </summary>
|
||||
protected override void OnDrawGizmos()
|
||||
{
|
||||
if (!DrawGizmos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Handles.color = MMColors.Orange;
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
if (KnobCanvasGroup != null)
|
||||
{
|
||||
Handles.DrawWireDisc(KnobCanvasGroup.transform.position, this.transform.forward, ComputedMaxRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handles.DrawWireDisc(this.transform.position, this.transform.forward, ComputedMaxRange);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Handles.DrawWireDisc(_neutralPosition, this.transform.forward, ComputedMaxRange);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
18
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchRepositionableJoystick.cs.meta
vendored
Normal file
18
Assets/External/Feel/MMTools/Foundation/MMControls/MMTouchRepositionableJoystick.cs.meta
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a60ed48e41f7574f890b8669d6fbfe0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 183370
|
||||
packageName: Feel
|
||||
packageVersion: 5.9.1
|
||||
assetPath: Assets/Feel/MMTools/Foundation/MMControls/MMTouchRepositionableJoystick.cs
|
||||
uploadId: 830868
|
||||
Reference in New Issue
Block a user