创建动态游戏对象,并根据 JSON 数据一起转换它们的位置



考虑这个数据集:

[
   {
     PartId: 0,
     Positions: [
       { x: 0, y: 0, z: 0, timeCode: 0.0000 },
       { x: 0, y: 0, z: 1, timeCode: 0.0025 },
       { x: 0, y: 0, z: 2, timeCode: 0.0050 },
       { x: 0, y: 0, z: 3, timeCode: 0.0075 },
       { x: 0, y: 0, z: 4, timeCode: 0.0100 },
       { x: 0, y: 0, z: 5, timeCode: 0.0125 },
       { x: 0, y: 0, z: 6, timeCode: 0.0150 },
       { x: 0, y: 0, z: 7, timeCode: 0.0175 },
       { x: 0, y: 0, z: 8, timeCode: 0.0200 },
     ]
   },
   {
     PartId: 1,
     Positions: [
       { x: 0, y: 0, z: 0, timeCode: 0.0000 },
       { x: 0, y: 0, z: 2, timeCode: 0.0025 },
       { x: 0, y: 0, z: 4, timeCode: 0.0050 },
       { x: 0, y: 0, z: 6, timeCode: 0.0075 },
       { x: 0, y: 0, z: 8, timeCode: 0.0100 },
       { x: 0, y: 0, z: 10, timeCode: 0.0125 },
       { x: 0, y: 0, z: 12, timeCode: 0.0150 },
       { x: 0, y: 0, z: 14, timeCode: 0.0175 },
       { x: 0, y: 0, z: 16, timeCode: 0.0200 },
     ]
   }
 ]

我能够加载和解析 JSON 数据,并且可以为每个 PartId 创建一个新的游戏对象。我正在尝试找出根据位置集合同时转换每个"零件"的最佳方法。

我在场景中有一个空的游戏对象,其中包含一个附加的类。 在 Start 方法中,我获取 JSON 数据,然后在循环中创建 GameObject 类,设置其初始位置,然后启动在同一类中定义的协程。

主类:

void Start() {
    // do json stuff...
    // ........
    // then
    // for each part...
    foreach(PartGroup pg in Parts) {
        // create a new GameObject from the Part class
        Part part = gameObject.AddComponent(typeof(Part)) as Part;
        // send this part data to the new GameObject
        part.PartGroup = pg;
        // set the initial position for the part
        part.Init();
        // start a IEnumerator Coroutine in the part class
        StartCoroutine(part.PlayFrom());
    }
}

零件类别:

public void Init() {
    Joint = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    Joint.transform.localScale = new Vector3(jointSize, jointSize, jointSize);
    Joint.transform.position = new Vector3(PartGroup.Positions[0].X, PartGroup.Positions[0].Z, PartGroup.Positions[0].Y);
}
public IEnumerator PlayFrom(float time = 0f) {
    while (PlayBack(time)) {
        yield return null;
        time += Time.fixedDeltaTime;
    }
}
bool PlayBack(float time) {
    float sample = time / (Time.fixedDeltaTime / speed);
    int previousIndex = (int)(sample);
    int last = PartGroup.Positions.Count - 1;
    if (previousIndex < last) {
        int nextIndex = previousIndex + 1;
        float interpolation = sample - previousIndex;
        Joint.transform.position = Vector3.Lerp(
            new Vector3(PartGroup.Positions[previousIndex].X, PartGroup.Positions[previousIndex].Z, PartGroup.Positions[previousIndex].Y),
            new Vector3(PartGroup.Positions[nextIndex].X, PartGroup.Positions[nextIndex].Z, PartGroup.Positions[nextIndex].Y),
            interpolation);
        return true;
    }
    Joint.transform.position = new Vector3(PartGroup.Positions[last].X, PartGroup.Positions[last].Z, PartGroup.Positions[last].Y);
    return false;
}

这就是我目前设置它的方式。它确实有效,但它不是平滑的运动,有时它似乎滞后或跳帧。这是实现此目的的最佳方法,还是有更好的方法(如 FixedUpdate(?我在项目设置中设置了固定时间属性以匹配数据时间码。

非常感谢有关

此类内容的最佳实践的任何帮助!

你必须在 中使用Time.deltaTime

time += Time.deltaTime;

float sample = time / (Time.deltaTime / speed);

协程与所有Update调用一起执行,因此使用 fixedDeltaTime 会破坏帧的独立性。

或者可能使用WaitForFixedUpdateFixedUpdate一样执行它

while (PlayBack(time)) {
    yield return new WaitForFixedUpdate();
    time += Time.fixedDeltaTime;
}

也在

foreach(PartGroup pg in Parts) 
{
    // create a new GameObject from the Part class
    Part part = gameObject.AddComponent(typeof(Part)) as Part;
    // send this part data to the new GameObject
    part.PartGroup = pg;
    // set the initial position for the part
    part.Init();
    // start a IEnumerator Coroutine in the part class
    StartCoroutine(part.PlayFrom());
}

看起来您正在为列表中的每个元素添加一个组件,所有这些都是同一个GameObject..我不知道这是否是你打算做的。 AddComponent不会使用该组件创建新GameObject,而是将该组件附加到该脚本附加到的同一gameObject

你可能想用new GameObject

Part part = new GameObject("new GameObject").AddComponent<Part>();
// make it a child of this gameObject?
part.SetParent(gameObject, false);

还有计算

float sample = time / (Time.fixedDeltaTime / speed);
int previousIndex = (int)(sample);
...
float interpolation = sample - previousIndex;

似乎有点奇怪..您确定它总是返回01之间的值吗?

最新更新