Code/VehicleCreator.cs
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Meteor.VehicleTool.Vehicle;
using Meteor.VehicleTool.Vehicle.Wheel;
using Sandbox;
namespace Meteor.VehicleTool;
public sealed class VehicleCreator : Component
{
[Property] public GameObject Model { get; set; }
[Property, Group( "Wheels" )] public List<GameObject> Wheels { get; set; }
[Property, Group( "Wheels" )] public List<GameObject> MotorWheels { get; set; }
[Property, Group( "Wheels" )] public List<GameObject> SteeringWheels { get; set; }
[Property, Group( "Wheels" )] public List<GameObject> HandBrakeWheels { get; set; }
[Property, Group( "Engine" )] public List<SoundFile> AcsendingSounds { get; set; }
[Property, Group( "Engine" )] public List<SoundFile> DecsendingSounds { get; set; }
[Button]
internal void CreateCar()
{
using var undo = Scene.Editor.UndoScope( "Create Car" ).WithComponentCreations().WithComponentDestructions( this ).Push();
var controller = AddComponent<VehicleController>();
List<WheelCollider> motors = [];
List<WheelCollider> steering = [];
List<WheelCollider> handBrake = [];
var maxRPM = 0;
foreach ( var item in Wheels )
{
GameObject p = new( item.Parent, true, $"WheelCollider ({item.Name})" )
{
WorldPosition = item.WorldPosition,
WorldRotation = WorldRotation,
};
var collider = p.AddComponent<WheelCollider>();
collider.UseVisual = true;
collider.Controller = controller;
item.SetParent( new( item.Parent, true, $"Wrap ({item.Name})" )
{
WorldPosition = item.WorldPosition,
WorldRotation = WorldRotation,
} );
collider.RendererObject = item.Parent;
if ( MotorWheels.Contains( item ) )
motors.Add( collider );
if ( SteeringWheels.Contains( item ) )
steering.Add( collider );
if ( HandBrakeWheels.Contains( item ) )
handBrake.Add( collider );
collider.SetBoundsToVisual();
collider.CreateColliders();
}
Dictionary<int, SoundFile> acsendingSounds = [];
Dictionary<int, SoundFile> decsendingSounds = [];
foreach ( var item in AcsendingSounds )
{
var rpm = ExtractInteger( item.ResourceName );
acsendingSounds.TryAdd( rpm, item );
maxRPM = Math.Max( maxRPM, rpm );
}
foreach ( var item in DecsendingSounds )
decsendingSounds.TryAdd( ExtractInteger( item.ResourceName ), item );
controller.AcsendingSounds = acsendingSounds;
controller.DecsendingSounds = decsendingSounds;
controller.HandBrakeWheels = handBrake;
controller.SteeringWheels = steering;
controller.MotorWheels = motors;
controller.Body.MassOverride = 1500;
var size = Model.GetLocalBounds().Size;
controller.CameraOffset = controller.CameraOffset.WithX( size.x * 1.5f ).WithZ( size.z / 2f );
controller.ConnectWheels();
controller.CreatePowertrain();
controller.Engine.RevLimiterRPM = maxRPM;
Destroy();
}
public static int ExtractInteger( string input )
{
Match match = Regex.Match( input, @"\d+" );
if ( match.Success )
return int.Parse( match.Value );
throw new FormatException( "No integer found in the input." );
}
}