mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-13 00:47:36 +02:00
Double Date Balls (#396)
* al l anims done yay * make balls follow paths added FollowPath objects * added 2 grass and changed sky * make balls rotate todo: shadows * complete SuperCurve add dropshadows add weasel hit * make football stop dropshadow when hit * finish animation add scrolling clouds * tint shader * oops * slow down clouds --------- Co-authored-by: ev <85412919+evdial@users.noreply.github.com>
This commit is contained in:
207
Assets/Scripts/Transform/SuperCurveObject.cs
Normal file
207
Assets/Scripts/Transform/SuperCurveObject.cs
Normal file
@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HeavenStudio
|
||||
{
|
||||
public class SuperCurveObject : MonoBehaviour
|
||||
{
|
||||
[SerializeField] protected Vector3 offset;
|
||||
protected Vector3 lastRealPos;
|
||||
protected PathPos currentPathPos;
|
||||
|
||||
[Serializable]
|
||||
public struct PathPos
|
||||
{
|
||||
[SerializeField] public string tag;
|
||||
[SerializeField] public Vector3 pos;
|
||||
[SerializeField] public Transform target;
|
||||
[SerializeField] public float height;
|
||||
[SerializeField] public float duration;
|
||||
[SerializeField] public bool useLastRealPos;
|
||||
[SerializeField] public PathValue[] values;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct Path
|
||||
{
|
||||
[SerializeField] public string name;
|
||||
[SerializeField] public bool preview;
|
||||
[SerializeField] public GameObject anchor;
|
||||
[SerializeField] public PathPos[] positions;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct PathValue
|
||||
{
|
||||
[SerializeField] public string key;
|
||||
[SerializeField] public float value;
|
||||
}
|
||||
|
||||
public static PathPos GetPathPosByTag(Path path, string tag)
|
||||
{
|
||||
foreach (PathPos pos in path.positions)
|
||||
{
|
||||
if (pos.tag == tag)
|
||||
return pos;
|
||||
}
|
||||
return default(PathPos);
|
||||
}
|
||||
|
||||
public static PathPos GetPathPosByTime(Path path, float currentTime, out float posTime, out PathPos nextPos, out PathPos prevPos, out bool pastCurve)
|
||||
{
|
||||
pastCurve = false;
|
||||
PathPos currentPos = path.positions[0];
|
||||
prevPos = path.positions[0];
|
||||
nextPos = path.positions[1];
|
||||
float currentPosTime = 0f;
|
||||
for (int i = 0; i < path.positions.Length - 1; i++)
|
||||
{
|
||||
prevPos = currentPos;
|
||||
currentPos = path.positions[i];
|
||||
nextPos = path.positions[i + 1];
|
||||
if (currentTime >= currentPosTime && currentTime < currentPosTime + currentPos.duration)
|
||||
{
|
||||
posTime = currentPosTime;
|
||||
return currentPos;
|
||||
}
|
||||
if (i + 1 < path.positions.Length - 1)
|
||||
currentPosTime += currentPos.duration;
|
||||
else
|
||||
{
|
||||
pastCurve = true;
|
||||
posTime = currentPosTime;
|
||||
return currentPos;
|
||||
}
|
||||
}
|
||||
nextPos = default(PathPos);
|
||||
prevPos = default(PathPos);
|
||||
posTime = 0f;
|
||||
return default(PathPos);
|
||||
}
|
||||
|
||||
public static PathPos GetPathPosByTime(Path path, float currentTime)
|
||||
{
|
||||
return GetPathPosByTime(path, currentTime, out _, out _, out _, out _);
|
||||
}
|
||||
|
||||
public static float GetPointTimeByTag(Path path, string tag)
|
||||
{
|
||||
float currentTime = 0f;
|
||||
foreach (PathPos pos in path.positions)
|
||||
{
|
||||
if (pos.tag == tag)
|
||||
return currentTime;
|
||||
currentTime += pos.duration;
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
|
||||
protected virtual void UpdateLastRealPos()
|
||||
{
|
||||
lastRealPos = transform.position;
|
||||
}
|
||||
|
||||
protected virtual float GetPathValue(string key)
|
||||
{
|
||||
if (currentPathPos.values == null)
|
||||
return 0f;
|
||||
foreach (PathValue value in currentPathPos.values)
|
||||
{
|
||||
if (value.key == key)
|
||||
{
|
||||
return value.value;
|
||||
}
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetPathPositionFromBeat(Path path, float currentTime, out float heightOffset, float startTime = 0f)
|
||||
{
|
||||
heightOffset = 0f;
|
||||
Vector3 anchorPos = Vector3.zero;
|
||||
if (path.anchor != null)
|
||||
anchorPos = path.anchor.transform.position;
|
||||
if (path.positions.Length < 2)
|
||||
return transform.position;
|
||||
|
||||
PathPos nextPos = path.positions[0];
|
||||
float currentPosTime = 0f;
|
||||
PathPos currentPos = GetPathPosByTime(path, currentTime - startTime, out currentPosTime, out nextPos, out _, out _);
|
||||
currentPathPos = currentPos;
|
||||
if (currentPos.pos == null || nextPos.pos == null)
|
||||
return transform.position;
|
||||
|
||||
Vector3 startPos = currentPos.pos;
|
||||
if (currentPos.useLastRealPos)
|
||||
startPos = lastRealPos;
|
||||
else if (currentPos.target != null)
|
||||
startPos = currentPos.target.position;
|
||||
Vector3 endPos = nextPos.pos;
|
||||
if (nextPos.target != null)
|
||||
endPos = nextPos.target.position;
|
||||
|
||||
float time = (currentTime - startTime - currentPosTime) / currentPos.duration;
|
||||
Vector3 pos = Vector3.LerpUnclamped(startPos, endPos, time);
|
||||
float yMul = time * 2f - 1f;
|
||||
float yWeight = -(yMul * yMul) + 1f;
|
||||
heightOffset = yWeight * currentPos.height;
|
||||
pos.y += heightOffset;
|
||||
return pos + offset + anchorPos;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetPathPositionFromBeat(Path path, float currentTime, float startTime = 0f)
|
||||
{
|
||||
return GetPathPositionFromBeat(path, currentTime, out _, startTime);
|
||||
}
|
||||
|
||||
// Editor gizmo to draw trajectories
|
||||
const float TRAJECTORY_STEP = 0.1f;
|
||||
public virtual void DrawEditorGizmo(Path path)
|
||||
{
|
||||
if (path.positions.Length > 1)
|
||||
{
|
||||
Vector3 anchorPos = Vector3.zero;
|
||||
if (path.anchor != null)
|
||||
anchorPos = path.anchor.transform.position;
|
||||
for (int i = 0; i < path.positions.Length - 1; i++)
|
||||
{
|
||||
PathPos pos = path.positions[i];
|
||||
PathPos nextPos = path.positions[i + 1];
|
||||
if (pos.pos == null || nextPos.pos == null)
|
||||
return;
|
||||
|
||||
Vector3 startPos = pos.pos;
|
||||
if (pos.target != null)
|
||||
startPos = pos.target.position;
|
||||
Vector3 endPos = nextPos.pos;
|
||||
if (nextPos.target != null)
|
||||
endPos = nextPos.target.position;
|
||||
|
||||
// draw a curve between the two points using the path height
|
||||
List<Vector3> points = new List<Vector3>();
|
||||
for (float t = 0; t < 1; t += TRAJECTORY_STEP)
|
||||
{
|
||||
float yMul = t * 2f - 1f;
|
||||
float yWeight = -(yMul * yMul) + 1f;
|
||||
Vector3 p = Vector3.LerpUnclamped(startPos, endPos, t);
|
||||
p.y += yWeight * pos.height;
|
||||
points.Add(p + anchorPos);
|
||||
}
|
||||
|
||||
points.Add(endPos + anchorPos);
|
||||
|
||||
for (int j = 0; j < points.Count - 1; j++)
|
||||
{
|
||||
Gizmos.color = Color.blue;
|
||||
Gizmos.DrawLine(points[j], points[j + 1]);
|
||||
}
|
||||
|
||||
Gizmos.DrawSphere(startPos, 0.1f);
|
||||
Gizmos.DrawSphere(endPos, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user