feat: polish VR gameplay and sync tools
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace VRBeats
|
||||
{
|
||||
public class SliceTrailEffect : MonoBehaviour
|
||||
{
|
||||
private const float Lifetime = 0.24f;
|
||||
private const int PointCount = 7;
|
||||
|
||||
private LineRenderer glowLine = null;
|
||||
private LineRenderer coreLine = null;
|
||||
private Vector3 center = Vector3.zero;
|
||||
private Vector3 tangent = Vector3.right;
|
||||
private Vector3 lift = Vector3.up;
|
||||
private Color effectColor = Color.cyan;
|
||||
|
||||
public static void Spawn(Vector3 position, Vector3 hitDir, Vector3 saberUp, Color color)
|
||||
{
|
||||
GameObject effectObject = new GameObject("SliceTrailEffect");
|
||||
SliceTrailEffect effect = effectObject.AddComponent<SliceTrailEffect>();
|
||||
effect.Construct(position, hitDir, saberUp, color);
|
||||
}
|
||||
|
||||
private void Construct(Vector3 position, Vector3 hitDir, Vector3 saberUp, Color color)
|
||||
{
|
||||
center = position;
|
||||
transform.position = position;
|
||||
effectColor = NormalizeColor(color);
|
||||
|
||||
tangent = saberUp.sqrMagnitude > 0.001f ? saberUp.normalized : Vector3.right;
|
||||
lift = hitDir.sqrMagnitude > 0.001f ? hitDir.normalized : Vector3.up;
|
||||
|
||||
glowLine = CreateLine("Glow", 0.16f, 0.45f);
|
||||
coreLine = CreateLine("Core", 0.045f, 0.95f);
|
||||
StartCoroutine(Animate());
|
||||
}
|
||||
|
||||
private LineRenderer CreateLine(string name, float width, float alpha)
|
||||
{
|
||||
GameObject lineObject = new GameObject(name);
|
||||
lineObject.transform.SetParent(transform, false);
|
||||
|
||||
LineRenderer line = lineObject.AddComponent<LineRenderer>();
|
||||
line.positionCount = PointCount;
|
||||
line.useWorldSpace = true;
|
||||
line.alignment = LineAlignment.View;
|
||||
line.textureMode = LineTextureMode.Stretch;
|
||||
line.numCornerVertices = 8;
|
||||
line.numCapVertices = 8;
|
||||
line.shadowCastingMode = ShadowCastingMode.Off;
|
||||
line.receiveShadows = false;
|
||||
line.material = CreateMaterial();
|
||||
line.widthMultiplier = width;
|
||||
ApplyGradient(line, alpha);
|
||||
return line;
|
||||
}
|
||||
|
||||
private IEnumerator Animate()
|
||||
{
|
||||
float age = 0.0f;
|
||||
while (age < Lifetime)
|
||||
{
|
||||
float t = age / Lifetime;
|
||||
float length = Mathf.Lerp(0.72f, 1.45f, t);
|
||||
float bend = Mathf.Lerp(0.12f, 0.34f, t);
|
||||
float alpha = 1.0f - t;
|
||||
|
||||
UpdateLine(glowLine, length, bend, alpha * 0.45f);
|
||||
UpdateLine(coreLine, length * 0.88f, bend * 0.55f, alpha * 0.95f);
|
||||
|
||||
age += Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void UpdateLine(LineRenderer line, float length, float bend, float alpha)
|
||||
{
|
||||
if (line == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < PointCount; i++)
|
||||
{
|
||||
float normalized = PointCount <= 1 ? 0.0f : (float)i / (PointCount - 1);
|
||||
float offset = normalized - 0.5f;
|
||||
float curve = Mathf.Sin(normalized * Mathf.PI) * bend;
|
||||
line.SetPosition(i, center + tangent * (offset * length) + lift * curve);
|
||||
}
|
||||
|
||||
ApplyGradient(line, alpha);
|
||||
}
|
||||
|
||||
private static Material CreateMaterial()
|
||||
{
|
||||
Shader shader = Shader.Find("Sprites/Default");
|
||||
if (shader == null)
|
||||
shader = Shader.Find("Unlit/Transparent");
|
||||
|
||||
Material material = new Material(shader);
|
||||
material.name = "Runtime Slice Trail";
|
||||
return material;
|
||||
}
|
||||
|
||||
private void ApplyGradient(LineRenderer line, float alpha)
|
||||
{
|
||||
Color start = new Color(effectColor.r, effectColor.g, effectColor.b, 0.0f);
|
||||
Color mid = new Color(effectColor.r, effectColor.g, effectColor.b, alpha);
|
||||
Color end = new Color(effectColor.r, effectColor.g, effectColor.b, 0.0f);
|
||||
|
||||
Gradient gradient = new Gradient();
|
||||
gradient.SetKeys(
|
||||
new[]
|
||||
{
|
||||
new GradientColorKey(start, 0.0f),
|
||||
new GradientColorKey(mid, 0.5f),
|
||||
new GradientColorKey(end, 1.0f),
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new GradientAlphaKey(0.0f, 0.0f),
|
||||
new GradientAlphaKey(alpha, 0.5f),
|
||||
new GradientAlphaKey(0.0f, 1.0f),
|
||||
});
|
||||
line.colorGradient = gradient;
|
||||
}
|
||||
|
||||
private static Color NormalizeColor(Color color)
|
||||
{
|
||||
float max = Mathf.Max(color.r, Mathf.Max(color.g, color.b));
|
||||
if (max > 1.0f)
|
||||
color /= max;
|
||||
|
||||
color.a = 1.0f;
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user