chore: initial commit
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public class WobbleButton : MonoBehaviour, IPointerExitHandler, IPointerEnterHandler
|
||||
{
|
||||
public RenderMode ParentCanvasRenderMode { get; protected set; }
|
||||
|
||||
[Header("Bindings")]
|
||||
public Camera TargetCamera;
|
||||
public AudioSource SpringAudioSource;
|
||||
public Animator TargetAnimator;
|
||||
|
||||
[Header("Haptics")]
|
||||
public HapticSource SpringHapticSource;
|
||||
|
||||
[Header("Colors")]
|
||||
public Image TargetModel;
|
||||
|
||||
[Header("Wobble")]
|
||||
public float OffDuration = 0.1f;
|
||||
public float MaxRange;
|
||||
public AnimationCurve WobbleCurve;
|
||||
public float DragResetDuration = 4f;
|
||||
public float WobbleFactor = 2f;
|
||||
|
||||
protected Vector3 _neutralPosition;
|
||||
protected Canvas _canvas;
|
||||
protected Vector3 _newTargetPosition;
|
||||
protected Vector3 _eventPosition;
|
||||
protected Vector2 _workPosition;
|
||||
protected float _initialZPosition;
|
||||
protected bool _dragging;
|
||||
protected int _pointerID;
|
||||
protected PointerEventData _pointerEventData;
|
||||
protected RectTransform _rectTransform;
|
||||
|
||||
protected Vector3 _dragEndedPosition;
|
||||
protected float _dragEndedAt;
|
||||
protected Vector3 _dragResetDirection;
|
||||
protected bool _pointerOn = false;
|
||||
protected bool _draggedOnce = false;
|
||||
protected int _sparkAnimationParameter;
|
||||
|
||||
protected long[] _wobbleAndroidPattern = { 0, 40, 40, 80 };
|
||||
protected int[] _wobbleAndroidAmplitude = { 0, 40, 0, 80 };
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void SetPitch(float newPitch)
|
||||
{
|
||||
SpringAudioSource.pitch = newPitch;
|
||||
SpringHapticSource.frequencyShift = NiceVibrationsDemoHelpers.Remap(newPitch, 0.3f, 1f, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
public virtual void Initialization()
|
||||
{
|
||||
_sparkAnimationParameter = Animator.StringToHash("Spark");
|
||||
ParentCanvasRenderMode = GetComponentInParent<Canvas>().renderMode;
|
||||
_canvas = GetComponentInParent<Canvas>();
|
||||
_initialZPosition = transform.position.z;
|
||||
_rectTransform = this.gameObject.GetComponent<RectTransform>();
|
||||
SetNeutralPosition();
|
||||
}
|
||||
|
||||
public virtual void SetNeutralPosition()
|
||||
{
|
||||
_neutralPosition = _rectTransform.transform.position;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetWorldPosition(Vector3 testPosition)
|
||||
{
|
||||
if (ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera)
|
||||
{
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvas.transform as RectTransform, testPosition, _canvas.worldCamera, out _workPosition);
|
||||
return _canvas.transform.TransformPoint(_workPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
return testPosition;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (_pointerOn && !_dragging)
|
||||
{
|
||||
_newTargetPosition = GetWorldPosition(_pointerEventData.position);
|
||||
|
||||
float distance = (_newTargetPosition - _neutralPosition).magnitude;
|
||||
|
||||
if (distance < MaxRange)
|
||||
{
|
||||
_dragging = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_dragging)
|
||||
{
|
||||
StickToPointer();
|
||||
}
|
||||
else
|
||||
{
|
||||
GoBackToInitialPosition();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void StickToPointer()
|
||||
{
|
||||
_draggedOnce = true;
|
||||
_eventPosition = _pointerEventData.position;
|
||||
|
||||
_newTargetPosition = GetWorldPosition(_eventPosition);
|
||||
|
||||
// We clamp the stick's position to let it move only inside its defined max range
|
||||
_newTargetPosition = Vector2.ClampMagnitude(_newTargetPosition - _neutralPosition, MaxRange);
|
||||
_newTargetPosition = _neutralPosition + _newTargetPosition;
|
||||
_newTargetPosition.z = _initialZPosition;
|
||||
|
||||
transform.position = _newTargetPosition;
|
||||
}
|
||||
|
||||
protected virtual void GoBackToInitialPosition()
|
||||
{
|
||||
if (!_draggedOnce)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Time.time - _dragEndedAt < DragResetDuration)
|
||||
{
|
||||
float time = Remap(Time.time - _dragEndedAt, 0f, DragResetDuration, 0f, 1f);
|
||||
float value = WobbleCurve.Evaluate(time) * WobbleFactor;
|
||||
_newTargetPosition = Vector3.LerpUnclamped(_neutralPosition, _dragEndedPosition, value);
|
||||
_newTargetPosition.z = _initialZPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
_newTargetPosition = _neutralPosition;
|
||||
_newTargetPosition.z = _initialZPosition;
|
||||
}
|
||||
transform.position = _newTargetPosition;
|
||||
}
|
||||
|
||||
public virtual void OnPointerEnter(PointerEventData data)
|
||||
{
|
||||
_pointerID = data.pointerId;
|
||||
_pointerEventData = data;
|
||||
_pointerOn = true;
|
||||
}
|
||||
|
||||
public virtual void OnPointerExit(PointerEventData data)
|
||||
{
|
||||
_eventPosition = _pointerEventData.position;
|
||||
|
||||
_newTargetPosition = GetWorldPosition(_eventPosition);
|
||||
_newTargetPosition = Vector2.ClampMagnitude(_newTargetPosition - _neutralPosition, MaxRange);
|
||||
_newTargetPosition = _neutralPosition + _newTargetPosition;
|
||||
_newTargetPosition.z = _initialZPosition;
|
||||
|
||||
_dragging = false;
|
||||
_dragEndedPosition = _newTargetPosition;
|
||||
_dragEndedAt = Time.time;
|
||||
_dragResetDirection = _dragEndedPosition - _neutralPosition;
|
||||
_pointerOn = false;
|
||||
|
||||
TargetAnimator.SetTrigger(_sparkAnimationParameter);
|
||||
SpringAudioSource.Play();
|
||||
SpringHapticSource.Play();
|
||||
}
|
||||
|
||||
protected virtual float Remap(float x, float A, float B, float C, float D)
|
||||
{
|
||||
float remappedValue = C + (x - A) / (B - A) * (D - C);
|
||||
return remappedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df337f93430edac488b1ddbd824df4d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public class WobbleDemoManager : DemoManager
|
||||
{
|
||||
public Camera ButtonCamera;
|
||||
public RectTransform ContentZone;
|
||||
public WobbleButton WobbleButtonPrefab;
|
||||
public Vector2 PrefabSize = new Vector2(200f, 200f);
|
||||
public float Margin = 20f;
|
||||
public float Padding = 20f;
|
||||
|
||||
protected List<WobbleButton> Buttons;
|
||||
protected Canvas _canvas;
|
||||
protected Vector3 _position = Vector3.zero;
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
_canvas = GetComponentInParent<Canvas>();
|
||||
|
||||
float horizontalF = (ContentZone.rect.width - 2 * Padding) / (PrefabSize.x + Margin);
|
||||
float verticalF = (ContentZone.rect.height - 2 * Padding) / (PrefabSize.y + Margin);
|
||||
int horizontal = Mathf.FloorToInt(horizontalF);
|
||||
int vertical = Mathf.FloorToInt(verticalF);
|
||||
|
||||
float centerH = (ContentZone.rect.width - (Padding * 2) - (horizontal * PrefabSize.x) - (horizontal - 1) * Margin) / 2f;
|
||||
float centerV = (ContentZone.rect.height - (Padding * 2) - (vertical * PrefabSize.x) - (vertical - 1) * Margin) / 2f;
|
||||
|
||||
Buttons = new List<WobbleButton>();
|
||||
|
||||
for (int i = 0; i < horizontal; i++)
|
||||
{
|
||||
for (int j = 0; j < vertical; j++)
|
||||
{
|
||||
_position.x = centerH + Padding + PrefabSize.x / 2f + i * (PrefabSize.x + Margin);
|
||||
_position.y = centerV + Padding + PrefabSize.y / 2f + j * (PrefabSize.y + Margin);
|
||||
_position.z = 0f;
|
||||
|
||||
WobbleButton button = Instantiate(WobbleButtonPrefab);
|
||||
button.transform.SetParent(ContentZone.transform);
|
||||
Buttons.Add(button);
|
||||
|
||||
RectTransform rectTransform = button.GetComponent<RectTransform>();
|
||||
rectTransform.anchorMin = Vector2.zero;
|
||||
rectTransform.anchorMax = Vector2.zero;
|
||||
button.name = "WobbleButton" + i + j;
|
||||
button.transform.localScale = Vector3.one;
|
||||
|
||||
rectTransform.anchoredPosition3D = _position;
|
||||
button.TargetCamera = ButtonCamera;
|
||||
button.Initialization();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
foreach (WobbleButton wbutton in Buttons)
|
||||
{
|
||||
float newPitch = NiceVibrationsDemoHelpers.Remap(counter, 0f, Buttons.Count, 0.3f, 1f);
|
||||
wbutton.SetPitch(newPitch);
|
||||
counter++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b4855626e574f44ba43876941f82210
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user