using Godot; using System; [Tool] public class Railway : Node { [Export] private NodePath[] _railPaths; [Export] private NodePath _centreLine; private float _railWidth; private float _railHeight; private float _railGauge; [Export] private float RailWidth { get => _railWidth; set { _railWidth = value; if (Engine.EditorHint) { SetRailCrossSection(); } } } [Export] private float RailHeight { get => _railHeight; set { _railHeight = value; if (Engine.EditorHint) { SetRailCrossSection(); } } } [Export] private float RailGauge { get => _railGauge; set { _railGauge = value; if (Engine.EditorHint) { SetRailCrossSection(); } } } private Path _path = null; private Path Path { get { if (_path == null) { _path = GetNode(_centreLine); } return _path; } } public Curve3D Curve => Path.Curve; // the centre line should not have geometry directly associated with it. // instead, two additional path/csgpolygon combinations should be managed // in reference to the centre line for the left and right rails. // Called when the node enters the scene tree for the first time. public override void _Ready() { } private void SetRailCrossSection() { // error checkin if (_railPaths.Length != 2) throw new Exception("need 2 rails"); // set rail geometry for (int i = 0; i < 2; i++) { var rail = GetNode(_railPaths[i]); float w = RailWidth; float h = RailHeight; // horizontal offset of rail from centreline float c = (-.5f + i) * RailGauge; var polygon = new Vector2[4]; polygon[0] = new Vector2(c - w, 0); polygon[1] = new Vector2(c - w, h); polygon[2] = new Vector2(c + w, h); polygon[3] = new Vector2(c + w, 0); rail.Polygon = polygon; } } public override void _Process(float delta) { } public void AddPathFollower(PathFollow pathFollow) { Path.AddChild(pathFollow); } }