感谢您花时间阅读此消息。
在统一中,我的目标是每隔固定时间间隔记录一个游戏对象的 Z 欧拉角,并将其输出为 CSV 文件,时间在左列,相应的欧拉角在第二列。
我收到这个错误
Assets\scripts\debug\ConcatArray.cs(28,21):错误 CS0029:无法将类型“float”隐式转换为“System.Collections.Generic.List”
这是我的尝试,并尝试更改“时间计数”的变量类型,但我仍然遇到相同的错误。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq; // allows for concat?
public class ConcatArray : MonoBehaviour
{
public string fileName = "Assets/Resources/test.txt"; // file pathname
private List<float> AnglesOne;
private List<float> TimeCount;
private float[] DoublePendulumData;
// Start is called before the first frame update
void Start()
{
AnglesOne = new List<float>();
TimeCount = new List<float>();
DoublePendulumData = new float[] { 15, 1645, 135, 567 };
}
void RecPoint()
{
// store position...
AnglesOne.Add(transform.eulerAngles.z);
// Store time... capital T?
TimeCount = Time.time;
}
void SaveToFile(string fileName)
{
System.IO.File.WriteAllText(fileName, ""); // clear old file, if any
DoublePendulumData = TimeCount.Concat(AnglesOne).ToArray();
}
void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 120, 30), "Save"))
{
CancelInvoke("RecPoint"); // stop recording
SaveToFile(fileName); // save positions
}
}
}
在
RecPoint()
内部,您需要将时间值添加到列表中,而不是尝试将其分配给列表,即
TimeCount.Add(Time.time);
我建议您使用一些类来表示您正在存储的数据类型。我认为对所有内容都使用
float
是一种反模式,因为无法从编译器那里获得帮助以确保类型匹配。
public class Angle{
public float Degrees {get; init;}
public Angle() {};
public Angle(float degrees) => Degrees = degrees;
}
public List<(TimeSpan Time, Angle Z)> data = new ();
这种方式应该更清楚数据实际代表什么,并降低混合不同类型数据的风险。
在您当前的解决方案中,您似乎在连接时间和角度,这大大增加了出错的风险。但是你的例子不是很清楚,因为
SaveToFile
实际上并没有对文件进行任何保存。
我不建议将 Csv 用于此类数据。如果您需要与其他应用程序交换数据,csv 文件可能很有用,但它不是定义明确的格式。不同的文化使用不同的分隔符、十进制字符、换行符的处理方式,以及其他一些我不想考虑的事情。像 excel 这样的软件有一个向导来帮助导入 csv 数据是有原因的。
我的建议是使用 json 序列化,请参阅How to serialize and deserialize JSON in .NET。这往往更可靠,将来更容易扩展,也更容易使用:
string jsonString = JsonSerializer.Serialize(data);
您可以决定是序列化为字符串,并将其写入文件,还是创建文件流并序列化为该字符串。只要您没有大量数据,两者都可以正常工作。如果您确实有大量数据,您可能需要考虑一些二进制序列化方法,或者压缩您的 json。