chore: initial commit
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public class DemoManager : MonoBehaviour
|
||||
{
|
||||
[Header("Demo")]
|
||||
public AudioSource DebugAudioEmphasis;
|
||||
public AudioSource DebugAudioContinuous;
|
||||
public MMUIShaker Logo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d17be13a510eb8d4e9143fc087d48ac8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public static class NiceVibrationsDemoHelpers
|
||||
{
|
||||
public static float Round(float value, int digits)
|
||||
{
|
||||
float mult = Mathf.Pow(10.0f, (float)digits);
|
||||
return Mathf.Round(value * mult) / mult;
|
||||
}
|
||||
|
||||
public static 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: 0b4ed85a472548245acff2bf62a492b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public class SoundSwitch : MonoBehaviour
|
||||
{
|
||||
public V2DemoManager DemoManager;
|
||||
|
||||
protected MMSwitch _switch;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_switch = this.gameObject.GetComponent<MMSwitch>();
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
if (DemoManager.SoundActive)
|
||||
{
|
||||
_switch.CurrentSwitchState = MMSwitch.SwitchStates.On;
|
||||
_switch.InitializeState();
|
||||
}
|
||||
else
|
||||
{
|
||||
_switch.CurrentSwitchState = MMSwitch.SwitchStates.Off;
|
||||
_switch.InitializeState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e91a9c36e72456e4db171843272d8a2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Feel/NiceVibrations/Demo/_Common/Scripts/UI.meta
Normal file
8
Assets/Feel/NiceVibrations/Demo/_Common/Scripts/UI.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db53aecfb6008cb4cac71d512dae5fe6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public class HapticCurve : MonoBehaviour
|
||||
{
|
||||
[Range(0f, 1f)]
|
||||
public float Amplitude = 1f;
|
||||
[Range(0f, 1f)]
|
||||
public float Frequency = 0f;
|
||||
public int PointsCount = 50;
|
||||
public float AmplitudeFactor = 3;
|
||||
[Range(1f, 4f)]
|
||||
private float Period = 1;
|
||||
public RectTransform StartPoint;
|
||||
public RectTransform EndPoint;
|
||||
|
||||
[Header("Movement")]
|
||||
public bool Move = false;
|
||||
public float MovementSpeed = 1f;
|
||||
|
||||
protected LineRenderer _targetLineRenderer;
|
||||
protected List<Vector3> Points;
|
||||
|
||||
protected Canvas _canvas;
|
||||
protected Camera _camera;
|
||||
|
||||
protected Vector3 _startPosition;
|
||||
protected Vector3 _endPosition;
|
||||
protected Vector3 _workPoint;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Initialization();
|
||||
}
|
||||
|
||||
protected virtual void Initialization()
|
||||
{
|
||||
Points = new List<Vector3>();
|
||||
_canvas = this.gameObject.GetComponentInParent<Canvas>();
|
||||
_targetLineRenderer = this.gameObject.GetComponent<LineRenderer>();
|
||||
_camera = _canvas.worldCamera;
|
||||
DrawCurve();
|
||||
}
|
||||
|
||||
protected virtual void DrawCurve()
|
||||
{
|
||||
_startPosition = StartPoint.transform.position;
|
||||
_startPosition.z -= 0.1f;
|
||||
_endPosition = EndPoint.transform.position;
|
||||
_endPosition.z -= 0.1f;
|
||||
|
||||
Points.Clear();
|
||||
|
||||
for (int i = 0; i < PointsCount; i++)
|
||||
{
|
||||
float t = NiceVibrationsDemoHelpers.Remap(i, 0, PointsCount, 0f, 1f);
|
||||
float sinValue = MMSignal.GetValue(t, MMSignal.SignalType.Sine, 1f, AmplitudeFactor, Period, 0f, false);
|
||||
|
||||
if (Move)
|
||||
{
|
||||
sinValue = MMSignal.GetValue(t + Time.time * MovementSpeed, MMSignal.SignalType.Sine, 1f, AmplitudeFactor, Period, 0f, false);
|
||||
}
|
||||
|
||||
_workPoint.x = Mathf.Lerp(_startPosition.x, _endPosition.x, t);
|
||||
_workPoint.y = sinValue * Amplitude + _startPosition.y;
|
||||
_workPoint.z = _startPosition.z;
|
||||
Points.Add(_workPoint);
|
||||
}
|
||||
|
||||
_targetLineRenderer.positionCount = PointsCount;
|
||||
_targetLineRenderer.SetPositions(Points.ToArray());
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
UpdateCurve(Amplitude, Frequency);
|
||||
}
|
||||
|
||||
public virtual void UpdateCurve(float amplitude, float frequency)
|
||||
{
|
||||
Amplitude = amplitude;
|
||||
Frequency = frequency;
|
||||
Period = NiceVibrationsDemoHelpers.Remap(frequency, 0f, 1f, 1f, 4f);
|
||||
DrawCurve();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a81aea2b884ed3d4da5135acac404ba3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
[RequireComponent(typeof(Text))]
|
||||
/// <summary>
|
||||
/// Add this class to a gameObject with a Text component and it'll feed it the number of FPS in real time.
|
||||
/// </summary>
|
||||
public class MMFPSCounter : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// The frequency at which the FPS counter should update (in seconds)
|
||||
/// </summary>
|
||||
public float UpdateInterval = 0.3f;
|
||||
|
||||
protected float _framesAccumulated = 0f;
|
||||
protected float _framesDrawnInTheInterval = 0f;
|
||||
protected float _timeLeft;
|
||||
protected Text _text;
|
||||
protected int _currentFPS;
|
||||
|
||||
static string[] _stringsFrom00To300 = {
|
||||
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09",
|
||||
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
|
||||
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
|
||||
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
|
||||
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
|
||||
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
|
||||
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
|
||||
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
|
||||
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
|
||||
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
|
||||
"100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
|
||||
"110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
|
||||
"120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
|
||||
"130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
|
||||
"140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
|
||||
"150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
|
||||
"160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
|
||||
"170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
|
||||
"180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
|
||||
"190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
|
||||
"200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
|
||||
"210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
|
||||
"220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
|
||||
"230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
|
||||
"240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
|
||||
"250", "251", "252", "253", "254", "255", "256", "257", "258", "259",
|
||||
"260", "261", "262", "263", "264", "265", "266", "267", "268", "269",
|
||||
"270", "271", "272", "273", "274", "275", "276", "277", "278", "279",
|
||||
"280", "281", "282", "283", "284", "285", "286", "287", "288", "289",
|
||||
"290", "291", "292", "293", "294", "295", "296", "297", "298", "299",
|
||||
"300"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// On Start(), we get the Text component and initialize our counter
|
||||
/// </summary>
|
||||
protected virtual void Start()
|
||||
{
|
||||
if (GetComponent<Text>() == null)
|
||||
{
|
||||
Debug.LogWarning("FPSCounter requires a GUIText component.");
|
||||
return;
|
||||
}
|
||||
_text = GetComponent<Text>();
|
||||
_timeLeft = UpdateInterval;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Update, we increment our various counters, and if we've reached our UpdateInterval, we update our FPS counter
|
||||
/// with the number of frames displayed since the last counter update
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
_framesDrawnInTheInterval++;
|
||||
_framesAccumulated = _framesAccumulated + Time.timeScale / Time.deltaTime;
|
||||
_timeLeft = _timeLeft - Time.deltaTime;
|
||||
|
||||
if (_timeLeft <= 0.0)
|
||||
{
|
||||
_currentFPS = (int)Mathf.Clamp(_framesAccumulated / _framesDrawnInTheInterval, 0, 300);
|
||||
if (_currentFPS >= 0 && _currentFPS <= 300)
|
||||
{
|
||||
_text.text = _stringsFrom00To300[_currentFPS];
|
||||
}
|
||||
_framesDrawnInTheInterval = 0;
|
||||
_framesAccumulated = 0f;
|
||||
_timeLeft = UpdateInterval;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a080b2252c3a59546a7462b0fb3ef79e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Add this component to any object and it'll set the target frame rate and vsync count. Note that vsync count must be 0 for the target FPS to work.
|
||||
/// </summary>
|
||||
public class MMFPSUnlock : MonoBehaviour
|
||||
{
|
||||
/// the target FPS you want the game to run at
|
||||
public int TargetFPS;
|
||||
[Range(0, 2)]
|
||||
/// whether vsync should be enabled or not (on a 60Hz screen, 1 : 60fps, 2 : 30fps, 0 : don't wait for vsync)
|
||||
public int VSyncCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// On start we change our target fps and vsync settings
|
||||
/// </summary>
|
||||
protected virtual void Start()
|
||||
{
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When a value gets changed in the editor, we update our settings
|
||||
/// </summary>
|
||||
protected virtual void OnValidate()
|
||||
{
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the target frame rate value and vsync count setting
|
||||
/// </summary>
|
||||
protected virtual void UpdateSettings()
|
||||
{
|
||||
QualitySettings.vSyncCount = VSyncCount;
|
||||
Application.targetFrameRate = TargetFPS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ecb76331b2602f4ba888267530cbfce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
125
Assets/Feel/NiceVibrations/Demo/_Common/Scripts/UI/MMKnob.cs
Normal file
125
Assets/Feel/NiceVibrations/Demo/_Common/Scripts/UI/MMKnob.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
// 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
|
||||
{
|
||||
[RequireComponent(typeof(Rect))]
|
||||
public class MMKnob : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
public RenderMode ParentCanvasRenderMode { get; protected set; }
|
||||
|
||||
[Header("Bindings")]
|
||||
public Camera TargetCamera;
|
||||
|
||||
[Header("Settings")]
|
||||
public float MinimumAngle = 45f;
|
||||
public float MaximumAngle = -225f;
|
||||
public float MaximumDistance = 50f;
|
||||
public Color ActiveColor;
|
||||
public Color InactiveColor;
|
||||
|
||||
[Header("Output")]
|
||||
public bool Dragging = false;
|
||||
public float Value = 0f;
|
||||
public bool Active = true;
|
||||
|
||||
public Image _image;
|
||||
protected PointerEventData _pointerEventData;
|
||||
protected float _distance;
|
||||
public RectTransform _rectTransform;
|
||||
protected Vector3 _rotation = Vector3.zero;
|
||||
protected Canvas _canvas;
|
||||
protected Vector2 _workPosition;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_image = this.gameObject.GetComponent<Image>();
|
||||
_canvas = GetComponentInParent<Canvas>();
|
||||
ParentCanvasRenderMode = GetComponentInParent<Canvas>().renderMode;
|
||||
_rectTransform = this.GetComponent<RectTransform>();
|
||||
SetRotation(MinimumAngle);
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (!Active)
|
||||
{
|
||||
Dragging = false;
|
||||
_image.color = InactiveColor;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_image.color = ActiveColor;
|
||||
}
|
||||
|
||||
if (!Dragging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 v1 = Vector2.down;
|
||||
Vector2 v2 = this.transform.position - GetWorldPosition(_pointerEventData.position);
|
||||
|
||||
float angle = Vector2.SignedAngle(v1, v2);
|
||||
|
||||
angle = Mathf.Clamp(angle, -130f, 130f);
|
||||
|
||||
_rotation.z = NiceVibrationsDemoHelpers.Remap(angle, -130f, 130f, MaximumAngle, MinimumAngle);
|
||||
_rectTransform.SetPositionAndRotation(this.transform.position, Quaternion.Euler(_rotation));
|
||||
|
||||
Value = NiceVibrationsDemoHelpers.Remap(angle, -130f, 130f, 1f, 0f);
|
||||
}
|
||||
|
||||
protected virtual void SetRotation(float angle)
|
||||
{
|
||||
angle = Mathf.Clamp(angle, MaximumAngle, MinimumAngle);
|
||||
_rotation.z = angle;
|
||||
_rectTransform.SetPositionAndRotation(this.transform.position, Quaternion.Euler(_rotation));
|
||||
}
|
||||
|
||||
public virtual void SetActive(bool status)
|
||||
{
|
||||
Active = status;
|
||||
}
|
||||
|
||||
public virtual void SetValue(float value)
|
||||
{
|
||||
SetRotation(MinimumAngle);
|
||||
Value = value;
|
||||
float angle = NiceVibrationsDemoHelpers.Remap(value, 0f, 1f, MinimumAngle, MaximumAngle);
|
||||
|
||||
_rotation.z = angle;
|
||||
_rectTransform.SetPositionAndRotation(this.transform.position, Quaternion.Euler(_rotation));
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
_pointerEventData = eventData;
|
||||
Dragging = true;
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
_pointerEventData = null;
|
||||
Dragging = false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 975863c8bb910594288081f50f6185aa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,354 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Add this bar to an object and link it to a bar (possibly the same object the script is on), and you'll be able to resize the bar object based on a current value, located between a min and max value.
|
||||
/// See the HealthBar.cs script for a use case
|
||||
/// </summary>
|
||||
public class MMProgressBar : MonoBehaviour
|
||||
{
|
||||
/// the possible fill modes
|
||||
public enum FillModes { LocalScale, FillAmount, Width, Height }
|
||||
/// the possible directions for the fill (for local scale and fill amount only)
|
||||
public enum BarDirections { LeftToRight, RightToLeft, UpToDown, DownToUp }
|
||||
/// the possible timescales the bar can work on
|
||||
public enum TimeScales { UnscaledTime, Time }
|
||||
|
||||
[Header("General Settings")]
|
||||
/// the local scale or fillamount value to reach when the bar is empty
|
||||
public float StartValue = 0f;
|
||||
/// the local scale or fillamount value to reach when the bar is full
|
||||
public float EndValue = 1f;
|
||||
/// the direction this bar moves to
|
||||
public BarDirections BarDirection = BarDirections.LeftToRight;
|
||||
/// the foreground bar's fill mode
|
||||
public FillModes FillMode = FillModes.LocalScale;
|
||||
/// defines whether the bar will work on scaled or unscaled time (whether or not it'll keep moving if time is slowed down for example)
|
||||
public TimeScales TimeScale = TimeScales.UnscaledTime;
|
||||
|
||||
[Header("Foreground Bar Settings")]
|
||||
/// whether or not the foreground bar should lerp
|
||||
public bool LerpForegroundBar = true;
|
||||
/// the speed at which to lerp the foreground bar
|
||||
public float LerpForegroundBarSpeed = 15f;
|
||||
|
||||
[Header("Delayed Bar Settings")]
|
||||
/// the delay before the delayed bar moves (in seconds)
|
||||
public float Delay = 1f;
|
||||
/// whether or not the delayed bar's animation should lerp
|
||||
public bool LerpDelayedBar = true;
|
||||
/// the speed at which to lerp the delayed bar
|
||||
public float LerpDelayedBarSpeed = 15f;
|
||||
|
||||
[Header("Bindings")]
|
||||
/// optional - the ID of the player associated to this bar
|
||||
public string PlayerID;
|
||||
/// the delayed bar
|
||||
public Transform DelayedBar;
|
||||
/// the main, foreground bar
|
||||
public Transform ForegroundBar;
|
||||
|
||||
[Header("Bump")]
|
||||
/// whether or not the bar should "bump" when changing value
|
||||
public bool BumpScaleOnChange = true;
|
||||
/// whether or not the bar should bump when its value increases
|
||||
public bool BumpOnIncrease = false;
|
||||
/// the duration of the bump animation
|
||||
public float BumpDuration = 0.2f;
|
||||
/// whether or not the bar should flash when bumping
|
||||
public bool ChangeColorWhenBumping = true;
|
||||
/// the color to apply to the bar when bumping
|
||||
public Color BumpColor = Color.white;
|
||||
/// the curve to map the bump animation on
|
||||
public AnimationCurve BumpAnimationCurve = new AnimationCurve(new Keyframe(1, 1), new Keyframe(0.3f, 1.05f), new Keyframe(1, 1));
|
||||
/// the curve to map the bump animation color animation on
|
||||
public AnimationCurve BumpColorAnimationCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
|
||||
/// whether or not the bar is bumping right now
|
||||
public bool Bumping { get; protected set; }
|
||||
|
||||
[Header("Realtime")]
|
||||
/// whether or not this progress bar should update itself every update (if not, you'll have to update it using the UpdateBar method
|
||||
public bool AutoUpdating = false;
|
||||
/// the current progress of the bar
|
||||
[Range(0f, 1f)]
|
||||
public float BarProgress;
|
||||
|
||||
protected float _targetFill;
|
||||
protected Vector3 _targetLocalScale = Vector3.one;
|
||||
protected float _newPercent;
|
||||
protected float _lastPercent;
|
||||
protected float _lastUpdateTimestamp;
|
||||
protected bool _bump = false;
|
||||
protected Color _initialColor;
|
||||
protected Vector3 _initialScale;
|
||||
protected Vector3 _newScale;
|
||||
protected Image _foregroundImage;
|
||||
protected Image _delayedImage;
|
||||
protected bool _initialized;
|
||||
protected Vector2 _initialFrontBarSize;
|
||||
|
||||
/// <summary>
|
||||
/// On start we store our image component
|
||||
/// </summary>
|
||||
protected virtual void Start()
|
||||
{
|
||||
_initialScale = this.transform.localScale;
|
||||
|
||||
if (ForegroundBar != null)
|
||||
{
|
||||
_foregroundImage = ForegroundBar.GetComponent<Image>();
|
||||
_initialFrontBarSize = _foregroundImage.rectTransform.sizeDelta;
|
||||
}
|
||||
if (DelayedBar != null)
|
||||
{
|
||||
_delayedImage = DelayedBar.GetComponent<Image>();
|
||||
}
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Update we update our bars
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
AutoUpdate();
|
||||
UpdateFrontBar();
|
||||
UpdateDelayedBar();
|
||||
}
|
||||
|
||||
protected virtual void AutoUpdate()
|
||||
{
|
||||
if (!AutoUpdating)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_newPercent = Remap(BarProgress, 0f, 1f, StartValue, EndValue);
|
||||
_targetFill = _newPercent;
|
||||
_lastUpdateTimestamp = (TimeScale == TimeScales.Time) ? Time.time : Time.unscaledTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the front bar's scale
|
||||
/// </summary>
|
||||
protected virtual void UpdateFrontBar()
|
||||
{
|
||||
float currentDeltaTime = (TimeScale == TimeScales.Time) ? Time.deltaTime : Time.unscaledTime;
|
||||
|
||||
if (ForegroundBar != null)
|
||||
{
|
||||
switch (FillMode)
|
||||
{
|
||||
case FillModes.LocalScale:
|
||||
_targetLocalScale = Vector3.one;
|
||||
switch (BarDirection)
|
||||
{
|
||||
case BarDirections.LeftToRight:
|
||||
_targetLocalScale.x = _targetFill;
|
||||
break;
|
||||
case BarDirections.RightToLeft:
|
||||
_targetLocalScale.x = 1f - _targetFill;
|
||||
break;
|
||||
case BarDirections.DownToUp:
|
||||
_targetLocalScale.y = _targetFill;
|
||||
break;
|
||||
case BarDirections.UpToDown:
|
||||
_targetLocalScale.y = 1f - _targetFill;
|
||||
break;
|
||||
}
|
||||
|
||||
if (LerpForegroundBar)
|
||||
{
|
||||
_newScale = Vector3.Lerp(ForegroundBar.localScale, _targetLocalScale, currentDeltaTime * LerpForegroundBarSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
_newScale = _targetLocalScale;
|
||||
}
|
||||
|
||||
ForegroundBar.localScale = _newScale;
|
||||
break;
|
||||
|
||||
case FillModes.Width:
|
||||
if (_foregroundImage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float newSizeX = Remap(_targetFill, 0f, 1f, 0, _initialFrontBarSize.x);
|
||||
newSizeX = Mathf.Lerp(_foregroundImage.rectTransform.sizeDelta.x, newSizeX, currentDeltaTime * LerpForegroundBarSpeed);
|
||||
_foregroundImage.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, newSizeX);
|
||||
break;
|
||||
|
||||
case FillModes.Height:
|
||||
if (_foregroundImage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float newSizeY = Remap(_targetFill, 0f, 1f, 0, _initialFrontBarSize.y);
|
||||
newSizeY = Mathf.Lerp(_foregroundImage.rectTransform.sizeDelta.x, newSizeY, currentDeltaTime * LerpForegroundBarSpeed);
|
||||
_foregroundImage.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, newSizeY);
|
||||
break;
|
||||
|
||||
case FillModes.FillAmount:
|
||||
if (_foregroundImage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (LerpForegroundBar)
|
||||
{
|
||||
_foregroundImage.fillAmount = Mathf.Lerp(_foregroundImage.fillAmount, _targetFill, currentDeltaTime * LerpForegroundBarSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
_foregroundImage.fillAmount = _targetFill;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the delayed bar's scale
|
||||
/// </summary>
|
||||
protected virtual void UpdateDelayedBar()
|
||||
{
|
||||
float currentDeltaTime = (TimeScale == TimeScales.Time) ? Time.deltaTime : Time.unscaledDeltaTime;
|
||||
float currentTime = (TimeScale == TimeScales.Time) ? Time.time : Time.unscaledTime;
|
||||
|
||||
if (DelayedBar != null)
|
||||
{
|
||||
if (currentTime - _lastUpdateTimestamp > Delay)
|
||||
{
|
||||
if (FillMode == FillModes.LocalScale)
|
||||
{
|
||||
_targetLocalScale = Vector3.one;
|
||||
|
||||
switch (BarDirection)
|
||||
{
|
||||
case BarDirections.LeftToRight:
|
||||
_targetLocalScale.x = _targetFill;
|
||||
break;
|
||||
case BarDirections.RightToLeft:
|
||||
_targetLocalScale.x = 1f - _targetFill;
|
||||
break;
|
||||
case BarDirections.DownToUp:
|
||||
_targetLocalScale.y = _targetFill;
|
||||
break;
|
||||
case BarDirections.UpToDown:
|
||||
_targetLocalScale.y = 1f - _targetFill;
|
||||
break;
|
||||
}
|
||||
|
||||
if (LerpDelayedBar)
|
||||
{
|
||||
_newScale = Vector3.Lerp(DelayedBar.localScale, _targetLocalScale, currentDeltaTime * LerpDelayedBarSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
_newScale = _targetLocalScale;
|
||||
}
|
||||
DelayedBar.localScale = _newScale;
|
||||
}
|
||||
|
||||
if ((FillMode == FillModes.FillAmount) && (_delayedImage != null))
|
||||
{
|
||||
if (LerpDelayedBar)
|
||||
{
|
||||
_delayedImage.fillAmount = Mathf.Lerp(_delayedImage.fillAmount, _targetFill, currentDeltaTime * LerpDelayedBarSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
_delayedImage.fillAmount = _targetFill;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the bar's values based on the specified parameters
|
||||
/// </summary>
|
||||
/// <param name="currentValue">Current value.</param>
|
||||
/// <param name="minValue">Minimum value.</param>
|
||||
/// <param name="maxValue">Max value.</param>
|
||||
public virtual void UpdateBar(float currentValue, float minValue, float maxValue)
|
||||
{
|
||||
_newPercent = Remap(currentValue, minValue, maxValue, StartValue, EndValue);
|
||||
if ((_newPercent != BarProgress) && !Bumping)
|
||||
{
|
||||
Bump();
|
||||
}
|
||||
BarProgress = _newPercent;
|
||||
_targetFill = _newPercent;
|
||||
_lastUpdateTimestamp = (TimeScale == TimeScales.Time) ? Time.time : Time.unscaledTime;
|
||||
_lastPercent = _newPercent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers a camera bump
|
||||
/// </summary>
|
||||
public virtual void Bump()
|
||||
{
|
||||
if (!BumpScaleOnChange || !_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!BumpOnIncrease && (_lastPercent < _newPercent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.gameObject.activeInHierarchy)
|
||||
{
|
||||
StartCoroutine(BumpCoroutine());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A coroutine that (usually quickly) changes the scale of the bar
|
||||
/// </summary>
|
||||
/// <returns>The coroutine.</returns>
|
||||
protected virtual IEnumerator BumpCoroutine()
|
||||
{
|
||||
float journey = 0f;
|
||||
float currentDeltaTime = (TimeScale == TimeScales.Time) ? Time.deltaTime : Time.unscaledDeltaTime;
|
||||
|
||||
Bumping = true;
|
||||
if (_foregroundImage != null)
|
||||
{
|
||||
_initialColor = _foregroundImage.color;
|
||||
}
|
||||
|
||||
while (journey <= BumpDuration)
|
||||
{
|
||||
journey = journey + currentDeltaTime;
|
||||
float percent = Mathf.Clamp01(journey / BumpDuration);
|
||||
float curvePercent = BumpAnimationCurve.Evaluate(percent);
|
||||
float colorCurvePercent = BumpColorAnimationCurve.Evaluate(percent);
|
||||
this.transform.localScale = curvePercent * _initialScale;
|
||||
|
||||
if (ChangeColorWhenBumping && (_foregroundImage != null))
|
||||
{
|
||||
_foregroundImage.color = Color.Lerp(_initialColor, BumpColor, colorCurvePercent);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
_foregroundImage.color = _initialColor;
|
||||
Bumping = false;
|
||||
yield return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
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: 0d9a9c3b9b9947b4b9b6b42f381d6cc1
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// This class lets you output the value corresponding to one of the basic signal types it contains. Useful to draw basic signal curves.
|
||||
/// </summary>
|
||||
public class MMSignal : MonoBehaviour
|
||||
{
|
||||
public enum SignalType
|
||||
{
|
||||
DigitalNoise,
|
||||
Pulse,
|
||||
Sawtooth,
|
||||
Sine,
|
||||
Square,
|
||||
Triangle,
|
||||
WhiteNoise
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the corresponding value based on the selected SignalType for a given time value
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <param name="signalType"></param>
|
||||
/// <param name="phase"></param>
|
||||
/// <param name="amplitude"></param>
|
||||
/// <param name="frequency"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="Invert"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetValue(float time, SignalType signalType, float phase, float amplitude, float frequency, float offset, bool Invert = false)
|
||||
{
|
||||
float value = 0f;
|
||||
float invert = Invert ? -1 : 1;
|
||||
float t = frequency * time + phase;
|
||||
|
||||
switch (signalType)
|
||||
{
|
||||
case SignalType.Sine:
|
||||
value = (float)Mathf.Sin(2f * Mathf.PI * t);
|
||||
break;
|
||||
case SignalType.Square:
|
||||
value = Mathf.Sign(Mathf.Sin(2f * Mathf.PI * t));
|
||||
break;
|
||||
case SignalType.Triangle:
|
||||
value = 1f - 4f * (float)Mathf.Abs(Mathf.Round(t - 0.25f) - (t - 0.25f));
|
||||
break;
|
||||
case SignalType.Sawtooth:
|
||||
value = 2f * (t - (float)Mathf.Floor(t + 0.5f));
|
||||
break;
|
||||
case SignalType.Pulse:
|
||||
value = (Mathf.Abs(Mathf.Sin(2 * Mathf.PI * t)) < 1.0 - 10E-3) ? (0) : (1);
|
||||
break;
|
||||
case SignalType.WhiteNoise:
|
||||
value = 2f * Random.Range(0, int.MaxValue) / int.MaxValue - 1f;
|
||||
break;
|
||||
case SignalType.DigitalNoise:
|
||||
value = Random.Range(0, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
return (invert * amplitude * value + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d76197e60487b7e46bf8b722dfde0a9b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,184 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
/// <summary>
|
||||
/// A class to add to an Image or SpriteRenderer to have it act like a button with a different sprite for on and off states
|
||||
/// </summary>
|
||||
public class MMSpriteReplace : MonoBehaviour
|
||||
{
|
||||
|
||||
[Header("Sprites")]
|
||||
|
||||
/// the sprite to use when in the "on" state
|
||||
public Sprite OnSprite;
|
||||
/// the sprite to use when in the "off" state
|
||||
public Sprite OffSprite;
|
||||
|
||||
[Header("Start settings")]
|
||||
/// if this is true, the button will start if "on" state
|
||||
public bool StartsOn = true;
|
||||
|
||||
/// the current state of the button
|
||||
public bool CurrentValue { get { return (_image.sprite == OnSprite); } }
|
||||
|
||||
protected Image _image;
|
||||
protected SpriteRenderer _spriteRenderer;
|
||||
protected MMTouchButton _mmTouchButton;
|
||||
|
||||
/// <summary>
|
||||
/// On Start we initialize our button
|
||||
/// </summary>
|
||||
protected virtual void Start()
|
||||
{
|
||||
Initialization();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On init, we grab our image component, and set our sprite in its initial state
|
||||
/// </summary>
|
||||
protected virtual void Initialization()
|
||||
{
|
||||
// grabs components
|
||||
_image = GetComponent<Image>();
|
||||
_spriteRenderer = GetComponent<SpriteRenderer>();
|
||||
|
||||
// grabs button
|
||||
_mmTouchButton = GetComponent<MMTouchButton>();
|
||||
if (_mmTouchButton != null)
|
||||
{
|
||||
_mmTouchButton.ReturnToInitialSpriteAutomatically = false;
|
||||
}
|
||||
|
||||
// handles start
|
||||
if ((OnSprite == null) || (OffSprite == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_image != null)
|
||||
{
|
||||
if (StartsOn)
|
||||
{
|
||||
_image.sprite = OnSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
_image.sprite = OffSprite;
|
||||
}
|
||||
}
|
||||
|
||||
if (_spriteRenderer != null)
|
||||
{
|
||||
if (StartsOn)
|
||||
{
|
||||
_spriteRenderer.sprite = OnSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
_spriteRenderer.sprite = OffSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A public method to change the sprite
|
||||
/// </summary>
|
||||
public virtual void Swap()
|
||||
{
|
||||
if (_image != null)
|
||||
{
|
||||
if (_image.sprite != OnSprite)
|
||||
{
|
||||
SwitchToOnSprite();
|
||||
}
|
||||
else
|
||||
{
|
||||
SwitchToOffSprite();
|
||||
}
|
||||
}
|
||||
|
||||
if (_spriteRenderer != null)
|
||||
{
|
||||
if (_spriteRenderer.sprite != OnSprite)
|
||||
{
|
||||
SwitchToOnSprite();
|
||||
}
|
||||
else
|
||||
{
|
||||
SwitchToOffSprite();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// a public method to switch to off sprite directly
|
||||
/// </summary>
|
||||
public virtual void SwitchToOffSprite()
|
||||
{
|
||||
if ((_image == null) && (_spriteRenderer == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (OffSprite == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SpriteOff();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the image's sprite to off
|
||||
/// </summary>
|
||||
protected virtual void SpriteOff()
|
||||
{
|
||||
if (_image != null)
|
||||
{
|
||||
_image.sprite = OffSprite;
|
||||
}
|
||||
if (_spriteRenderer != null)
|
||||
{
|
||||
_spriteRenderer.sprite = OffSprite;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// a public method to switch to on sprite directly
|
||||
/// </summary>
|
||||
public virtual void SwitchToOnSprite()
|
||||
{
|
||||
if ((_image == null) && (_spriteRenderer == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (OnSprite == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SpriteOn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the image's sprite to on
|
||||
/// </summary>
|
||||
protected virtual void SpriteOn()
|
||||
{
|
||||
|
||||
if (_image != null)
|
||||
{
|
||||
_image.sprite = OnSprite;
|
||||
}
|
||||
if (_spriteRenderer != null)
|
||||
{
|
||||
_spriteRenderer.sprite = OnSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 516e3ec07e472164f97fd51ce17b13b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
122
Assets/Feel/NiceVibrations/Demo/_Common/Scripts/UI/MMSwitch.cs
Normal file
122
Assets/Feel/NiceVibrations/Demo/_Common/Scripts/UI/MMSwitch.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
/// <summary>
|
||||
/// A component to handle switches
|
||||
/// </summary>
|
||||
public class MMSwitch : MMTouchButton
|
||||
{
|
||||
[Header("Switch")]
|
||||
/// a SpriteReplace to represent the switch knob
|
||||
public Image SwitchKnob;
|
||||
/// the possible states of the switch
|
||||
public enum SwitchStates { Off, On }
|
||||
/// the current state of the switch
|
||||
public SwitchStates CurrentSwitchState { get; set; }
|
||||
|
||||
[Header("Knob")]
|
||||
/// the state the switch should start in
|
||||
public SwitchStates InitialState = SwitchStates.Off;
|
||||
public Transform OffPosition;
|
||||
public Transform OnPosition;
|
||||
public AnimationCurve KnobMovementCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
||||
public float KnobMovementDuration = 0.2f;
|
||||
|
||||
[Header("Binding")]
|
||||
/// the methods to call when the switch is turned on
|
||||
public UnityEvent SwitchOn;
|
||||
/// the methods to call when the switch is turned off
|
||||
public UnityEvent SwitchOff;
|
||||
|
||||
protected float _knobMovementStartedAt = -50f;
|
||||
|
||||
/// <summary>
|
||||
/// On init, we set our current switch state
|
||||
/// </summary>
|
||||
protected override void Initialization()
|
||||
{
|
||||
base.Initialization();
|
||||
CurrentSwitchState = InitialState;
|
||||
InitializeState();
|
||||
}
|
||||
|
||||
public virtual void InitializeState()
|
||||
{
|
||||
if (CurrentSwitchState == SwitchStates.Off)
|
||||
{
|
||||
if (_animator != null)
|
||||
{
|
||||
_animator.Play("RollLeft");
|
||||
}
|
||||
SwitchKnob.transform.position = OffPosition.transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_animator != null)
|
||||
{
|
||||
_animator.Play("RollRight");
|
||||
}
|
||||
SwitchKnob.transform.position = OnPosition.transform.position;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
if (Time.time - _knobMovementStartedAt < KnobMovementDuration)
|
||||
{
|
||||
float time = Remap(Time.time - _knobMovementStartedAt, 0f, KnobMovementDuration, 0f, 1f);
|
||||
float value = KnobMovementCurve.Evaluate(time);
|
||||
|
||||
if (CurrentSwitchState == SwitchStates.Off)
|
||||
{
|
||||
SwitchKnob.transform.position = Vector3.Lerp(OnPosition.transform.position, OffPosition.transform.position, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
SwitchKnob.transform.position = Vector3.Lerp(OffPosition.transform.position, OnPosition.transform.position, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this method to go from one state to the other
|
||||
/// </summary>
|
||||
public virtual void SwitchState()
|
||||
{
|
||||
_knobMovementStartedAt = Time.time;
|
||||
if (CurrentSwitchState == SwitchStates.Off)
|
||||
{
|
||||
CurrentSwitchState = SwitchStates.On;
|
||||
if (_animator != null)
|
||||
{
|
||||
_animator?.SetTrigger("Right");
|
||||
}
|
||||
if (SwitchOn != null)
|
||||
{
|
||||
SwitchOn.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSwitchState = SwitchStates.Off;
|
||||
if (_animator != null)
|
||||
{
|
||||
_animator?.SetTrigger("Left");
|
||||
}
|
||||
if (SwitchOff != null)
|
||||
{
|
||||
SwitchOff.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdac5e74bb2234a4aa365592aa547afb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,395 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
[RequireComponent(typeof(Rect))]
|
||||
[RequireComponent(typeof(CanvasGroup))]
|
||||
/// <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>
|
||||
public class MMTouchButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler, IPointerEnterHandler, ISubmitHandler
|
||||
{
|
||||
/// 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
|
||||
public UnityEvent ButtonPressedFirstTime;
|
||||
/// The method(s) to call when the button gets released
|
||||
public UnityEvent ButtonReleased;
|
||||
/// The method(s) to call while the button is being pressed
|
||||
public UnityEvent ButtonPressed;
|
||||
|
||||
[Header("Sprite Swap")]
|
||||
public Sprite DisabledSprite;
|
||||
public Sprite PressedSprite;
|
||||
public Sprite HighlightedSprite;
|
||||
|
||||
[Header("Color Changes")]
|
||||
public bool PressedChangeColor = false;
|
||||
public Color PressedColor = Color.white;
|
||||
public bool LerpColor = true;
|
||||
public float LerpColorDuration = 0.2f;
|
||||
public AnimationCurve LerpColorCurve;
|
||||
|
||||
[Header("Opacity")]
|
||||
/// the new opacity to apply to the canvas group when the button is pressed
|
||||
public float PressedOpacity = 1f;
|
||||
public float IdleOpacity = 1f;
|
||||
public float DisabledOpacity = 1f;
|
||||
|
||||
[Header("Delays")]
|
||||
public float PressedFirstTimeDelay = 0f;
|
||||
public float ReleasedDelay = 0f;
|
||||
|
||||
[Header("Buffer")]
|
||||
public float BufferDuration = 0f;
|
||||
|
||||
[Header("Animation")]
|
||||
public Animator Animator;
|
||||
public string IdleAnimationParameterName = "Idle";
|
||||
public string DisabledAnimationParameterName = "Disabled";
|
||||
public string PressedAnimationParameterName = "Pressed";
|
||||
|
||||
[Header("Mouse Mode")]
|
||||
/// 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 ReturnToInitialSpriteAutomatically { get; set; }
|
||||
|
||||
/// the current state of the button (off, down, pressed or up)
|
||||
public ButtonStates CurrentState { get; protected set; }
|
||||
|
||||
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;
|
||||
protected float _lastStateChangeAt = -50f;
|
||||
|
||||
protected Color _imageColor;
|
||||
protected Color _fromColor;
|
||||
protected Color _toColor;
|
||||
|
||||
/// <summary>
|
||||
/// On Start, we get our canvasgroup and set our initial alpha
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Initialization();
|
||||
}
|
||||
|
||||
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.sprite = _initialSprite;
|
||||
}
|
||||
if (_selectable != null)
|
||||
{
|
||||
_selectable.interactable = true;
|
||||
if (EventSystem.current.currentSelectedGameObject == this.gameObject)
|
||||
{
|
||||
if (HighlightedSprite != null)
|
||||
{
|
||||
_image.sprite = HighlightedSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonStates.Disabled:
|
||||
SetOpacity(DisabledOpacity);
|
||||
if (_image != null)
|
||||
{
|
||||
if (DisabledSprite != null)
|
||||
{
|
||||
_image.sprite = DisabledSprite;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if ((_image != null) && (PressedChangeColor))
|
||||
{
|
||||
if (Time.time - _lastStateChangeAt < LerpColorDuration)
|
||||
{
|
||||
float t = LerpColorCurve.Evaluate(Remap(Time.time - _lastStateChangeAt, 0f, LerpColorDuration, 0f, 1f));
|
||||
_image.color = Color.Lerp(_fromColor, _toColor, t);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
_lastStateChangeAt = Time.time;
|
||||
_fromColor = PressedColor;
|
||||
_toColor = _initialColor;
|
||||
CurrentState = ButtonStates.Off;
|
||||
}
|
||||
if (CurrentState == ButtonStates.ButtonDown)
|
||||
{
|
||||
_lastStateChangeAt = Time.time;
|
||||
_fromColor = _initialColor;
|
||||
_toColor = PressedColor;
|
||||
CurrentState = ButtonStates.ButtonPressed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer down action
|
||||
/// </summary>
|
||||
public virtual void OnPointerDown(PointerEventData data)
|
||||
{
|
||||
if (Time.time - _lastClickTimestamp < BufferDuration)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentState != ButtonStates.Off)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CurrentState = ButtonStates.ButtonDown;
|
||||
_lastClickTimestamp = Time.time;
|
||||
if ((Time.timeScale != 0) && (PressedFirstTimeDelay > 0))
|
||||
{
|
||||
Invoke("InvokePressedFirstTime", PressedFirstTimeDelay);
|
||||
}
|
||||
else
|
||||
{
|
||||
ButtonPressedFirstTime.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void InvokePressedFirstTime()
|
||||
{
|
||||
if (ButtonPressedFirstTime != null)
|
||||
{
|
||||
ButtonPressedFirstTime.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 ((Time.timeScale != 0) && (ReleasedDelay > 0))
|
||||
{
|
||||
Invoke("InvokeReleased", ReleasedDelay);
|
||||
}
|
||||
else
|
||||
{
|
||||
ButtonReleased.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void InvokeReleased()
|
||||
{
|
||||
if (ButtonReleased != null)
|
||||
{
|
||||
ButtonReleased.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the bound pointer pressed action
|
||||
/// </summary>
|
||||
public virtual void OnPointerPressed()
|
||||
{
|
||||
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 (!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>
|
||||
/// OnEnable, we reset our button state
|
||||
/// </summary>
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
ResetButton();
|
||||
}
|
||||
|
||||
public virtual void DisableButton()
|
||||
{
|
||||
CurrentState = ButtonStates.Disabled;
|
||||
}
|
||||
|
||||
public virtual void EnableButton()
|
||||
{
|
||||
if (CurrentState == ButtonStates.Disabled)
|
||||
{
|
||||
CurrentState = ButtonStates.Off;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void SetOpacity(float newOpacity)
|
||||
{
|
||||
if (_canvasGroup != null)
|
||||
{
|
||||
_canvasGroup.alpha = newOpacity;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnSubmit(BaseEventData eventData)
|
||||
{
|
||||
if (ButtonPressedFirstTime != null)
|
||||
{
|
||||
ButtonPressedFirstTime.Invoke();
|
||||
}
|
||||
if (ButtonReleased != null)
|
||||
{
|
||||
ButtonReleased.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
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: 98d97271f03727a4f93fa3baff1ea05f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public class MMUIShaker : MonoBehaviour
|
||||
{
|
||||
public float Amplitude;
|
||||
public float Frequency;
|
||||
public bool Shaking = false;
|
||||
|
||||
protected Vector3 _initialPosition;
|
||||
protected Vector3 _shakePosition;
|
||||
protected RectTransform _rectTransform;
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
_rectTransform = this.gameObject.GetComponent<RectTransform>();
|
||||
_initialPosition = _rectTransform.localPosition;
|
||||
}
|
||||
|
||||
public virtual IEnumerator Shake(float duration)
|
||||
{
|
||||
Shaking = true;
|
||||
yield return new WaitForSeconds(duration);
|
||||
Shaking = false;
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (!Shaking)
|
||||
{
|
||||
_rectTransform.localPosition = _initialPosition;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_shakePosition.x = Mathf.PerlinNoise(-(Time.time) * Frequency, Time.time * Frequency) * Amplitude - Amplitude / 2f;
|
||||
_shakePosition.y = Mathf.PerlinNoise(-(Time.time + 0.25f) * Frequency, Time.time * Frequency) * Amplitude - Amplitude / 2f;
|
||||
_shakePosition.z = Mathf.PerlinNoise(-(Time.time + 0.5f) * Frequency, Time.time * Frequency) * Amplitude - Amplitude / 2f;
|
||||
_rectTransform.localPosition = _initialPosition + _shakePosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 109aed369f1d8af47948f3f6aafbdbdc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public class Pagination : MonoBehaviour
|
||||
{
|
||||
public GameObject PaginationDotPrefab;
|
||||
public Color ActiveColor;
|
||||
public Color InactiveColor;
|
||||
protected List<Image> _images;
|
||||
|
||||
public virtual void InitializePagination(int numberOfPages)
|
||||
{
|
||||
_images = new List<Image>();
|
||||
for (int i = 0; i < numberOfPages; i++)
|
||||
{
|
||||
GameObject dotPrefab = Instantiate(PaginationDotPrefab);
|
||||
dotPrefab.transform.SetParent(this.transform);
|
||||
dotPrefab.name = "PaginationDot" + i;
|
||||
_images.Add(dotPrefab.GetComponent<Image>());
|
||||
}
|
||||
foreach (Image image in _images)
|
||||
{
|
||||
image.color = InactiveColor;
|
||||
image.rectTransform.localScale = Vector3.one;
|
||||
image.rectTransform.localPosition = Vector3.zero;
|
||||
image.SetNativeSize();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetCurrentPage(int numberOfPages, int currentPage)
|
||||
{
|
||||
for (int i = 0; i < numberOfPages; i++)
|
||||
{
|
||||
if (i == currentPage)
|
||||
{
|
||||
_images[i].color = ActiveColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
_images[i].color = InactiveColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7719238c9686c2645a6b5a89cba3de35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
159
Assets/Feel/NiceVibrations/Demo/_Common/Scripts/V2DemoManager.cs
Normal file
159
Assets/Feel/NiceVibrations/Demo/_Common/Scripts/V2DemoManager.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
public class V2DemoManager : MonoBehaviour
|
||||
{
|
||||
public List<RectTransform> Pages;
|
||||
public int CurrentPage = 0;
|
||||
public float PageTransitionDuration = 1f;
|
||||
public AnimationCurve TransitionCurve;
|
||||
public Color ActiveColor;
|
||||
public Color InactiveColor;
|
||||
public bool SoundActive = true;
|
||||
|
||||
protected Vector3 _position;
|
||||
protected List<Pagination> _paginations;
|
||||
protected Coroutine _transitionCoroutine;
|
||||
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
Initialization();
|
||||
}
|
||||
|
||||
protected virtual void Initialization()
|
||||
{
|
||||
Application.targetFrameRate = 60;
|
||||
_paginations = new List<Pagination>();
|
||||
foreach (RectTransform page in Pages)
|
||||
{
|
||||
_paginations.Add(page.GetComponentInChildren<Pagination>());
|
||||
page.gameObject.SetActive(false);
|
||||
}
|
||||
foreach (Pagination pagination in _paginations)
|
||||
{
|
||||
pagination.InitializePagination(Pages.Count);
|
||||
pagination.ActiveColor = ActiveColor;
|
||||
pagination.InactiveColor = InactiveColor;
|
||||
pagination.SetCurrentPage(Pages.Count, 0);
|
||||
}
|
||||
Pages[0].gameObject.SetActive(true);
|
||||
if (SoundActive)
|
||||
{
|
||||
AudioListener.volume = 1f;
|
||||
SoundActive = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioListener.volume = 0f;
|
||||
SoundActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PreviousPage()
|
||||
{
|
||||
if (CurrentPage > 0)
|
||||
{
|
||||
CurrentPage--;
|
||||
Transition(CurrentPage + 1, CurrentPage, false);
|
||||
SetCurrentPage();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void NextPage()
|
||||
{
|
||||
if (CurrentPage < Pages.Count - 1)
|
||||
{
|
||||
CurrentPage++;
|
||||
Transition(CurrentPage - 1, CurrentPage, true);
|
||||
SetCurrentPage();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void SetCurrentPage()
|
||||
{
|
||||
foreach (Pagination pagination in _paginations)
|
||||
{
|
||||
pagination.SetCurrentPage(Pages.Count, CurrentPage);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Transition(int previous, int next, bool goingRight)
|
||||
{
|
||||
HapticController.Reset();
|
||||
|
||||
if (_transitionCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_transitionCoroutine);
|
||||
}
|
||||
_transitionCoroutine = StartCoroutine(TransitionCoroutine(previous, next, goingRight));
|
||||
}
|
||||
|
||||
protected virtual IEnumerator TransitionCoroutine(int previous, int next, bool goingRight)
|
||||
{
|
||||
_position.y = Pages[previous].localPosition.y;
|
||||
_position.z = Pages[previous].localPosition.z;
|
||||
|
||||
foreach (RectTransform page in Pages)
|
||||
{
|
||||
_position.x = 1200f;
|
||||
page.localPosition = _position;
|
||||
}
|
||||
|
||||
Pages[next].gameObject.SetActive(true);
|
||||
|
||||
float timeSpent = 0f;
|
||||
while (timeSpent < PageTransitionDuration)
|
||||
{
|
||||
if (goingRight)
|
||||
{
|
||||
_position.x = Mathf.Lerp(0f, -1200f, TransitionCurve.Evaluate(NiceVibrationsDemoHelpers.Remap(timeSpent, 0f, PageTransitionDuration, 0f, 1f)));
|
||||
Pages[previous].localPosition = _position;
|
||||
_position.x = Mathf.Lerp(1200f, 0f, TransitionCurve.Evaluate(NiceVibrationsDemoHelpers.Remap(timeSpent, 0f, PageTransitionDuration, 0f, 1f)));
|
||||
Pages[next].localPosition = _position;
|
||||
}
|
||||
else
|
||||
{
|
||||
_position.x = Mathf.Lerp(0f, 1200f, TransitionCurve.Evaluate(NiceVibrationsDemoHelpers.Remap(timeSpent, 0f, PageTransitionDuration, 0f, 1f)));
|
||||
Pages[previous].localPosition = _position;
|
||||
_position.x = Mathf.Lerp(-1200f, 0f, TransitionCurve.Evaluate(NiceVibrationsDemoHelpers.Remap(timeSpent, 0f, PageTransitionDuration, 0f, 1f)));
|
||||
Pages[next].localPosition = _position;
|
||||
}
|
||||
|
||||
timeSpent += Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Pages[previous].gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public virtual void TurnHapticsOn()
|
||||
{
|
||||
HapticPatterns.PlayPreset(HapticPatterns.PresetType.Success);
|
||||
}
|
||||
|
||||
public virtual void TurnHapticsOff()
|
||||
{
|
||||
HapticPatterns.PlayPreset(HapticPatterns.PresetType.Warning);
|
||||
}
|
||||
|
||||
public virtual void TurnSoundsOn()
|
||||
{
|
||||
AudioListener.volume = 1f;
|
||||
SoundActive = true;
|
||||
HapticPatterns.PlayPreset(HapticPatterns.PresetType.Success);
|
||||
}
|
||||
|
||||
public virtual void TurnSoundsOff()
|
||||
{
|
||||
AudioListener.volume = 0f;
|
||||
SoundActive = false;
|
||||
HapticPatterns.PlayPreset(HapticPatterns.PresetType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10365fb504697425a880c74cc63902ec
|
||||
timeCreated: 1515035236
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Lofelt.NiceVibrations
|
||||
{
|
||||
[RequireComponent(typeof(Text))]
|
||||
public class VersionNumber : MonoBehaviour
|
||||
{
|
||||
public string Version = "v3.3";
|
||||
|
||||
protected Text _text;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_text = this.gameObject.GetComponent<Text>();
|
||||
}
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
// There is not much space in the text, so make the string for alpha
|
||||
// and beta versions a bit shorter
|
||||
_text.text = Version.Replace("-alpha.", "a").Replace("-beta.", "b");
|
||||
|
||||
#if (UNITY_IOS && !UNITY_EDITOR)
|
||||
_text.text += " iOS " + DeviceCapabilities.platformVersion.ToString();
|
||||
#elif (UNITY_ANDROID && !UNITY_EDITOR)
|
||||
_text.text += " Android " + DeviceCapabilities.platformVersion.ToString();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61c0f36737ce72e4282216983bcc84d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user