I'm working on playing a replay on every strike. For that I'm recording the positions and rotation of the sphere in the list individually. I now have the values reside in the list. How do i move my sphere with the defined pos and rot. Below is what I've tried so far.
Replay.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Replay : MonoBehaviour
{
BallRecorder script;
public List position;
public List rotation;
// Use this for initialization
void Start()
{
script = GetComponent();
position = new List();
rotation = new List();
position = script.position; // Now contains all the values of the sphere(positions)
rotation = script.rotation; // Now contains all the values of the sphere(rotation)
foreach (Vector3 av in position)
{
transform.position = av; //transferring position to the sphere
}
}
BallRecorder.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallRecorder : MonoBehaviour {
// Use this for initialization
public List position;
public List rotation;
static int count = 50;
void Start () {
position = new List();
rotation = new List();
}
// Update is called once per frame
void Update()
{
count = count - 1;
if (count < 1)
{
position.Add(transform.position);
rotation.Add(transform.rotation);
}
}
}
Answer
I'd be inclined to do this as a Coroutine like so, letting us start the playback by calling StartCoroutine(PlayFrom(0f));
IEenumerator PlayFrom(float time = 0f) {
// As long as there's still more recording to play,
// update our transform to match the replay data at this moment.
while(Playback(time)) {
// Wait until next frame.
yield return null;
// Advance the playhead by deltaTime and loop again.
// You can set Time.timeScale to get slow-motion replays this way.
time += Time.deltaTime;
}
}
bool Playback(float time) {
// Convert the playback time to a position in our sample array.
// (Here I'm assuming the current fixedDeltaTime is the same one used to record)
float sample = time / Time.fixedDeltaTime;
// Round down to the position & rotation sample just before this moment.
// (Here I'm assuming time is non-negative)
int previousIndex = (int)(sample);
int last = positions.Count - 1;
if(previousIndex < last) {
// We have another snapshot ahead, so we'll interpolate smoothly between them.
int nextIndex = previousIndex + 1;
float interpolation = sample - previousIndex;
transform.position = Vector3.Lerp(
position[previousIndex],
position[nextIndex],
interpolation);
// Slerp is technically a more consistent option here, since it keeps
// the rate of change even over the course of the interpolation.
// But each step is usually too small for this difference to be visible.
transform.rotation = Quaternion.Lerp(
rotation[previousIndex],
rotation[nextIndex].
interpolation);
// Signal that there's still more replay past here.
return true;
}
// Here we're off the end of the timeline, so we'll hold on the last snapshot.
transform.position = position[last];
transform.rotation = rotation[last];
// Signal that we're at the end of the replay.
return false;
}
Pulling out Playback
as its own method also lets you call it separately if you want to seek to a particular freezeframe in the replay, or reverse time and rewind the recording, or use a shared playhead controller to scrub through the timeline, things like that.
No comments:
Post a Comment