将数据统一存储到一个csv文件中

时间:2018-07-17 04:30:11

标签: c# unity3d

我有一个不断向某个方向移动的多维数据集,我想以Excel工作表中的行和列中的x,y和z坐标每秒存储其位置。我有编写用于收集和存储数据的代码:

using UnityEngine;
using System.Collections;
using System.IO;
using System;

public class fileMaker: MonoBehaviour {
    public static void putBytes(ref byte[] output, int index, float value)
    {
        //turns a float into its 4 bytes and then puts them into the output array
        //at the given index
        byte[] data = BitConverter.GetBytes(value);
        output[index] = data[0];
        output[index + 1] = data[1];
        output[index + 2] = data[2];
        output[index + 3] = data[3];
    }
    public static void makeFile(Vector3 position)
    {
        //each float is 4 bytes.
        //3 floats in a vector 3(x,y,z) and 3x4 =12!
        byte[] output = new byte[12];
        //get bytes for each part of our lil vector3
        putBytes(ref output, 0, position.x);
        putBytes(ref output, 4, position.y);
        putBytes(ref output, 8, position.z);
        File.WriteAllBytes(Application.dataPath + "/log.csv", output);
    }

    public static void loadFile()
    {
        //converts it all back into pretty print
        if (File.Exists(Application.dataPath + "/log.csv"))
        {
            byte[] input = File.ReadAllBytes(Application.dataPath + "/log.csv");
            int length = input.Length;
            if (length == 12)
            {
                Vector3 ourVector3 = new Vector3();
                ourVector3.x = (float)BitConverter.ToSingle(input, 0);
                ourVector3.y = (float)BitConverter.ToSingle(input, 4);
                ourVector3.z = (float)BitConverter.ToSingle(input, 8);
                print("Position saved in file (" + Application.dataPath + "/log.csv): " + ourVector3.ToString());
            }

        }
    }

}

但是此代码有两个问题。

  1. 收集的数据不可读。当我打开csv文件时,总是得到如下内容:̸AûwªAñF©Á。我该如何解决这个问题?

2。我面临的另一个问题是每秒收集数据,我在侧面有一个按钮,每次必须按下该按钮以统一以保存立方体的位置。我希望它每秒自动收集多维数据集的位置。我正在谈论的是:I have to press the button everytime for unity to log the cubes position on the console 因此,我该如何删除此按钮,并使每次都统一记录位置。我对统一编程非常陌生。

1 个答案:

答案 0 :(得分:1)

除非您的代码比显示给我们的更多,否则我只能问“为什么?”。您没有将数据另存为CSV。您正在输入字节数据,并尝试手动读取。

在这里,我的头顶上有一些可以减轻很多头痛的替代方法:

  • 创建一个Serializable类,然后将引用存储在您的MonoBehaviour脚本之一中,或使用.Net Binary Serializer。
  • 使用Json存储数据,然后再次将字符串存储为MonoBahviour中的引用,或对其进行序列化。
  • 将数据存储在ScriptableObject中。

使用上述所有方法,您可以创建Property DrawerCustom Editor Window以类似网格的方式显示数据。

问题1。

这是一个示例,展示了如何设置ScriptableObject,存储对其的引用并在运行时仍在编辑器中对其进行修改:

using UnityEngine;
using System.Collections.Generic;

public class Test : MonoBehaviour
{
    float timer = 0.0f;
    public TestSO so;

    public void Update ( )
    {
        timer += Time.deltaTime;

        if ( timer > 1.0f )
        {
            timer -= 1.0f;
            so.Vectors.Add ( new Vector3 ( UnityEngine.Random.Range ( 0, 10 ), UnityEngine.Random.Range ( 0, 10 ), UnityEngine.Random.Range ( 0, 10 ) ) );
        }
    }
}

[CreateAssetMenu ( fileName = "TestSO", menuName = "Create TestSO", order = 0 )]
public class TestSO : ScriptableObject
{
    public List<Vector3> Vectors;
}

要测试此代码:

  • 转到菜单,然后选择资产> 创建> 创建TestSO 。将创建一个ScriptableObect。
  • 将“测试”脚本附加到层次结构中的GameObject。
  • 将先前创建的TestSO ScriptableObject拖到Test组件中的对象插槽中。
  • 单击TestSO,以便在层次结构中看到它。您会注意到它具有一个字段Vectors,您可以使用折叠开关打开它。
  • 运行游戏,您会注意到每一秒钟,新的Vector被添加到列表中。

停止并重新启动游戏。您会注意到“向量”列表已保存,并在第二次运行时被添加到其中。在Unity编辑器中,ScriptableObject数据会自动进行序列化。

问题2。

关于您的第二个问题,那是另外一锅鱼。您正在寻找的是将在“编辑”模式下运行的脚本。具体来说,您可以使用ExecuteInEditMode装饰脚本中的方法。然后,您需要创建一个重复的协程,以检查您的多维数据集位置并保存数据,或者,我的首选是使用System.Threading.Tasks命名空间。您可以设置一个方法,例如:

#if UNITY_EDITOR
public async void PollCubePosition ( )
{
    if ( pollCube ) return;
    pollCube = true;

    do
    {
        // Read cube data and perform whatever functions you want here..

        // Wait 1 seconds.
        await Task.Delay ( 1000 );
    } while ( pollCube );
}
#endif

完成编辑后,只需将pollCube设置为false,因为它将无限期运行。 (您也可以在其中放置一些保护措施,以便在一段时间后将pollCube设置为false,以防万一您忘记了。)