我有一个不断向某个方向移动的多维数据集,我想以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());
}
}
}
}
但是此代码有两个问题。
2。我面临的另一个问题是每秒收集数据,我在侧面有一个按钮,每次必须按下该按钮以统一以保存立方体的位置。我希望它每秒自动收集多维数据集的位置。我正在谈论的是: 因此,我该如何删除此按钮,并使每次都统一记录位置。我对统一编程非常陌生。
答案 0 :(得分:1)
除非您的代码比显示给我们的更多,否则我只能问“为什么?”。您没有将数据另存为CSV。您正在输入字节数据,并尝试手动读取。
在这里,我的头顶上有一些可以减轻很多头痛的替代方法:
Serializable
类,然后将引用存储在您的MonoBehaviour
脚本之一中,或使用.Net Binary Serializer。MonoBahviour
中的引用,或对其进行序列化。ScriptableObject
中。使用上述所有方法,您可以创建Property Drawer或Custom 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;
}
要测试此代码:
停止并重新启动游戏。您会注意到“向量”列表已保存,并在第二次运行时被添加到其中。在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,以防万一您忘记了。)