Unity3D读取txt文件坐标实现双车同步移动方案咨询
Unity读取positions.txt实现汽车同步移动方案
1. 定义匹配JSON结构的C#类
先创建对应JSON层级的可序列化类,确保Unity能正确解析数据:
[System.Serializable] public class CarPositionData { public string id; public PositionInfo position; } [System.Serializable] public class PositionInfo { public float[] cartesian; }
2. 读取文件内容
根据文件存放位置选择读取方式:
- 放在StreamingAssets文件夹:
using System.IO; using UnityEngine; string filePath = Path.Combine(Application.streamingAssetsPath, "positions.txt"); string jsonContent = File.ReadAllText(filePath);
- 放在Resources文件夹:
TextAsset jsonText = Resources.Load<TextAsset>("positions"); string jsonContent = jsonText.text;
3. 解析JSON并拆分坐标数据
方法一:用Unity自带JsonUtility(处理顶层数组)
Unity原生JsonUtility不支持直接解析顶层数组,需用辅助类包裹处理:
public static class JsonHelper { public static T[] FromJson<T>(string json) { string wrappedJson = "{\"items\":" + json + "}"; Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(wrappedJson); return wrapper.items; } [System.Serializable] private class Wrapper<T> { public T[] items; } }
然后解析并拆分cartesian数组为时间序列和位置序列:
// 解析所有车辆数据 CarPositionData[] carDatas = JsonHelper.FromJson<CarPositionData>(jsonContent); // 存储每辆车的时间、位置数据 var carMovementDict = new Dictionary<string, (float[] times, Vector3[] positions)>(); foreach (var carData in carDatas) { float[] cartesian = carData.position.cartesian; int dataGroupCount = cartesian.Length / 4; float[] times = new float[dataGroupCount]; Vector3[] positions = new Vector3[dataGroupCount]; for (int i = 0; i < dataGroupCount; i++) { int baseIndex = i * 4; times[i] = cartesian[baseIndex]; positions[i] = new Vector3( cartesian[baseIndex + 1], cartesian[baseIndex + 2], cartesian[baseIndex + 3] ); } carMovementDict.Add(carData.id, (times, positions)); }
方法二:用Newtonsoft.Json(更简便)
通过Unity Package Manager安装com.unity.nuget.newtonsoft-json包后,可直接解析顶层数组:
using Newtonsoft.Json; CarPositionData[] carDatas = JsonConvert.DeserializeObject<CarPositionData[]>(jsonContent);
后续拆分数组的逻辑和方法一完全一致。
4. 实现汽车同步移动
创建控制汽车移动的脚本,挂载到每辆汽车上:
using UnityEngine; public class CarMovement : MonoBehaviour { public string carId; private float[] _timeSequence; private Vector3[] _positionSequence; private int _currentDataIndex = 0; private float _movementStartTime; public void Initialize(float[] times, Vector3[] positions) { _timeSequence = times; _positionSequence = positions; _movementStartTime = Time.time; } void Update() { if (_timeSequence == null || _positionSequence == null || _currentDataIndex >= _timeSequence.Length - 1) return; float elapsedTime = Time.time - _movementStartTime; // 定位当前时间对应的区间 while (_currentDataIndex < _timeSequence.Length - 1 && elapsedTime > _timeSequence[_currentDataIndex + 1]) { _currentDataIndex++; } // 到达最后一个点时固定位置 if (_currentDataIndex >= _timeSequence.Length - 1) { transform.position = _positionSequence[^1]; return; } // 计算插值比例并移动 float t = (elapsedTime - _timeSequence[_currentDataIndex]) / (_timeSequence[_currentDataIndex + 1] - _timeSequence[_currentDataIndex]); transform.position = Vector3.Lerp(_positionSequence[_currentDataIndex], _positionSequence[_currentDataIndex + 1], t); } }
最后在控制脚本中初始化所有汽车:
public class MovementController : MonoBehaviour { public GameObject car1; public GameObject car2; void Start() { // 放入前面的文件读取、解析代码... // 初始化car1 if (carMovementDict.ContainsKey("car_1")) { var data = carMovementDict["car_1"]; car1.GetComponent<CarMovement>().Initialize(data.times, data.positions); } // 初始化car2 if (carMovementDict.ContainsKey("car_2")) { var data = carMovementDict["car_2"]; car2.GetComponent<CarMovement>().Initialize(data.times, data.positions); } } }
内容的提问来源于stack exchange,提问作者alcor
相关产品推荐
相关产品推荐

