using System;
using System.Collections.Generic;
using UnityEngine;
using WSMGameStudio.Splines;
namespace WSMGameStudio.RailroadSystem
{
public static class CustomWagonCreator
{
///
///
///
///
///
///
///
///
public static bool Validate(CustomWagonProfile profile, GameObject modelPrefab, string name, out string message)
{
message = string.Empty;
if (profile == null)
{
message = string.Format("Profile cannot be null.{0}Please select a profile and try again.", System.Environment.NewLine);
return false;
}
if (modelPrefab == null)
{
message = string.Format("Model cannot be null.{0}Please select your custom model and try again.", System.Environment.NewLine);
return false;
}
if (name == null || name == string.Empty)
{
message = string.Format("Name cannot be null.{0}Please select a name and try again.", System.Environment.NewLine);
return false;
}
return true;
}
///
///
///
///
///
///
///
public static bool Create(CustomWagonProfile profile, GameObject modelPrefab, string name, out string message)
{
message = string.Empty;
Vector3 railsOffset = profile.railsOffset;
//Wagon/locomotive game object
GameObject wagonInstance = new GameObject(name);
//Model
GameObject modelInstance;
if (modelPrefab != null)
modelInstance = InstantiateChild(modelPrefab, modelPrefab.name, profile.modelOffset, Quaternion.identity, wagonInstance.transform);
//Default child instances
GameObject wheels = InstantiateChild("Wheels", railsOffset, Quaternion.identity, wagonInstance.transform);
GameObject sfx = InstantiateChild("SFX", Vector3.zero, Quaternion.identity, wagonInstance.transform);
GameObject vfx = InstantiateChild("VFX", Vector3.zero, Quaternion.identity, wagonInstance.transform);
GameObject colliders = InstantiateChild("Colliders", Vector3.zero, Quaternion.identity, wagonInstance.transform);
GameObject bumpers = InstantiateChild("Bumpers", Vector3.zero, Quaternion.identity, wagonInstance.transform);
GameObject doors = InstantiateChild("Doors", Vector3.zero, Quaternion.identity, wagonInstance.transform);
GameObject lights = InstantiateChild("Lights", Vector3.zero, Quaternion.identity, wagonInstance.transform);
GameObject sensors = null;
GameObject suspension = null;
if (profile.trainType == TrainType.PhysicsBased)
{
sensors = InstantiateChild("Sensors", railsOffset, Quaternion.identity, wagonInstance.transform);
suspension = InstantiateChild("Suspension", railsOffset, Quaternion.identity, wheels.transform);
}
//Add common unity components
Rigidbody rigidbody = wagonInstance.AddComponent();
//Configure common unity components
rigidbody.mass = 10000f;
rigidbody.useGravity = (profile.trainType == TrainType.PhysicsBased);
rigidbody.isKinematic = (profile.trainType == TrainType.SplineBased);
rigidbody.interpolation = (profile.trainType == TrainType.PhysicsBased) ? RigidbodyInterpolation.Interpolate : RigidbodyInterpolation.None;
rigidbody.detectCollisions = true;
//Instantiate common profile components
InstantiateWagonComponents(profile.bumper, bumpers.transform, null);
if (profile.trainType == TrainType.PhysicsBased)
InstantiateWagonComponents(profile.suspensionCollider, suspension.transform, null);
InstantiateWagonComponents(profile.colliders, colliders.transform, null);
InstantiateWagonComponents(profile.internalDetails, wagonInstance.transform, null);
InstantiateWagonComponents(profile.passengerSensor, wagonInstance.transform, null);
//Instantiate specific profile components
if (profile.type == WagonType.Wagon)
{
IRailwayVehicle wagonScript = null;
HingeJoint hingeJoint = null;
//Add specific unity components
if (profile.trainType == TrainType.PhysicsBased)
{
wagonScript = wagonInstance.AddComponent();
hingeJoint = wagonInstance.AddComponent();
hingeJoint.axis = new Vector3(1f, 1f, 0f);
}
else if (profile.trainType == TrainType.SplineBased)
wagonScript = wagonInstance.AddComponent();
//Instantiate specific unity components
InstantiateWagonComponents(profile.wheelsSFX, sfx.transform, new Action>(ConfigureWheelSFX), wagonScript);
InstantiateWagonComponents(profile.brakesSFX, sfx.transform, new Action>(ConfigureBrakesSFX), wagonScript);
InstantiateWagonComponents(profile.wagonConnectionSFX, sfx.transform, new Action>(ConfigureConnectionSFX), wagonScript);
//Couplers
if (profile.trainType == TrainType.PhysicsBased)
InstantiateWagonComponents(profile.frontCoupler, wagonInstance.transform, new Action>(ConfigureFrontCoupler), rigidbody, wagonScript, hingeJoint);
else if (profile.trainType == TrainType.SplineBased)
InstantiateWagonComponents(profile.frontCoupler, wagonInstance.transform, new Action>(ConfigureFrontCoupler), rigidbody, wagonScript);
InstantiateWagonComponents(profile.backCoupler, wagonInstance.transform, new Action>(ConfigureBackCoupler), rigidbody, wagonScript);
//Lights
InstantiateWagonComponents(profile.externalLights, lights.transform, new Action>(ConfigureExternalLights), wagonScript);
InstantiateWagonComponents(profile.internalLights, lights.transform, new Action>(ConfigureInternalLights), wagonScript);
//Wheels
InstantiateWagonComponents(profile.wheelsVisuals, wheels.transform, new Action>(ConfigureWheels), wagonScript);
if (profile.trainType == TrainType.PhysicsBased)
{
InstantiateWagonComponents(profile.wheelsPhysics, wheels.transform, new Action>(ConfigurePhysicsWheels), rigidbody, wagonScript);
//Sensors
InstantiateWagonComponents(profile.railSensor, sensors.transform, new Action>(ConfigureSensors), wagonScript);
InstantiateWagonComponents(profile.defaultJointAnchor, wagonInstance.transform, new Action>(ConfigureDefaultJointAnchor), wagonScript);
}
}
else if (profile.type == WagonType.Locomotive)
{
ILocomotive locomotiveScript = null;
//Add specific unity components
if (profile.trainType == TrainType.PhysicsBased)
locomotiveScript = wagonInstance.AddComponent();
else if (profile.trainType == TrainType.SplineBased)
{
locomotiveScript = wagonInstance.AddComponent();
}
TrainPlayerInput playerInput = wagonInstance.AddComponent();
TrainSpeedMonitor speedMonitor = wagonInstance.AddComponent();
TrainStationController stationController = wagonInstance.AddComponent();
PassengerTags passengerTags = wagonInstance.AddComponent();
passengerTags.passengerTags = new List() { "Player", "NPC" };
BoxCollider locomotiveTrigger = wagonInstance.AddComponent();
//Configure specific unity components
locomotiveScript.EnginesOn = true;
locomotiveScript.Acceleration = 1f;
locomotiveScript.SpeedUnit = profile.speedUnits;
playerInput.inputSettings = profile.inputSettings;
locomotiveTrigger.isTrigger = true;
locomotiveTrigger.size = new Vector3(0.5f, 0.5f, 0.5f);
locomotiveTrigger.center = profile.controlZoneTriggerPosition;
//Instantitate specific unity components
InstantiateWagonComponents(profile.engineSFX, sfx.transform, new Action>(ConfigureEngineSFX), locomotiveScript);
InstantiateWagonComponents(profile.brakesSFX, sfx.transform, new Action>(ConfigureBrakesSFX), locomotiveScript);
InstantiateWagonComponents(profile.wheelsSFX, sfx.transform, new Action>(ConfigureWheelSFX), locomotiveScript);
InstantiateWagonComponents(profile.hornSFX, sfx.transform, new Action>(ConfigureHornSFX), locomotiveScript);
InstantiateWagonComponents(profile.bellSFX, sfx.transform, new Action>(ConfigureBellSFX), locomotiveScript);
//Particles
InstantiateWagonComponents(profile.smokeParticles, vfx.transform, new Action>(ConfigureSmokeParticles), locomotiveScript);
InstantiateWagonComponents(profile.brakingSparksParticles, vfx.transform, new Action>(ConfigureBrakingSparksParticles), locomotiveScript);
//Couplers
InstantiateWagonComponents(profile.frontCoupler, wagonInstance.transform, new Action>(ConfigureFrontCoupler), rigidbody, locomotiveScript);
InstantiateWagonComponents(profile.backCoupler, wagonInstance.transform, new Action>(ConfigureBackCoupler), rigidbody, locomotiveScript);
//Lights
InstantiateWagonComponents(profile.externalLights, lights.transform, new Action>(ConfigureExternalLights), locomotiveScript);
InstantiateWagonComponents(profile.internalLights, lights.transform, new Action>(ConfigureInternalLights), locomotiveScript);
//Wheels
InstantiateWagonComponents(profile.wheelsVisuals, wheels.transform, new Action>(ConfigureWheels), locomotiveScript);
//Steam Locomotive Rear wheels and Pistons
InstantiateWagonComponents(profile.steamLocomotiveRearWheelsAndPistons, wheels.transform, new Action>(ConfigureWheels), locomotiveScript);
//Bell
InstantiateWagonComponents(profile.bell, wagonInstance.transform, new Action>(ConfigureBell), locomotiveScript);
if (profile.trainType == TrainType.PhysicsBased)
{
InstantiateWagonComponents(profile.wheelsPhysics, wheels.transform, new Action>(ConfigurePhysicsWheels), rigidbody, locomotiveScript);
//Sensors
InstantiateWagonComponents(profile.railSensor, sensors.transform, new Action>(ConfigureSensors), locomotiveScript);
}
}
TrainDoorsController doorsController = wagonInstance.AddComponent();
wagonInstance.AddComponent();
if (profile.trainType == TrainType.PhysicsBased)
wagonInstance.AddComponent();
InstantiateWagonComponents(profile.cabinDoorLeft, doors.transform, new Action>(ConfigureLeftCabinDoor), doorsController);
InstantiateWagonComponents(profile.cabinDoorRight, doors.transform, new Action>(ConfigureRightCabinDoor), doorsController);
InstantiateWagonComponents(profile.passengerDoorLeft, doors.transform, new Action>(ConfigureLeftPassengerDoors), doorsController);
InstantiateWagonComponents(profile.passengerDoorRight, doors.transform, new Action>(ConfigureRightPassengerDoors), doorsController);
InstantiateWagonComponents(profile.openCabinDoorSFX, sfx.transform, new Action>(ConfigureOpenCabinDoorSFX), doorsController);
InstantiateWagonComponents(profile.closeCabinDoorSFX, sfx.transform, new Action>(ConfigureCloseCabinDoorSFX), doorsController);
InstantiateWagonComponents(profile.openPassengerDoorSFX, sfx.transform, new Action>(ConfigureOpenPassengerDoorSFX), doorsController);
InstantiateWagonComponents(profile.closePassengerDoorSFX, sfx.transform, new Action>(ConfigureClosePassengerDoorSFX), doorsController);
InstantiateWagonComponents(profile.closeDoorWarningSFX, sfx.transform, new Action>(ConfigureCloseDoorWarningSFX), doorsController);
string carType = profile.type.ToString();
message = string.Format("{0} created successfully!", carType);
return true;
}
///
/// Instantiate new child based on prefab
///
///
///
///
///
///
///
private static GameObject InstantiateChild(GameObject prefab, string name, Vector3 position, Quaternion rotation, Transform parent)
{
GameObject child = GameObject.Instantiate(prefab, position, rotation, parent);
child.name = name;
return child;
}
///
/// Creates a new child game object instance
///
///
///
///
///
///
private static GameObject InstantiateChild(string name, Vector3 position, Quaternion rotation, Transform parent)
{
GameObject child = new GameObject(name);
child.transform.SetParent(parent);
child.transform.position = position;
child.transform.rotation = rotation;
return child;
}
///
/// Instatiate wagon component based on profile settings
///
///
///
private static void InstantiateWagonComponents(CustomWagonComponent wagonComponent, Transform parent, Delegate configMethod, params object[] configParams)
{
if (wagonComponent.prefab == null)
return;
string instanceName = string.Empty;
List instances = new List();
for (int i = 0; i < wagonComponent.positions.Length; i++)
{
instanceName = wagonComponent.customName != string.Empty ? wagonComponent.customName : wagonComponent.prefab.name;
GameObject newComponentInstance = InstantiateChild(wagonComponent.prefab, instanceName, wagonComponent.positions[i].position, Quaternion.Euler(wagonComponent.positions[i].rotation), parent);
EnforceUniqueName(newComponentInstance);
instances.Add(newComponentInstance);
}
if (configMethod != null)
{
List