c# - Deje que un tren con varios vagones viaje por un camino de Bézier

CorePress2024-01-25  13

Utilizo Bezier Path Creator del administrador de paquetes para permitir que un tren viaje por una ruta predefinida. (https://assetstore.unity.com/packages/tools/utilities/b-zier-path-creator-136082)

Actualmente, tengo el siguiente código en una unidad de tren:

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);

    }
}

Esto funciona bastante bien. Pero cuando tengo un tren con varias unidades/vagones, cada vagón debe girar tras otro, no todos a la vez.

Estoy un poco perdido, ¿cómo podría solucionar esto? ¿Alguna idea?

¡Gracias!



------------------------------------

Yo manejaría esto manejando el bogie delantero y trasero de cada vagón en lugar del centro de cada vagón. Y si puedes comoSupongamos que la pista es relativamente recta y que cada auto va a la misma velocidad (estas son las mismas suposiciones a menos que desee modelar las fuerzas de los resortes en cada acoplamiento de auto), esto debería funcionar:

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);
    }
    
}

asegúrese de establecer la distancia de inicio de cada automóvil para que incluya el relleno entre todos los automóviles anteriores, así como la longitud de todos los automóviles anteriores, de modo que el furgón de cola tenga startDistance=0, el penúltimo automóvil tenga startDistance=cabooseLength + relleno, etc.

Tenga en cuenta que esto dará como resultado diferentes grados de separación entre los autos en diferentes momentos, lo cual es un comportamiento realista para una secuencia de autos que se mueven todos a la misma velocidad a lo largo de una pista.

Para reiterar, si desea una distancia constante entre cada automóvil a lo largo de las curvas, entonces no puede asumir una velocidad común entre cada automóvil..

Lo ideal sería tener una forma de encontrar todas las intersecciones entre las curvas de Bézier con la esfera centrada en una posición mundial y un radio determinados. Es más una pregunta matemática, pero si tuvieras ese método, podrías usarlo en un par de lugares.

Una vez, para cada automóvil, encuentre dónde colocar el bogey delantero en función del bogey trasero usando una esfera de radio carLength y centrada en rearPos. Y en segundo lugar, para cada automóvil sucesivo, encontrar dónde colocar el bogey trasero basándose en el bogy delantero del automóvil anterior, utilizando una esfera de relleno de radio centrada en la posición delantera del automóvil anterior. Alternativamente, puedes comenzar con el auto delantero y avanzar hacia atrás. Y deberá asegurarse de ignorar las intersecciones que harían que el automóvil "salte" de la carretera. la pista y otras tonterías.

SiSi encontró este método, cada automóvil querrá hacer referencia a los bogeys delanteros y/o traseros de sus vecinos, por lo que sugeriría incluir algunos campos adicionales.

2

Muchas gracias por tu aporte bien pensado, lo investigaré :) No puedo votar esto debido a mi baja puntuación de principiante aquí. ¡Siéntete muy votado de todos modos!

-hdbrnd

11 de abril de 2021 a las 9:40

@hdbrnd Si esta respuesta te ayuda, ¡espero que consideres aceptarla!

- Ruzihm

11 de abril de 2021 a las 14:43



------------------------------------

Actualización: Experimenté un poco y lo probé con un valor de relleno por vagón:

transform.position = pathCreator.path.GetPointAtDistance(distanceTravelled+padding);
        transform.rotation = pathCreator.path.GetRotationAtDistance(distanceTravelled+padding);

Aun así: ¿Es esta una buena manera o crees que podría generar problemas más adelante?

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare