【问题标题】:How to rotate a game object through an array of Quaternions?如何通过四元数数组旋转游戏对象?
【发布时间】:2017-07-06 06:41:59
【问题描述】:

我试图通过我通过 CSV 文件读取的四元数数组来旋转游戏对象。它目前没有旋转对象,因为我相信我没有正确更新 transform.rotation。任何解决此问题的帮助将不胜感激,如果您需要更多信息,请告诉我。

RotationAnimator.cs 旋转器脚本:

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 读取 csv 文件的脚本

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;
    }
}

调用 PlayRecording 的位置:

    public void Playback()
    {
        Debug.Log("Beginning Playback...");
        csvReader.ReadFile();
        rotationAnimator.PlayRecording();
    }

【问题讨论】:

  • 你在哪里打电话给 PlayRecording?
  • 在另一个脚本中,函数如下: public void Playback() { Debug.Log("Beginning Playback..."); csvReader.ReadFile(); rotationAnimator.PlayRecording(); rotationAnimator.playingBack = true; }
  • 我明白你在说什么,我已经摆脱了 bool 并添加了必要的调用函数
  • 好的,我明白了。我认为它正在“工作”,但您看不到它,因为它发生得太快了。原因是因为您一次循环遍历所有值,而您应该看到的是记录中的最终旋转(假设四元数值是正确的)。您需要在 Update 或 Coroutine 中进行迭代。
  • 那么我真的不知道。您可能需要打印一些日志以查看是否调用了 PlayRecording、for 循环是否正在迭代、是否获得正确的值等。Debug.Log(csvReader.quaternionRecords[row].x)

标签: c# csv unity3d .net-3.5 quaternions


【解决方案1】:

这是一种通过修改现有代码使用Coroutines 迭代quaternionRecords 的方法。

//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());
}

我还没有测试过代码,所以它可能不起作用,也可能不是最好的解决方案,但它是一种方法。其他方式是使用UpdateTime.deltaTime

【讨论】:

  • 您可以保存每个记录旋转的时间戳,并在更新/固定更新中通过记录并根据当前时间设置当前旋转。我会将行放入队列中,并在更新中将行列出队列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多