BITFALL/Assets/WSM Game Studio/Train Controller_v3/Railroad Builder/Editor/RailroadTurnoutCreatorWindo...

322 lines
12 KiB
C#
Raw Normal View History

2024-03-22 20:16:32 +08:00
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using WSMGameStudio.Splines;
using System;
namespace WSMGameStudio.RailroadSystem
{
public class RailroadTurnoutCreatorWindow : EditorWindow
{
private string _turnoutPrefabName;
private string _outputDirectory = string.Empty;
private string _selectedFolder = string.Empty;
private string _defaultDiretory = "WSM Game Studio/Train Controller_v3/Prefabs/Turnouts/";
private string _txtMessage;
private float _labelsWidth = 140f;
private Color _txtColor = Color.black;
private GUIStyle _errorMessageStyle;
private GUIStyle _instructionsTitleStyle;
private GUIStyle _instructionsStyle;
private GUIStyle _menuBoxStyle;
private Transform _referenceTransform;
private GameObject _mainRails;
private GameObject _turnoutRails;
private GameObject _paralledRails;
//public List<GameObject> mainRails;
//public GameObject turnoutRails;
[MenuItem("WSM Game Studio/Train Controller/Utilities/Railroad Turnout Creator")]
[MenuItem("Window/WSM Game Studio/Railroad Turnout Creator")]
public static void ShowWindow()
{
RailroadTurnoutCreatorWindow currentWindow = GetWindow<RailroadTurnoutCreatorWindow>("Railroad Turnout Creator");
currentWindow.minSize = new Vector2(540, 240);
}
/// <summary>
/// Render Window
/// </summary>
private void OnGUI()
{
GUILayout.Label("Railroad Turnout Creator", EditorStyles.boldLabel);
//Set up the box style if null
if (_menuBoxStyle == null)
{
_menuBoxStyle = new GUIStyle(GUI.skin.box);
_menuBoxStyle.normal.textColor = GUI.skin.label.normal.textColor;
_menuBoxStyle.fontStyle = FontStyle.Bold;
_menuBoxStyle.alignment = TextAnchor.UpperLeft;
}
if (_outputDirectory == string.Empty)
_outputDirectory = _defaultDiretory;
GUILayout.BeginVertical(_menuBoxStyle);
GUILayout.BeginHorizontal();
GUILayout.BeginVertical(GUILayout.Width(_labelsWidth));
EditorGUILayout.LabelField("Main Rails", GUILayout.Width(_labelsWidth));
EditorGUILayout.LabelField("Turnout Rails", GUILayout.Width(_labelsWidth));
EditorGUILayout.LabelField("Parallel Rails (optional)", GUILayout.Width(_labelsWidth));
EditorGUILayout.LabelField("Name", GUILayout.Width(_labelsWidth));
EditorGUILayout.LabelField("Output Directory", GUILayout.Width(_labelsWidth));
GUILayout.EndVertical();
GUILayout.BeginVertical();
_mainRails = EditorGUILayout.ObjectField(_mainRails, typeof(GameObject), true) as GameObject;
_turnoutRails = EditorGUILayout.ObjectField(_turnoutRails, typeof(GameObject), true) as GameObject;
_paralledRails = EditorGUILayout.ObjectField(_paralledRails, typeof(GameObject), true) as GameObject;
_turnoutPrefabName = EditorGUILayout.TextField(_turnoutPrefabName);
using (new EditorGUI.DisabledScope(true))
{
_outputDirectory = EditorGUILayout.TextField(_outputDirectory);
}
GUILayout.EndVertical();
GUILayout.EndHorizontal();
if (GUILayout.Button("Browse Folder"))
{
_selectedFolder = EditorUtility.OpenFolderPanel("Select Output Directory", _defaultDiretory, "");
if (_selectedFolder != string.Empty)
_outputDirectory = string.Concat(_selectedFolder.Replace(string.Format("{0}/", Application.dataPath), string.Empty), "/");
}
if (GUILayout.Button("Create"))
{
CreateTurnout();
}
_errorMessageStyle = new GUIStyle();
_errorMessageStyle.normal.textColor = _txtColor;
GUILayout.Label(_txtMessage, _errorMessageStyle);
string instructions = string.Format(
" 1) Drag & Drop the rails (Baked Segments) prefabs to the scene {0}" +
" 2) Select a name and output folder{0}" +
" 3) Select the rails segments from your scene{0}" +
" 4) Click on the Create Button", System.Environment.NewLine);
_instructionsTitleStyle = new GUIStyle();
_instructionsTitleStyle.normal.textColor = Color.blue;
_instructionsTitleStyle.fontStyle = FontStyle.Bold;
GUILayout.Label(" Instructions", _instructionsTitleStyle);
_instructionsStyle = new GUIStyle();
_instructionsStyle.normal.textColor = Color.blue;
GUILayout.Label(instructions, _instructionsStyle);
GUILayout.EndVertical();
}
/// <summary>
/// Save turnout prefab
/// </summary>
private void CreateTurnout()
{
_txtMessage = string.Empty;
int railsCount = 0;
int bakedSegmentsCount = 0;
if (_turnoutPrefabName == string.Empty)
{
ShowMessage("Please, enter a name for your turnout before proceding", Splines.MessageType.Error);
return;
}
if (_mainRails == null)
{
ShowMessage("Main rails not selected", Splines.MessageType.Error);
return;
}
else
{
railsCount++;
if (IsBakeSegment(_mainRails)) bakedSegmentsCount++;
}
if (_turnoutRails == null)
{
ShowMessage("Turnout rails not selected", Splines.MessageType.Error);
return;
}
else
{
railsCount++;
if (IsBakeSegment(_turnoutRails)) bakedSegmentsCount++;
}
if (_paralledRails != null)
{
railsCount++;
if (IsBakeSegment(_paralledRails)) bakedSegmentsCount++;
}
if (bakedSegmentsCount != railsCount)
{
ShowMessage("All selected objects must be Baked Segments", Splines.MessageType.Error);
return;
}
DirectoryInfo info = new DirectoryInfo(Application.dataPath);
string folderPath = Path.Combine(info.Name, _outputDirectory);
string prefabFilePath = Path.Combine(folderPath, _turnoutPrefabName + ".prefab");
//Check folder existence
if (!Directory.Exists(folderPath))
{
ShowMessage(string.Format("Folder does not exist: {0}", folderPath), Splines.MessageType.Error);
return;
}
//Overwrite dialog
if (Exists(prefabFilePath))
{
if (!ShowOverwriteDialog(_turnoutPrefabName))
return;
}
GameObject sceneObject = new GameObject(_turnoutPrefabName);
RailroadSwitch_v3 railroadSwitchScript = sceneObject.AddComponent<RailroadSwitch_v3>();
railroadSwitchScript.RailsColliders = new List<GameObject>();
railroadSwitchScript.RailsSplines = new List<Spline>();
_referenceTransform = _mainRails.transform;
sceneObject.transform.SetParent(_referenceTransform.parent);
sceneObject.transform.localPosition = _referenceTransform.localPosition;
sceneObject.transform.localRotation = _referenceTransform.localRotation;
ConfigureRail(sceneObject, _mainRails);
ConfigureRail(sceneObject, _turnoutRails, true);
if (_paralledRails != null) ConfigureRail(sceneObject, _paralledRails);
//Save prefab as .prefab file
bool success = false;
GameObject prefab = SavePrefabFile(sceneObject, prefabFilePath, out success);
if (success)
{
ShowMessage(string.Format("{0} Created Succesfuly!", _turnoutPrefabName), Splines.MessageType.Success);
ResetForm();
}
else
ShowMessage(string.Format("Could not create prefab.{0}Please check Console Window for more information.", System.Environment.NewLine), Splines.MessageType.Error);
}
//Reset form inputs
private void ResetForm()
{
_mainRails = null;
_turnoutRails = null;
_paralledRails = null;
_turnoutPrefabName = string.Empty;
}
/// <summary>
/// Configure rails on railroad switch
/// </summary>
/// <param name="railroadSwitch"></param>
/// <param name="rails"></param>
/// <param name="deactivateRails"></param>
private static void ConfigureRail(GameObject railroadSwitch, GameObject rails, bool deactivateRails = false)
{
RailroadSwitch_v3 railroadSwitchScript = railroadSwitch.GetComponent<RailroadSwitch_v3>();
foreach (Transform child in rails.transform)
{
if (child.GetComponent<MeshCollider>() != null)
{
railroadSwitchScript.RailsColliders.Add(child.gameObject);
if (deactivateRails)
child.gameObject.SetActive(false);
}
Spline spline = child.GetComponentInChildren<Spline>();
if (spline != null)
{
railroadSwitchScript.RailsSplines.Add(spline);
}
}
rails.transform.SetParent(railroadSwitch.transform);
}
/// <summary>
/// Validate if selected object is a baked segment
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private bool IsBakeSegment(GameObject obj)
{
return (obj.GetComponent<BakedSegment>() != null);
}
#region Auxiliar Methods
/// <summary>
/// Save prefab as .prefab file
/// </summary>
/// <param name="prefabName"></param>
/// <param name="prefabFilePath"></param>
/// <returns></returns>
private GameObject SavePrefabFile(GameObject sceneObject, string prefabFilePath, out bool success)
{
GameObject prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(sceneObject, prefabFilePath, InteractionMode.UserAction, out success);
return prefab;
}
/// <summary>
/// Show message on Window
/// </summary>
/// <param name="message"></param>
/// <param name="type"></param>
private void ShowMessage(string message, Splines.MessageType type)
{
_txtMessage = message;
switch (type)
{
case Splines.MessageType.Success:
_txtColor = new Color(0, 0.5f, 0); //Dark green;
break;
case Splines.MessageType.Warning:
_txtColor = Color.yellow;
break;
case Splines.MessageType.Error:
_txtColor = Color.red;
break;
}
}
/// <summary>
/// Show overwrite dialog confirmation
/// </summary>
/// <param name="meshName"></param>
/// <returns></returns>
private bool ShowOverwriteDialog(string prefabName)
{
return EditorUtility.DisplayDialog("Are you sure?",
string.Format("A prefab named {0} already exists. Do you want to overwrite it?", prefabName.ToUpper()),
"Yes",
"No");
}
/// <summary>
/// Check if file already exists
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private bool Exists(string filePath)
{
return File.Exists(filePath);
}
#endregion
}
}