首页 > 解决方案 > 让多节车厢的火车在贝塞尔路径上行驶

问题描述

我使用包管理器中的 Bezier Path Creator 让火车在预定义的路径上行驶。(https://assetstore.unity.com/packages/tools/utilities/b-zier-path-creator-136082

目前,我在一个火车单元上有以下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class pathFollower : MonoBehaviour
{
    public PathCreator pathCreator;
    public float speed = 5;
    float distanceTravelled;
    


    // Update is called once per frame
    void Update()
    {

        distanceTravelled += speed * Time.deltaTime;
        transform.position = pathCreator.path.GetPointAtDistance(distanceTravelled);
        transform.rotation = pathCreator.path.GetRotationAtDistance(distanceTravelled);

    }
}

这工作得很好。但是当我有一列有多个单元/货车的火车时,每辆货车都需要依次转向,而不是一次全部转向。

我有点迷茫,我怎么能解决这个问题。有任何想法吗?

谢谢!

标签: c#unity3d

解决方案


我会通过处理每辆车的前后转向架而不是每辆车的中心来处理这个问题。如果您可以假设轨道相对笔直并且每辆汽车的速度相同(除非您想在每个汽车联轴器上模拟弹簧力,否则这些假设是相同的),这应该有效:

public class pathFollower : MonoBehaviour
{
    public PathCreator pathCreator;
    public float speed = 5;
    float distanceTravelled;

    // set these appropriately in inspector and/or instantiation
    public float startDistance = 0f;
    public float carLength = 2f;

    // Update is called once per frame
    void Update()
    {
        distanceTravelled += speed * Time.deltaTime;

        UpdateTransform();
    }

    // May want to call this when instantiating, after startDistance & carLength are called
    // to position it before the first call to Update
    public void UpdateTransform()
    {
        Vector3 rearPos = pathCreator.path.GetPointAtDistance(startDistance + distanceTravelled);
        Vector3 frontPos = pathCreator.path.GetPointAtDistance(startDistance + distanceTravelled 
            + carLength);
        
        transform.position = 0.5f * (rearPos+frontPos); // midpoint between bogies
        transform.LookAt(frontPos);
    }
    
}

确保设置startDistance每辆车的 ,使其包括所有先前车辆之间的填充以及所有先前车辆的长度,因此守车有startDistance=0,倒数第二辆车有startDistance=cabooseLength + 填充等。

请注意,这将导致不同时间的汽车之间的分离量不同,这对于沿轨道以相同速度移动的一系列汽车来说是现实的行为。


重申一下,如果您希望每辆车之间沿曲线保持恒定距离,那么您不能假设每辆车之间的速度相同。

理想情况下,您将有一种方法可以找到贝塞尔曲线之间的所有交点,球体以给定的世界位置和半径为中心。这更像是一个数学问题,但如果你有这种方法,你可以在几个地方使用它。

一次,每辆车根据后柏忌使用半径为 的球体找到放置前柏忌的位置carLength,以 为中心rearPos。其次,对于每辆车,根据前一辆汽车的前转向架,使用以前一辆汽车为padding 中心的半径球体,找到放置后柏忌的位置frontPos。或者,您可以从前车开始并向后工作。而且您需要确保忽略会使汽车“跳过”轨道和其他废话的交叉路口。

如果您确实找到了这种方法,那么每辆车都希望引用其邻居的前和/或后柏忌,因此建议您添加一些额外的字段。


推荐阅读