Predective algo
This commit is contained in:
@@ -7,8 +7,10 @@ public class CamFollower : MonoBehaviour
|
||||
public Transform target;
|
||||
Vector3 offset;
|
||||
public float speed = 0.1f;
|
||||
public static CamFollower instance;
|
||||
private void Awake()
|
||||
{
|
||||
instance = this;
|
||||
offset = transform.position - target.position;
|
||||
}
|
||||
void Start()
|
||||
@@ -17,8 +19,12 @@ public class CamFollower : MonoBehaviour
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void FixedUpdate ()
|
||||
public void UpdateFrame ()
|
||||
{
|
||||
}
|
||||
|
||||
void LateUpdate(){
|
||||
transform.position = Vector3.Lerp(transform.position, target.position + offset, speed);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
21
Assets/Scripts/Helpers.cs
Normal file
21
Assets/Scripts/Helpers.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class Helpers{
|
||||
|
||||
public static List<float> BubbleSort(List<float> array){
|
||||
float temp =0;
|
||||
List<float> output = new List<float>();
|
||||
output.AddRange(array);
|
||||
for(int write=0; write < output.Count; write++){
|
||||
for(int sort=0; sort < output.Count-1; sort++){
|
||||
if(output[sort] > output[sort+1]){
|
||||
temp = output[sort+1];
|
||||
output[sort + 1] = output[sort];
|
||||
output[sort] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Helpers.cs.meta
Normal file
11
Assets/Scripts/Helpers.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b84cb24ae83a454ca038cc76e0e628c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/Mover.meta
Normal file
8
Assets/Scripts/Mover.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dacfc47cc20142148bb412040dd4c124
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
44
Assets/Scripts/Mover/MoverSettingsManager.cs
Normal file
44
Assets/Scripts/Mover/MoverSettingsManager.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class MoverSettingsManager : MonoBehaviour
|
||||
{
|
||||
public Slider xSlider,ySlider;
|
||||
public Button btnClose,btnSave,btnRestart;
|
||||
public PredictiveMover mover;
|
||||
|
||||
public GameObject panel;
|
||||
public GameObject activator;
|
||||
|
||||
void Start()
|
||||
{
|
||||
xSlider.onValueChanged.AddListener(OnSettingsChanged);
|
||||
ySlider.onValueChanged.AddListener(OnSettingsChanged);
|
||||
|
||||
btnClose.onClick.AddListener(HideSettings);
|
||||
btnRestart.onClick.AddListener(Restart);
|
||||
m_onSettingsChanged();
|
||||
}
|
||||
|
||||
void HideSettings(){
|
||||
activator.SetActive(true);
|
||||
panel.SetActive(false);
|
||||
}
|
||||
|
||||
void OnSettingsChanged(float useless){
|
||||
m_onSettingsChanged();
|
||||
}
|
||||
|
||||
void m_onSettingsChanged(){
|
||||
mover.multipliers.x = xSlider.value;
|
||||
mover.multipliers.y = ySlider.value;
|
||||
|
||||
mover.RegenerateLines();
|
||||
}
|
||||
|
||||
void Restart(){
|
||||
mover.Restart();
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Mover/MoverSettingsManager.cs.meta
Normal file
11
Assets/Scripts/Mover/MoverSettingsManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00de3ca2780fc9d4383d675e3bb35bf7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
30
Assets/Scripts/Mover/MoverSettingsPanel.cs
Normal file
30
Assets/Scripts/Mover/MoverSettingsPanel.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class MoverSettingsPanel : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
|
||||
float touchdownTimer =0f;
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
touchdownTimer =0f;
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
if(touchdownTimer > 4){
|
||||
settingsPanel.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
public GameObject settingsPanel;
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(touchdownTimer < 5f){
|
||||
touchdownTimer +=Time.deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Mover/MoverSettingsPanel.cs.meta
Normal file
11
Assets/Scripts/Mover/MoverSettingsPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17228f1c211f8ed4db8114fd85f6b2d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
123
Assets/Scripts/Mover/PredictiveMover.cs
Normal file
123
Assets/Scripts/Mover/PredictiveMover.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class PredictiveMover : MonoBehaviour
|
||||
{
|
||||
|
||||
private Vector3[] points;
|
||||
public List<float> allHits = new List<float>();
|
||||
public LineRenderer line;
|
||||
public GameObject objectToMove;
|
||||
public AudioSource source;
|
||||
public float audioOffset = -0.05f;
|
||||
public Vector2 multipliers;
|
||||
public AnimationCurve lerpCurve;
|
||||
|
||||
public DrawShape botShape, topShape;
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
RegenerateLines();
|
||||
}
|
||||
|
||||
public void RegenerateLines()
|
||||
{
|
||||
points = new Vector3[allHits.Count];
|
||||
|
||||
for (int i = 0; i < points.Length; i++)
|
||||
{
|
||||
points[i] = GetPosition(i);
|
||||
}
|
||||
|
||||
line.positionCount = points.Length;
|
||||
line.SetPositions(points);
|
||||
}
|
||||
|
||||
void Start(){
|
||||
Restart();
|
||||
}
|
||||
|
||||
|
||||
void FixedUpdate(){
|
||||
// RegenerateLines();
|
||||
objectToMove.transform.position = Vector3.Lerp(objectToMove.transform.position,GetPositionAtTime(source.time + audioOffset),0.5f);
|
||||
CamFollower.instance.UpdateFrame();
|
||||
}
|
||||
|
||||
public void Restart(){
|
||||
source.time =0;
|
||||
source.Play();
|
||||
|
||||
RegenerateLines();
|
||||
List<Vector3> botPoints = new List<Vector3>();
|
||||
List<Vector3> topPoints = new List<Vector3>();
|
||||
for(int i=0; i < points.Length; i++){
|
||||
if(i%2 == 0){
|
||||
botPoints.Add(points[i]);
|
||||
}else{
|
||||
topPoints.Add(points[i]);
|
||||
}
|
||||
}
|
||||
botShape.Draw(botPoints, new Vector3(0, 30));
|
||||
topShape.Draw(topPoints, new Vector3(0, -30));
|
||||
}
|
||||
|
||||
Vector3 GetPosition(int index)
|
||||
{
|
||||
float hitX = allHits[index];
|
||||
|
||||
float diff = 0;
|
||||
float prevY = 0;
|
||||
|
||||
// Calculate diff and prevY if the index is greater than 0
|
||||
if (index > 0)
|
||||
{
|
||||
diff = allHits[index] - allHits[index - 1];
|
||||
prevY = points[index - 1].y; // Use the already calculated point to avoid recursion
|
||||
}
|
||||
|
||||
float flipSide = index % 2 == 0 ? 1 : -1;
|
||||
float y = prevY + (flipSide * diff * multipliers.y);
|
||||
|
||||
return new Vector3(hitX * multipliers.x, y, 0);
|
||||
}
|
||||
|
||||
public float bouncingIntensity = 0.5f;
|
||||
public Vector3 GetPositionAtTime(float time)
|
||||
{
|
||||
if (points == null || points.Length < 2)
|
||||
{
|
||||
return Vector3.zero; // Return zero if points are not set up
|
||||
}
|
||||
|
||||
// If the time is before the first hit, return the first position
|
||||
if (time <= allHits[0])
|
||||
{
|
||||
return points[0];
|
||||
}
|
||||
|
||||
// If the time is after the last hit, return the last position
|
||||
if (time >= allHits[allHits.Count - 1])
|
||||
{
|
||||
return points[points.Length - 1];
|
||||
}
|
||||
|
||||
// Find the current segment based on the given time
|
||||
for (int i = 0; i < allHits.Count - 1; i++)
|
||||
{
|
||||
if (time >= allHits[i] && time < allHits[i + 1])
|
||||
{
|
||||
Vector3 startPoint = points[i];
|
||||
Vector3 endPoint = points[i + 1];
|
||||
float segmentDuration = allHits[i + 1] - allHits[i];
|
||||
float t = (time - allHits[i]) / segmentDuration;
|
||||
|
||||
float curvedVal = lerpCurve.Evaluate(t);
|
||||
return Vector3.Lerp(startPoint, endPoint,curvedVal);
|
||||
}
|
||||
}
|
||||
|
||||
return Vector3.zero; // Return zero if no valid segment is found (should not happen)
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Mover/PredictiveMover.cs.meta
Normal file
11
Assets/Scripts/Mover/PredictiveMover.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a0f01b5b35bc4d46bbe9ec3a2c09a68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -7,6 +7,7 @@ using UnityEngine.Networking;
|
||||
public class LoadFromPrep : MonoBehaviour
|
||||
{
|
||||
public AudioSource source;
|
||||
public PredictiveMover mover;
|
||||
|
||||
void Awake(){
|
||||
if(PrepConnector.saveLoadData == null){
|
||||
@@ -18,6 +19,7 @@ public class LoadFromPrep : MonoBehaviour
|
||||
void Start(){
|
||||
if(PrepConnector.saveLoadData != null){
|
||||
StartCoroutine(LoadAudioCoroutine(PrepConnector.saveLoadData.musicFile));
|
||||
mover.allHits = PrepConnector.saveLoadData.hits;
|
||||
PlayerPrefs.SetString("saveData", JsonUtility.ToJson(PrepConnector.saveLoadData));
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@@ -15,7 +16,7 @@ public class PrepController : MonoBehaviour
|
||||
public Button pinBtn;
|
||||
public Button removePinBtn;
|
||||
public Toggle followSeekerToggle;
|
||||
|
||||
public TMP_Text playbackTimeTxt;
|
||||
public static List<GameObject> markers = new List<GameObject>();
|
||||
|
||||
public static void Reset(){
|
||||
@@ -28,12 +29,20 @@ public class PrepController : MonoBehaviour
|
||||
pinBtn.onClick.AddListener(AddMarker);
|
||||
removePinBtn.onClick.AddListener(RemoveMarker);
|
||||
instance = this;
|
||||
|
||||
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if(followSeekerToggle.isOn && source.isPlaying){
|
||||
cam.position = new Vector3(source.time * AudioAnalyzer.instance.zoomingYMult, cam.position.y, cam.position.z);
|
||||
source.time = startOffset + (Time.time - startTime);
|
||||
playbackTimeTxt.text = source.time.ToString("n3");
|
||||
|
||||
if(followSeekerToggle.isOn){
|
||||
if(source.isPlaying){
|
||||
cam.position = new Vector3(source.time * AudioAnalyzer.instance.zoomingYMult, cam.position.y, cam.position.z);
|
||||
source.time = startOffset + (Time.time - startTime);
|
||||
}else{
|
||||
source.time = cam.position.x / AudioAnalyzer.instance.zoomingYMult;
|
||||
}
|
||||
}
|
||||
bool anythingInProximity = false;
|
||||
for(int i=0; i < transform.childCount; i++){
|
||||
@@ -80,6 +89,7 @@ public class PrepController : MonoBehaviour
|
||||
// go.transform.position = new Vector3(cam.position.x, 0);
|
||||
go.GetComponent<Marker>().myTime = cam.position.x / AudioAnalyzer.instance.zoomingYMult;
|
||||
|
||||
|
||||
markers.Add(go);
|
||||
}
|
||||
|
||||
@@ -111,5 +121,23 @@ public class PrepController : MonoBehaviour
|
||||
markers.RemoveAt(indexToRemove);
|
||||
Destroy(closestOne);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void OnSeekerDragged(Vector3 newCamPos){
|
||||
if(source.isPlaying){
|
||||
TogglePlay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool playAfterDragEnd = false;
|
||||
public void OnSeekerDown(){
|
||||
playAfterDragEnd=source.isPlaying;
|
||||
}
|
||||
|
||||
public void OnSeekerUp(){
|
||||
if(playAfterDragEnd){
|
||||
TogglePlay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +50,13 @@ public class SaveLoadPrep : MonoBehaviour
|
||||
|
||||
public void Save(){
|
||||
saveLoadData = new SaveLoadData(txtPath.text);
|
||||
List<float> unsortedHits = new List<float>();
|
||||
foreach(GameObject marker in PrepController.markers){
|
||||
saveLoadData.hits.Add(marker.transform.position.x / AudioAnalyzer.instance.zoomingYMult);
|
||||
unsortedHits.Add(marker.transform.position.x / AudioAnalyzer.instance.zoomingYMult);
|
||||
}
|
||||
|
||||
saveLoadData.hits = Helpers.BubbleSort(unsortedHits);
|
||||
|
||||
saveContentPanel.SetActive(true);
|
||||
string fileName = txtPath.text;
|
||||
if(fileName.Contains("/")){
|
||||
|
||||
@@ -7,6 +7,7 @@ public class SeekController : MonoBehaviour, IPointerDownHandler, IPointerUpHand
|
||||
{
|
||||
public Transform cam;
|
||||
public AudioAnalyzer audioAnalyzer;
|
||||
public PrepController controller;
|
||||
public LineRenderer referenceLine;
|
||||
public float startX, endX;
|
||||
public float zoomingSpeed =0.001f;
|
||||
@@ -20,16 +21,18 @@ public class SeekController : MonoBehaviour, IPointerDownHandler, IPointerUpHand
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
Vector3 pointerDelta = eventData.position - pointerDownPos;
|
||||
cam.position = pointerDownCamPos + (new Vector3(pointerDelta.x,0) * 0.035f);
|
||||
if(cam.position.x < startX){
|
||||
cam.position = new Vector3(startX, cam.position.y,-10);
|
||||
Vector3 newCamPos = pointerDownCamPos + (new Vector3(pointerDelta.x,0) * 0.035f);
|
||||
if(newCamPos.x < startX){
|
||||
newCamPos = new Vector3(startX, newCamPos.y,-10);
|
||||
}
|
||||
if(cam.position.x > endX){
|
||||
cam.position = new Vector3(endX, cam.position.y,-10);
|
||||
if(newCamPos.x > endX){
|
||||
newCamPos = new Vector3(endX, newCamPos.y,-10);
|
||||
}
|
||||
if(eventData.position.x > Screen.width / 2f){
|
||||
audioAnalyzer.SetZoomingYMult(pointerDownZoomingYMult + (pointerDelta.y * zoomingSpeed));
|
||||
audioAnalyzer.SetZoomingYMult(pointerDownZoomingYMult + (pointerDelta.y * zoomingSpeed));
|
||||
}
|
||||
controller.OnSeekerDragged(newCamPos);
|
||||
cam.position = newCamPos;
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
@@ -37,11 +40,14 @@ public class SeekController : MonoBehaviour, IPointerDownHandler, IPointerUpHand
|
||||
pointerDownPos = eventData.position;
|
||||
pointerDownCamPos = cam.position;
|
||||
pointerDownZoomingYMult = audioAnalyzer.zoomingYMult;
|
||||
|
||||
controller.OnSeekerDown();
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
pointerDownPos = Vector3.zero;
|
||||
controller.OnSeekerUp();
|
||||
}
|
||||
|
||||
void Awake(){
|
||||
|
||||
43
Assets/Scripts/Prep/TimescaleAdjuster.cs
Normal file
43
Assets/Scripts/Prep/TimescaleAdjuster.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class TimescaleAdjuster : MonoBehaviour
|
||||
{
|
||||
public Button nextBtn;
|
||||
public Button prevBtn;
|
||||
public TMP_Text txt;
|
||||
|
||||
void Start()
|
||||
{
|
||||
nextBtn.onClick.AddListener(IncrementTime);
|
||||
prevBtn.onClick.AddListener(DecrementTime);
|
||||
UpdateText();
|
||||
}
|
||||
|
||||
void IncrementTime(){
|
||||
if(Time.timeScale < 0.25f){
|
||||
Time.timeScale = 0.25f;
|
||||
}else{
|
||||
Time.timeScale += 0.25f;
|
||||
}
|
||||
|
||||
UpdateText();
|
||||
}
|
||||
|
||||
void DecrementTime(){
|
||||
if(Time.timeScale > 0.25f){
|
||||
Time.timeScale -= 0.25f;
|
||||
}else{
|
||||
Time.timeScale = 0.1f;
|
||||
}
|
||||
UpdateText();
|
||||
|
||||
}
|
||||
|
||||
void UpdateText(){
|
||||
txt.text = Time.timeScale.ToString("n2");
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Prep/TimescaleAdjuster.cs.meta
Normal file
11
Assets/Scripts/Prep/TimescaleAdjuster.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78209ab90a9209446921f39c899d1147
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/Utils.meta
Normal file
8
Assets/Scripts/Utils.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6352c794c162583488dc298e2618c079
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
30
Assets/Scripts/Utils/SliderValueText.cs
Normal file
30
Assets/Scripts/Utils/SliderValueText.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[RequireComponent(typeof(TMP_Text))]
|
||||
public class SliderValueText : MonoBehaviour
|
||||
{
|
||||
public Slider slider;
|
||||
|
||||
|
||||
void OnValidate(){
|
||||
if(slider==null){
|
||||
slider = GetComponentInParent<Slider>();
|
||||
}
|
||||
}
|
||||
void Start()
|
||||
{
|
||||
slider.onValueChanged.AddListener(RefreshText);
|
||||
txt= GetComponent<TMP_Text>();
|
||||
RefreshText(slider.value);
|
||||
|
||||
}
|
||||
TMP_Text txt;
|
||||
|
||||
void RefreshText(float value){
|
||||
txt.text = slider.value.ToString("n3");
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Utils/SliderValueText.cs.meta
Normal file
11
Assets/Scripts/Utils/SliderValueText.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffd6249c0d241384ab3caa05bc93e9cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user