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 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("Railroad Turnout Creator"); currentWindow.minSize = new Vector2(540, 240); } /// /// Render Window /// 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(); } /// /// Save turnout prefab /// 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(); railroadSwitchScript.RailsColliders = new List(); railroadSwitchScript.RailsSplines = new List(); _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; } /// /// Configure rails on railroad switch /// /// /// /// private static void ConfigureRail(GameObject railroadSwitch, GameObject rails, bool deactivateRails = false) { RailroadSwitch_v3 railroadSwitchScript = railroadSwitch.GetComponent(); foreach (Transform child in rails.transform) { if (child.GetComponent() != null) { railroadSwitchScript.RailsColliders.Add(child.gameObject); if (deactivateRails) child.gameObject.SetActive(false); } Spline spline = child.GetComponentInChildren(); if (spline != null) { railroadSwitchScript.RailsSplines.Add(spline); } } rails.transform.SetParent(railroadSwitch.transform); } /// /// Validate if selected object is a baked segment /// /// /// private bool IsBakeSegment(GameObject obj) { return (obj.GetComponent() != null); } #region Auxiliar Methods /// /// Save prefab as .prefab file /// /// /// /// private GameObject SavePrefabFile(GameObject sceneObject, string prefabFilePath, out bool success) { GameObject prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(sceneObject, prefabFilePath, InteractionMode.UserAction, out success); return prefab; } /// /// Show message on Window /// /// /// 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; } } /// /// Show overwrite dialog confirmation /// /// /// 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"); } /// /// Check if file already exists /// /// /// private bool Exists(string filePath) { return File.Exists(filePath); } #endregion } }