2022-08-04 22:20:29 +02:00
|
|
|
using Godot;
|
|
|
|
using System;
|
|
|
|
|
2022-08-12 01:16:38 +02:00
|
|
|
public class Train : Spatial
|
2022-08-04 22:20:29 +02:00
|
|
|
{
|
2022-08-12 01:16:38 +02:00
|
|
|
[Export]
|
|
|
|
private float _speed = 1.0f;
|
|
|
|
|
|
|
|
[Export]
|
|
|
|
private NodePath _railwayPath;
|
|
|
|
|
|
|
|
private Railway _railway;
|
|
|
|
private readonly PathFollow _pathFollow = new PathFollow
|
|
|
|
{
|
|
|
|
RotationMode = PathFollow.RotationModeEnum.Oriented
|
|
|
|
};
|
|
|
|
private float _distance = 0;
|
|
|
|
|
2022-08-04 22:20:29 +02:00
|
|
|
// Called when the node enters the scene tree for the first time.
|
|
|
|
public override void _Ready()
|
|
|
|
{
|
2022-08-12 01:16:38 +02:00
|
|
|
_railway = GetNode<Railway>(_railwayPath) as Railway;
|
|
|
|
_railway.AddPathFollower(_pathFollow);
|
2022-08-04 22:20:29 +02:00
|
|
|
}
|
|
|
|
|
2022-08-12 01:16:38 +02:00
|
|
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
|
|
public override void _Process(float delta)
|
|
|
|
{
|
|
|
|
var length = _railway.Curve.GetBakedLength();
|
|
|
|
|
|
|
|
// keep track of total distance
|
|
|
|
_distance += delta * _speed;
|
|
|
|
// wrap at 2x total distance
|
|
|
|
_distance %= length * 2;
|
|
|
|
|
|
|
|
var distance = PingPong(_distance, length);
|
|
|
|
|
|
|
|
_pathFollow.Offset = distance;
|
|
|
|
Translation = _pathFollow.Translation;
|
|
|
|
Rotation = _pathFollow.Rotation;
|
|
|
|
}
|
|
|
|
|
|
|
|
// poor mans branching ping pong
|
|
|
|
private float PingPong(float t, float length)
|
|
|
|
{
|
|
|
|
var tml = t % length;
|
|
|
|
|
|
|
|
return t > length
|
|
|
|
? length - tml
|
|
|
|
: tml;
|
|
|
|
}
|
2022-08-04 22:20:29 +02:00
|
|
|
}
|