0

Im trying to rotate a gameobject through an array of Quaternions that I've read in via a CSV file. Its currently not rotating the objectas i believe i'm not updating the transform.rotation correctly. Any help resolving this would be greatly appreciated, let me know if you need anymore information.

RotationAnimator.cs The Rotator Script:

public class RotationAnimator : MonoBehaviour
{
    public Transform playbackTarget;
    [HideInInspector]
    public bool playingBack = false;
    public CSVReader csvReader;

    public void PlayRecording()
    {
        //  -1 as it reads the last blank line of the CSV for reasons
        for (int row = 0; row < csvReader.quaternionRecords.Length-1; row++)
        {
            playbackTarget.rotation = new Quaternion(csvReader.quaternionRecords[row].x, csvReader.quaternionRecords[row].y, csvReader.quaternionRecords[row].z, csvReader.quaternionRecords[row].w);
        }
    }
}

CSVReader.cs The script reading the csv file

public class CSVReader : MonoBehaviour
{
    public QuaternionRecord[] quaternionRecords;
    public List<List<String>> fileData;
    ILogging logger;
    string path = "Assets\\Logs\\RotationList.csv";

    private void OnEnable()
    {
        logger = Logging.GetCurrentClassLogger();
    }

    public void ReadFile()
    {
        var r = File.OpenText(path);
        fileData = r.ReadToEnd().Split('\n').Select(s => s.Split(',').ToList()).ToList();
        quaternionRecords = new QuaternionRecord[fileData.Count];

        // skip last empty line at "file data.count -1"
        for(int row = 0; row <  fileData.Count-1; row++)
        {
            try
            {
                quaternionRecords[row] = new QuaternionRecord();
                quaternionRecords[row].time = float.Parse(fileData[row][0]);
                quaternionRecords[row].x = float.Parse(fileData[row][1]);
                quaternionRecords[row].y = float.Parse(fileData[row][2]);
                quaternionRecords[row].z = float.Parse(fileData[row][3]);
                quaternionRecords[row].w = float.Parse(fileData[row][4]);
            }
            catch(Exception e)
            {
                Debug.Log("Ouch!");
            }
        }
        r.Close();
    }

    public struct QuaternionRecord
    {
        public float time;
        public float x;
        public float y;
        public float z;
        public float w;
    }
}

Where PlayRecording is called:

    public void Playback()
    {
        Debug.Log("Beginning Playback...");
        csvReader.ReadFile();
        rotationAnimator.PlayRecording();
    }
7
  • How and where are you calling PlayRecording? Commented Feb 16, 2017 at 23:07
  • In another script, here is the function: public void Playback() { Debug.Log("Beginning Playback..."); csvReader.ReadFile(); rotationAnimator.PlayRecording(); rotationAnimator.playingBack = true; } Commented Feb 16, 2017 at 23:11
  • I see what you're getting at, i've gotten rid of the bool and added the necessary call function Commented Feb 16, 2017 at 23:17
  • 2
    Okay I see. I think it is "working" but you don't see it because it happens too fast. The reason is because you loop through all values at once and what you should see is the final rotation in the recording (asuming the quaterion values are correct). You would need to do the itterating in Update or in a Coroutine. Commented Feb 16, 2017 at 23:27
  • 1
    Well then I don't really know. You might need to print some logs to see if PlayRecording is called, if the for loop is itterating, if you are getting the correct values, etc. Debug.Log(csvReader.quaternionRecords[row].x) Commented Feb 16, 2017 at 23:36

1 Answer 1

1

Here is a way to itterate the quaternionRecords using Coroutines by modifying your existing code.

//Change void to IEnumerator 
public IEnumerator PlayRecording()
{
    for (int row = 0; row < csvReader.quaternionRecords.Length; row++)
    {
        playbackTarget.rotation = new Quaternion(csvReader.quaternionRecords[row].x, csvReader.quaternionRecords[row].y, csvReader.quaternionRecords[row].z, csvReader.quaternionRecords[row].w);
        //Add this line to wait 1 second until next itteration
        yield return new WaitForSeconds(1f);
    }
}

public void Playback()
{
    Debug.Log("Beginning Playback...");
    csvReader.ReadFile();
    //Change to StartCourotine
    StartCoroutine(rotationAnimator.PlayRecording());
}

I haven't tested the code so it might not work and it might not be the best solution but it is a a way to do it. Other ways is using Update with Time.deltaTime

Sign up to request clarification or add additional context in comments.

1 Comment

You could save a time stamp of each recorded rotation and go thru recordings in update/fixed update and set current rotation according to the current time. I would put rows to the queue, and took the out of queue in update.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.