Add generic animatable class and add smooth curves

master v0.92-Preview-455
D4VID 3 months ago
parent da60751b32
commit 8154b7e676

@ -1,7 +1,7 @@
ID: D4VID_CameraRoll
Name: CameraRoll
Author: D4VID
Version: 0.3.0
Version: 0.4.0
Priority: 0
ClientOnly: true
Dependencies:

@ -37,7 +37,6 @@ namespace CameraRoll.Client {
/// Called when the game transitions into this game state i.e. after pressing the configured keybinding
/// </summary>
public override void OnEnter() {
CameraRollClientMod.Logger.Info("CameraRollGameState enter");
CameraRollTool.OnEnter();
}
@ -64,7 +63,6 @@ namespace CameraRoll.Client {
/// Called when the game transitions away from this game state i.e. after pressing the back keybinding
/// </summary>
public override void OnExit() {
CameraRollClientMod.Logger.Info("CameraRollGameState exit");
}
}
}

@ -0,0 +1,18 @@
using System.Collections.Generic;
using UnityEngine;
namespace CameraRoll.Client.Tool {
public abstract class Animatable {
protected readonly List<GameObject> PathPoints;
protected Animatable(List<GameObject> pathPoints) {
PathPoints = pathPoints;
}
public abstract void Animate(ref int pointIndex, Camera cam);
public abstract void Reset();
protected Vector3 GetPos(int index) => PathPoints[index].transform.position;
protected Quaternion GetRot(int index) => PathPoints[index].transform.rotation;
}
}

@ -31,12 +31,8 @@ namespace CameraRoll.Client.Tool {
/// </summary>
private static int _pointIndex;
/// <summary>
/// Progress of the linear interpolation (0.0f - 1.0f)
/// </summary>
private static float _interpolationState;
private static readonly List<GameObject> PathPoints = new List<GameObject>();
private static readonly List<Animatable> Animations = new List<Animatable>();
public static void Init(ILogicLogger logger) {
_logger = logger;
@ -50,7 +46,6 @@ namespace CameraRoll.Client.Tool {
}
public static void PlacePoint() {
_logger.Info("PlacePoint");
GameObject point = new GameObject($"PathPoint #{PathPoints.Count}") {
transform = {
position = _cam.transform.position,
@ -63,6 +58,12 @@ namespace CameraRoll.Client.Tool {
if (PathPoints.Count > 1) {
point.GetComponent<PathPoint>().LinkPreviousPoint(PathPoints[^2]);
}
if (PathPoints.Count == 1) {
Animations.Add(new TeleportAnimation(PathPoints));
} else {
Animations.Add(new CurveAnimation(PathPoints, InterpolationSpeed));
}
}
public static void SetPointsVisible(bool visible) {
@ -79,8 +80,10 @@ namespace CameraRoll.Client.Tool {
_originalRotation = _cam.transform.localRotation;
_pointIndex = 0;
_interpolationState = 0.0f;
foreach (Animatable animation in Animations) {
animation.Reset();
}
SetPointsVisible(false);
_showBuildingUI.SetValue(null, false); // Hide UI
@ -109,40 +112,15 @@ namespace CameraRoll.Client.Tool {
public static void Update() {
if (_playing) {
if (_pointIndex >= PathPoints.Count) {
// Reached the end
_logger.Info("Reached the end of track");
// Reached the end of track
Stop();
return;
}
if (_pointIndex == 0) {
// Snap to the first defined point
_cam.transform.position = PathPoints[0].transform.position;
_pointIndex++;
_interpolationState = 0.0f;
return;
}
_interpolationState += InterpolationSpeed;
Vector3 prevPos = GetPos(_pointIndex - 1);
Vector3 newPos = GetPos(_pointIndex);
_cam.transform.position = Vector3.Lerp(prevPos, newPos, _interpolationState);
Quaternion prevRot = GetRot(_pointIndex - 1);
Quaternion newRot = GetRot(_pointIndex);
_cam.transform.rotation = Quaternion.Slerp(prevRot, newRot, _interpolationState);
if (_interpolationState >= 1.0f) {
_pointIndex++;
_interpolationState = 0.0f;
}
Animations[_pointIndex].Animate(ref _pointIndex, _cam);
}
}
private static Vector3 GetPos(int index) => PathPoints[index].transform.position;
private static Quaternion GetRot(int index) => PathPoints[index].transform.rotation;
public static void OnExit() {
Clear();
_playing = false;

@ -0,0 +1,33 @@
using System.Collections.Generic;
using UnityEngine;
namespace CameraRoll.Client.Tool {
public class CurveAnimation : InterpolationAnimation {
public CurveAnimation(List<GameObject> pathPoints, float speed) : base(pathPoints, speed) { }
public override void Animate(ref int pointIndex, Camera cam) {
if (pointIndex >= PathPoints.Count - 1) {
// it's the last point
base.Animate(ref pointIndex, cam); // animate simple interpolation
return;
}
Vector3 prevPos = GetPos(pointIndex - 1);
Vector3 middlePos = GetPos(pointIndex);
Vector3 nextPos = GetPos(pointIndex + 1);
Vector3 curveA = Vector3.Lerp(prevPos, middlePos, InterpolationState);
Vector3 curveB = Vector3.Lerp(middlePos, nextPos, InterpolationState);
cam.transform.position = Vector3.Lerp(curveA, curveB, InterpolationState);
Quaternion prevRot = GetRot(pointIndex - 1);
Quaternion nextRot = GetRot(pointIndex + 1);
cam.transform.rotation = Quaternion.Slerp(prevRot, nextRot, InterpolationState);
InterpolationState += Speed;
if (InterpolationState >= 1.0f) {
pointIndex += 2;
}
}
}
}

@ -0,0 +1,34 @@
using System.Collections.Generic;
using UnityEngine;
namespace CameraRoll.Client.Tool {
public class InterpolationAnimation : Animatable {
protected float InterpolationState;
protected readonly float Speed;
public InterpolationAnimation(List<GameObject> pathPoints, float speed) : base(pathPoints) {
InterpolationState = 0.0f;
Speed = speed;
}
public override void Animate(ref int pointIndex, Camera cam) {
Vector3 prevPos = GetPos(pointIndex - 1);
Vector3 nextPos = GetPos(pointIndex);
cam.transform.position = Vector3.Lerp(prevPos, nextPos, InterpolationState);
Quaternion prevRot = GetRot(pointIndex - 1);
Quaternion nextRot = GetRot(pointIndex);
cam.transform.rotation = Quaternion.Slerp(prevRot, nextRot, InterpolationState);
InterpolationState += Speed;
if (InterpolationState >= 1.0f) {
pointIndex++;
}
}
public override void Reset() {
InterpolationState = 0.0f;
}
}
}

@ -4,6 +4,7 @@ namespace CameraRoll.Client.Tool {
public class PathPoint : MonoBehaviour {
private const float AxisLength = 0.2f;
// ReSharper disable once UnusedMember.Local
void Start() {
CreateAxis(Vector3.right, Color.red, false);
CreateAxis(Vector3.up, Color.green, false);

@ -0,0 +1,15 @@
using System.Collections.Generic;
using UnityEngine;
namespace CameraRoll.Client.Tool {
public class TeleportAnimation : Animatable {
public TeleportAnimation(List<GameObject> pathPoints) : base(pathPoints) { }
public override void Animate(ref int pointIndex, Camera cam) {
cam.transform.position = GetPos(pointIndex);
pointIndex++;
}
public override void Reset() { }
}
}
Loading…
Cancel
Save