ball testing
This commit is contained in:
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:
|
||||
Reference in New Issue
Block a user