Tuesday, November 15, 2016

unity - Move GameObject with defined lists of position and rotation


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

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...