ball testing
This commit is contained in:
@@ -23,7 +23,7 @@ public class CamFollower : MonoBehaviour
|
||||
{
|
||||
}
|
||||
|
||||
void LateUpdate(){
|
||||
void FixedUpdate(){
|
||||
transform.position = Vector3.Lerp(transform.position, target.position + offset, speed);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,36 +3,42 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEditor.SearchService;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.U2D;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class Mover : MonoBehaviour
|
||||
{
|
||||
[Header("Prep Mode stuff")]
|
||||
public GameObject prepModePanel;
|
||||
public TMP_Text txtProgress;
|
||||
public Button btnBackToPrep;
|
||||
public Button btnSave;
|
||||
public Button btnRun;
|
||||
|
||||
|
||||
[Header("End of prep mode stuff")]
|
||||
public Vector3 movingSpeed;
|
||||
public float loudBoost = 1f;
|
||||
public float momentumBoost = 1f;
|
||||
|
||||
public AudioSplitter splitter;
|
||||
|
||||
public GameObject prefab;
|
||||
|
||||
|
||||
float prev_loud = 0;
|
||||
|
||||
|
||||
public float loudnessThreshold = 0.08f;
|
||||
public float yieldTime = 0.2f;
|
||||
float LastTime;
|
||||
public SpriteShapeController botShape;
|
||||
public SpriteShapeController topShape;
|
||||
public LineRenderer botLineRenderer, topLineRenderer;
|
||||
public DrawShape botDrawer;
|
||||
public DrawShape topDrawer;
|
||||
public GameObject txtDebug;
|
||||
public bool isDebug = false;
|
||||
public Light2D glowLight;
|
||||
public Transform scalingObject;
|
||||
public float scalingEffect = 0.1f;
|
||||
public float scalingResetLerp = 0.05f;
|
||||
Vector3 defaultSize;
|
||||
public float glowReductionSpeed = 2f;
|
||||
public float fovZoomingSpeed = 0.5f;
|
||||
|
||||
@@ -48,20 +54,31 @@ public class Mover : MonoBehaviour
|
||||
|
||||
float defFOV;
|
||||
|
||||
public AudioSource source;
|
||||
|
||||
List<float> recordedTimes = null;
|
||||
List<float> pastTimes = null;
|
||||
|
||||
float startedTime =0;
|
||||
private void Awake()
|
||||
{
|
||||
startedTime = Time.time;
|
||||
defaultSize = scalingObject.localScale;
|
||||
defFOV = Camera.main.orthographicSize;
|
||||
if (!playReplay) { themeMan.Randomize(); }
|
||||
|
||||
if(PrepConnector.saveLoadData != null){
|
||||
recordedTimes = PrepConnector.saveLoadData.hits;
|
||||
}
|
||||
|
||||
playReplay = PlayerPrefs.HasKey("prep_data");
|
||||
if(playReplay){
|
||||
recordedStepsJson = PlayerPrefs.GetString("prep_data");
|
||||
}
|
||||
|
||||
Screen.orientation = ScreenOrientation.Portrait;
|
||||
}
|
||||
|
||||
public List<float> allHits = new List<float>();
|
||||
private void Start()
|
||||
{
|
||||
// Application.targetFrameRate = 164;
|
||||
@@ -69,9 +86,41 @@ public class Mover : MonoBehaviour
|
||||
{
|
||||
recordedSteps = JsonConvert.DeserializeObject<List<RecorderStep>>(recordedStepsJson);
|
||||
GenerateRecordedPlatform();
|
||||
}else{
|
||||
//Show prep mode
|
||||
prepModePanel.SetActive(true);
|
||||
|
||||
btnBackToPrep.onClick.AddListener(()=>{ SceneManager.LoadScene("prep"); });
|
||||
btnRun.onClick.AddListener(OnRun);
|
||||
btnSave.onClick.AddListener(OnSaveBtn);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRun(){
|
||||
PlayerPrefs.SetString("prep_data", currentStepsJson);
|
||||
PlayerPrefs.Save();
|
||||
|
||||
SceneManager.LoadScene("Runner");
|
||||
}
|
||||
|
||||
void OnSaveBtn(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
int totalHits = 0;
|
||||
public void SetHits(List<float> hits){
|
||||
allHits.AddRange(hits);
|
||||
float lastTime = hits[hits.Count-1];
|
||||
for(int i=1; i < 3; i++){
|
||||
foreach(float hit in hits){
|
||||
allHits.Add(hit + lastTime*i);
|
||||
}
|
||||
}
|
||||
|
||||
totalHits = hits.Count * 3;
|
||||
}
|
||||
|
||||
Vector3 LastPos;
|
||||
|
||||
float movingSpeedMultiplier = 1;
|
||||
@@ -114,6 +163,8 @@ public class Mover : MonoBehaviour
|
||||
}
|
||||
void FixedUpdate()
|
||||
{
|
||||
time=Time.time - startedTime;
|
||||
|
||||
movingSpeedMultiplier = Mathf.Lerp(movingSpeedMultiplier, 1, Time.deltaTime * 2);
|
||||
float boostedX = movingSpeed.x * Mathf.Clamp((movingSpeedMultiplier * 1),0,1.25f);
|
||||
float boostedY = movingSpeed.y * (movingSpeedMultiplier * 1f);
|
||||
@@ -258,35 +309,24 @@ public class Mover : MonoBehaviour
|
||||
|
||||
float tensionBuildup = 0f;
|
||||
float endTimer = 0;
|
||||
|
||||
public float time=0;
|
||||
void PreWork()
|
||||
{
|
||||
float loudness_delta = splitter.loudness - prev_loud;
|
||||
bool notTooShort = (Time.time - LastTime) > yieldTime;
|
||||
bool oldLoudLogic = splitter.loudness > loudnessThreshold && prev_loud < loudnessThreshold;
|
||||
bool newLoudLogic = (loudness_delta > loudnessThreshold && notTooShort);
|
||||
bool notTooShort = (time - LastTime) > yieldTime;
|
||||
|
||||
bool prepLogic = false;
|
||||
if(pastTimes.Count <= 0){
|
||||
if(endTimer < 10f){
|
||||
endTimer+=Time.deltaTime;
|
||||
}else{
|
||||
SceneManager.LoadScene("prep");
|
||||
endTimer=0;
|
||||
}
|
||||
}else{
|
||||
if(pastTimes[0] < source.time){
|
||||
prepLogic = true;
|
||||
pastTimes.RemoveAt(0);
|
||||
}
|
||||
bool newPrepLogic = allHits[0] <time;
|
||||
if(newPrepLogic){
|
||||
allHits.RemoveAt(0);
|
||||
}
|
||||
|
||||
|
||||
bool newDynamicLogic = recordedTimes == null ? oldLoudLogic : prepLogic ;
|
||||
txtProgress.text = $"{allHits.Count} left of {totalHits}. One cycle : {(totalHits/3f).ToString("n0")}";
|
||||
// bool newDynamicLogic = recordedTimes == null ? oldLoudLogic : prepLogic ;
|
||||
tensionBuildup += Time.deltaTime;
|
||||
|
||||
if (newDynamicLogic || Input.GetKeyDown(KeyCode.Space))
|
||||
if (newPrepLogic || Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
Debug.Log(LastTime - Time.time);
|
||||
Debug.Log(LastTime - time);
|
||||
//Instantiate(prefab, transform.position, Quaternion.identity);
|
||||
int random = Random.Range(0, 3);
|
||||
bool flippedX = LastPos.x - transform.position.x > LastPos.y - transform.position.y;
|
||||
@@ -294,39 +334,41 @@ public class Mover : MonoBehaviour
|
||||
if (flippedX)
|
||||
{
|
||||
movingSpeed.x = -movingSpeed.x;
|
||||
Instantiate(prefab, transform.position + new Vector3(-1 / 5f, 0), Quaternion.Euler(new Vector3(0, 0, 0))).transform.GetComponentInChildren<TextMesh>().text = loudness_delta.ToString("n3");
|
||||
}
|
||||
else
|
||||
{
|
||||
movingSpeed.y = -movingSpeed.y;
|
||||
Instantiate(prefab, transform.position + new Vector3(0, -1 / 5f), Quaternion.Euler(new Vector3(0, 0, 90))).transform.GetComponentInChildren<TextMesh>().text = loudness_delta.ToString("n3"); ;
|
||||
|
||||
}
|
||||
movingSpeedMultiplier += (loudness_delta * loudBoost) / loudnessThreshold;
|
||||
movingSpeedMultiplier += (loudBoost) / loudnessThreshold;
|
||||
movingSpeedMultiplier += tensionBuildup * momentumBoost;
|
||||
|
||||
LastTime = Time.time;
|
||||
LastTime = time;
|
||||
currentSteps.Add(new RecorderStep(LastTime, movingSpeed, movingSpeedMultiplier, transform.position));
|
||||
currentStepsJson = JsonConvert.SerializeObject(currentSteps);
|
||||
LastPos = transform.position;
|
||||
|
||||
tensionBuildup = 0;
|
||||
}
|
||||
prev_loud = splitter.loudness;
|
||||
|
||||
}
|
||||
int index = 0;
|
||||
|
||||
void PostWork()
|
||||
{
|
||||
scalingObject.localScale = Vector3.Lerp(scalingObject.localScale, defaultSize, scalingResetLerp);
|
||||
|
||||
if(recordedSteps.Count <= 0) { return; }
|
||||
tensionBuildup += Time.deltaTime;
|
||||
if (Time.time >= recordedSteps[0].time)
|
||||
if (time >= recordedSteps[0].time)
|
||||
{
|
||||
//Time to act
|
||||
movingSpeed = recordedSteps[0].movingSpeed;
|
||||
movingSpeedMultiplier = recordedSteps[0].movingSpeedMultiplier;
|
||||
musicSourceToSync.time = (float)recordedSteps[0].time;
|
||||
musicSourceToSync.time = (float)recordedSteps[0].time % (musicSourceToSync.clip.length);
|
||||
if(!musicSourceToSync.isPlaying){
|
||||
musicSourceToSync.Play();
|
||||
}
|
||||
|
||||
recordedSteps.RemoveAt(0);
|
||||
|
||||
@@ -361,7 +403,7 @@ public class Mover : MonoBehaviour
|
||||
|
||||
themeMan.Randomize(movingSpeedMultiplier /3f);
|
||||
targetRotation *= Quaternion.Euler(0, 0, -90);
|
||||
|
||||
scalingObject.localScale -= (Vector3.one * scalingEffect);
|
||||
// themeMan.SetColor(new Color(Random.Range(0f,1f), Random.Range(0f,1f),Random.Range(0f,1f)));
|
||||
/*themeMan.r = Random.Range(0f, 1f);
|
||||
themeMan.g = Random.Range(0f, 1f);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class MoverSettingsManager : MonoBehaviour
|
||||
{
|
||||
public Slider xSlider,ySlider;
|
||||
public Button btnClose,btnSave,btnRestart;
|
||||
public Button btnClose,btnBackToPrep,btnRestart;
|
||||
public PredictiveMover mover;
|
||||
|
||||
public GameObject panel;
|
||||
@@ -14,11 +14,10 @@ public class MoverSettingsManager : MonoBehaviour
|
||||
|
||||
void Start()
|
||||
{
|
||||
xSlider.onValueChanged.AddListener(OnSettingsChanged);
|
||||
ySlider.onValueChanged.AddListener(OnSettingsChanged);
|
||||
|
||||
btnClose.onClick.AddListener(HideSettings);
|
||||
btnRestart.onClick.AddListener(Restart);
|
||||
btnBackToPrep.onClick.AddListener(()=>{SceneManager.LoadScene("prep");});
|
||||
m_onSettingsChanged();
|
||||
}
|
||||
|
||||
@@ -32,9 +31,6 @@ public class MoverSettingsManager : MonoBehaviour
|
||||
}
|
||||
|
||||
void m_onSettingsChanged(){
|
||||
mover.multipliers.x = xSlider.value;
|
||||
mover.multipliers.y = ySlider.value;
|
||||
|
||||
mover.RegenerateLines();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using UnityEngine.EventSystems;
|
||||
public class MoverSettingsPanel : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
|
||||
float touchdownTimer =0f;
|
||||
public float touchdownTimer =0f;
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
touchdownTimer =0f;
|
||||
@@ -14,7 +14,7 @@ public class MoverSettingsPanel : MonoBehaviour, IPointerDownHandler, IPointerUp
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
if(touchdownTimer > 4){
|
||||
if(touchdownTimer > 2){
|
||||
settingsPanel.SetActive(true);
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ public class MoverSettingsPanel : MonoBehaviour, IPointerDownHandler, IPointerUp
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(touchdownTimer < 5f){
|
||||
if(touchdownTimer < 3f){
|
||||
touchdownTimer +=Time.deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,17 +38,20 @@ public class PredictiveMover : MonoBehaviour
|
||||
Restart();
|
||||
}
|
||||
|
||||
|
||||
float playbackTime;
|
||||
void FixedUpdate(){
|
||||
// RegenerateLines();
|
||||
objectToMove.transform.position = Vector3.Lerp(objectToMove.transform.position,GetPositionAtTime(source.time + audioOffset),0.5f);
|
||||
CamFollower.instance.UpdateFrame();
|
||||
source.time = playbackTime;
|
||||
playbackTime+=Time.deltaTime;
|
||||
}
|
||||
|
||||
public void Restart(){
|
||||
source.time =0;
|
||||
playbackTime=0;
|
||||
source.Play();
|
||||
|
||||
|
||||
RegenerateLines();
|
||||
List<Vector3> botPoints = new List<Vector3>();
|
||||
List<Vector3> topPoints = new List<Vector3>();
|
||||
|
||||
19
Assets/Scripts/Mover/SaveLoadMover.cs
Normal file
19
Assets/Scripts/Mover/SaveLoadMover.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class SaveLoadMover : MonoBehaviour
|
||||
{
|
||||
public Mover mover;
|
||||
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Mover/SaveLoadMover.cs.meta
Normal file
11
Assets/Scripts/Mover/SaveLoadMover.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2b99dc11aa746e4cabb4b9fad122746
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -7,7 +7,8 @@ using UnityEngine.Networking;
|
||||
public class LoadFromPrep : MonoBehaviour
|
||||
{
|
||||
public AudioSource source;
|
||||
public PredictiveMover mover;
|
||||
public Mover mover;
|
||||
public List<float> allHits;
|
||||
|
||||
void Awake(){
|
||||
if(PrepConnector.saveLoadData == null){
|
||||
@@ -19,7 +20,8 @@ public class LoadFromPrep : MonoBehaviour
|
||||
void Start(){
|
||||
if(PrepConnector.saveLoadData != null){
|
||||
StartCoroutine(LoadAudioCoroutine(PrepConnector.saveLoadData.musicFile));
|
||||
mover.allHits = PrepConnector.saveLoadData.hits;
|
||||
allHits = PrepConnector.saveLoadData.hits;
|
||||
mover.SetHits(allHits);
|
||||
PlayerPrefs.SetString("saveData", JsonUtility.ToJson(PrepConnector.saveLoadData));
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
@@ -29,7 +31,7 @@ public class LoadFromPrep : MonoBehaviour
|
||||
{
|
||||
string filePath = Path.Combine(Application.persistentDataPath, fileName);
|
||||
string url = "file://" + filePath;
|
||||
|
||||
Debug.Log("Loading file from " + url);
|
||||
UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, AudioType.WAV); // Use AudioType.MPEG for MP3 files
|
||||
yield return www.SendWebRequest();
|
||||
|
||||
|
||||
@@ -9,8 +9,11 @@ public class PrepConnector : MonoBehaviour
|
||||
public static SaveLoadData saveLoadData;
|
||||
|
||||
public void LoadPlay(){
|
||||
Time.timeScale = 1f;
|
||||
SaveLoadPrep.instance.Save();
|
||||
saveLoadData = SaveLoadPrep.instance.saveLoadData;
|
||||
PlayerPrefs.DeleteKey("prep_data");
|
||||
PlayerPrefs.Save();
|
||||
SceneManager.LoadScene("Runner");
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ public class PrepController : MonoBehaviour
|
||||
public Button removePinBtn;
|
||||
public Toggle followSeekerToggle;
|
||||
public TMP_Text playbackTimeTxt;
|
||||
public TMP_Text hitCountTxt;
|
||||
public static List<GameObject> markers = new List<GameObject>();
|
||||
|
||||
public static void Reset(){
|
||||
@@ -30,10 +31,38 @@ public class PrepController : MonoBehaviour
|
||||
removePinBtn.onClick.AddListener(RemoveMarker);
|
||||
instance = this;
|
||||
|
||||
|
||||
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if(Input.GetKeyDown(KeyCode.RightArrow)){
|
||||
AddMarker();
|
||||
}
|
||||
if(Input.GetKeyDown(KeyCode.LeftArrow)){
|
||||
|
||||
float lastTime=0f;
|
||||
for(int i=0; i < markers.Count; i++){
|
||||
if(markers[i].GetComponent<Marker>().myTime < source.time){
|
||||
lastTime = markers[i].GetComponent<Marker>().myTime;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
Vector3 newCamPos = new Vector3(lastTime * AudioAnalyzer.instance.zoomingYMult, cam.position.y, cam.position.z);
|
||||
if(source.isPlaying){
|
||||
TogglePlay();
|
||||
cam.position = newCamPos;
|
||||
TogglePlay();
|
||||
}else{
|
||||
cam.position = newCamPos;
|
||||
}
|
||||
|
||||
if(Input.GetKey(KeyCode.RightShift)){
|
||||
RemoveMarker();
|
||||
}
|
||||
|
||||
}
|
||||
hitCountTxt.text = markers.Count.ToString();
|
||||
playbackTimeTxt.text = source.time.ToString("n3");
|
||||
|
||||
if(followSeekerToggle.isOn){
|
||||
|
||||
@@ -25,6 +25,17 @@ public class SaveLoadPrep : MonoBehaviour
|
||||
saveBtn.onClick.AddListener(Save);
|
||||
loadBtn.onClick.AddListener(ShowLoadContent);
|
||||
instance =this;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Start(){
|
||||
if(PrepConnector.saveLoadData != null){
|
||||
saveLoadData = PrepConnector.saveLoadData;
|
||||
Debug.Log("Loading music file at " + saveLoadData.musicFile);
|
||||
MusicLoader.instance.OnFileSelected(saveLoadData.musicFile, true);
|
||||
PrepController.instance.SetMarkers(saveLoadData.hits);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class TimescaleAdjuster : MonoBehaviour
|
||||
if(Time.timeScale > 0.25f){
|
||||
Time.timeScale -= 0.25f;
|
||||
}else{
|
||||
Time.timeScale = 0.1f;
|
||||
Time.timeScale *= 0.5f;
|
||||
}
|
||||
UpdateText();
|
||||
|
||||
|
||||
154
Assets/Scripts/ProtoTyping/BallPathTest.cs
Normal file
154
Assets/Scripts/ProtoTyping/BallPathTest.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BallPathTest : MonoBehaviour
|
||||
{
|
||||
public AudioSource audioToSync;
|
||||
public List<float> allHits = new List<float>();
|
||||
public LineRenderer line;
|
||||
public Transform mover;
|
||||
public float horizontalSpeed = 1f;
|
||||
public float gravity = -9f;
|
||||
public float gravityWhenUpwardMult = 1f;
|
||||
public float maxFallSpeed = 10;
|
||||
public AnimationCurve bouncingEfficiencyGraph = new AnimationCurve();
|
||||
// public float bouncingEfficiency =0.4f;
|
||||
public float changeDirCloseThresh = 0.1f;
|
||||
public Vector2 velocity;
|
||||
public bool simulate = false;
|
||||
|
||||
public GameObject bouncerPrefab;
|
||||
public Transform bouncerParent;
|
||||
|
||||
void OnValidate()
|
||||
{
|
||||
if (simulate)
|
||||
{
|
||||
Simulate();
|
||||
simulate = false;
|
||||
}
|
||||
}
|
||||
float timer = 0;
|
||||
public List<float> hitsCache = new List<float>();
|
||||
List<Vector3> pointsHistory = new List<Vector3>();
|
||||
List<BounceData> hitPointsHistory = new List<BounceData>();
|
||||
|
||||
|
||||
void Start()
|
||||
{
|
||||
Reset(Time.time);
|
||||
}
|
||||
|
||||
void Reset(float time){
|
||||
velocity = new Vector2(horizontalSpeed, 0);
|
||||
mover.transform.position = Vector2.zero;
|
||||
hitsCache = new List<float>();
|
||||
hitsCache.AddRange(allHits);
|
||||
pointsHistory= new List<Vector3>();
|
||||
hitPointsHistory= new List<BounceData>();
|
||||
prevTime=time;
|
||||
timer =0;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
ManualUpdate(Time.time);
|
||||
}
|
||||
|
||||
float prevTime;
|
||||
bool ManualUpdate(float time){
|
||||
float dt = time - prevTime;
|
||||
prevTime = time;
|
||||
timer += dt;
|
||||
|
||||
audioToSync.time = time;
|
||||
|
||||
if(hitsCache.Count <= 1){return true;}
|
||||
|
||||
velocity += new Vector2(0, gravity*dt * (velocity.y > 0 ? gravityWhenUpwardMult : 1));
|
||||
|
||||
if (timer > hitsCache[0])
|
||||
{
|
||||
float timeToNextHit = hitsCache[1]-hitsCache[0];//(hitsCache.Count >1)?1:0
|
||||
Debug.Log($"hit: {timeToNextHit}, velocity : {velocity}");
|
||||
BounceData bounceData = new BounceData();
|
||||
bounceData.point = mover.position;
|
||||
bounceData.prevVelocity = velocity;
|
||||
//Bounce
|
||||
hitsCache.RemoveAt(0);
|
||||
bool changeDir= timeToNextHit < changeDirCloseThresh;
|
||||
float bouncingEfficiency = bouncingEfficiencyGraph.Evaluate(Mathf.Abs(velocity.y)/maxFallSpeed);
|
||||
velocity = new Vector2(velocity.x * (changeDir ? -1 : 1), velocity.y * -bouncingEfficiency * (changeDir ? 0:1));
|
||||
bounceData.newVelocity = velocity;
|
||||
|
||||
hitPointsHistory.Add(bounceData);
|
||||
}
|
||||
|
||||
velocity = new Vector2(velocity.x, velocity.y < -maxFallSpeed ? -maxFallSpeed : velocity.y);
|
||||
|
||||
mover.transform.position += (Vector3)velocity * dt;
|
||||
|
||||
pointsHistory.Add(mover.transform.position);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Simulate(){
|
||||
float fps = 60;
|
||||
float totalLength = allHits[allHits.Count-1];
|
||||
float curFrame =0;
|
||||
Reset(0);
|
||||
|
||||
//Purge existing bouncing plats
|
||||
bouncerParent.PurgeChildrenEdit();
|
||||
|
||||
int totalFrames = Mathf.CeilToInt(totalLength * fps);
|
||||
while(curFrame < totalFrames){
|
||||
if(ManualUpdate(curFrame/fps)){
|
||||
break;
|
||||
}
|
||||
curFrame++;
|
||||
}
|
||||
|
||||
line.positionCount = pointsHistory.Count;
|
||||
line.SetPositions(pointsHistory.ToArray());
|
||||
|
||||
foreach(BounceData data in hitPointsHistory){
|
||||
GameObject newPlat = Instantiate(bouncerPrefab, bouncerParent);
|
||||
newPlat.transform.position = data.point;
|
||||
newPlat.transform.rotation = Quaternion.AngleAxis(CalculateWallAngle(data.prevVelocity,data.newVelocity), Vector3.forward);
|
||||
}
|
||||
}
|
||||
|
||||
public static float CalculateWallAngle(Vector2 previousVelocity, Vector2 newVelocity)
|
||||
{
|
||||
// Normalize velocities to ignore the speed and just focus on direction
|
||||
Vector2 previousDir = previousVelocity.normalized;
|
||||
Vector2 newDir = newVelocity.normalized;
|
||||
|
||||
// The reflection vector is the difference between the two normalized velocities
|
||||
Vector2 reflectionVector = newDir - previousDir;
|
||||
|
||||
// Calculate the wall normal using reflection law (midpoint of incoming and outgoing angles)
|
||||
Vector2 wallNormal = Vector2.Perpendicular(reflectionVector).normalized;
|
||||
|
||||
// Calculate the angle of the wall from the wall's normal
|
||||
float wallAngle = Mathf.Atan2(wallNormal.y, wallNormal.x) * Mathf.Rad2Deg;
|
||||
|
||||
// Make sure the angle is between 0 and 360 degrees
|
||||
if (wallAngle < 0) wallAngle += 360;
|
||||
|
||||
return wallAngle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public struct BounceData{
|
||||
public Vector3 point;
|
||||
public Vector2 prevVelocity;
|
||||
public Vector2 newVelocity;
|
||||
}
|
||||
11
Assets/Scripts/ProtoTyping/BallPathTest.cs.meta
Normal file
11
Assets/Scripts/ProtoTyping/BallPathTest.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c6b1703eac7163458faaf39e26ad393
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
36
Assets/Scripts/Utils/Extensions.cs
Normal file
36
Assets/Scripts/Utils/Extensions.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
|
||||
public static class CustomExtensions{
|
||||
public static void PurgeChildren(this Transform parent){
|
||||
foreach(Transform child in parent.GetComponentsInChildren<Transform>()){
|
||||
if(child == parent){continue;}
|
||||
|
||||
SmartDestroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public static void PurgeChildrenEdit(this Transform parent){
|
||||
for (int i = parent.transform.childCount; i > 0; --i)
|
||||
GameObject.DestroyImmediate(parent.GetChild(0).gameObject);
|
||||
}
|
||||
|
||||
public static void SmartDestroy(UnityEngine.Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
GameObject.DestroyImmediate(obj);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
GameObject.Destroy(obj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
Assets/Scripts/Utils/Extensions.cs.meta
Normal file
11
Assets/Scripts/Utils/Extensions.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 677d3c8524a47b1498d6d5d4013fbc43
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user