Add Unity3D projects
This commit is contained in:
@ -0,0 +1,196 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using RoadArchitect;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
/// <summary> Provides the menu items inside the editor </summary>
|
||||
public class EditorMenu
|
||||
{
|
||||
/// <summary> Creates the road system. </summary>
|
||||
[MenuItem("Window/Road Architect/Create road system")]
|
||||
public static void CreateRoadSystem()
|
||||
{
|
||||
Object[] allRoadSystemObjects = GameObject.FindObjectsOfType<RoadSystem>();
|
||||
int nextCount = (allRoadSystemObjects.Length + 1);
|
||||
allRoadSystemObjects = null;
|
||||
|
||||
GameObject newRoadSystemObject = new GameObject("RoadArchitectSystem" + nextCount.ToString());
|
||||
RoadSystem newRoadSystem = newRoadSystemObject.AddComponent<RoadSystem>();
|
||||
//Add road for new road system.
|
||||
newRoadSystem.AddRoad(true);
|
||||
|
||||
GameObject masterIntersectionsObject = new GameObject("Intersections");
|
||||
masterIntersectionsObject.transform.parent = newRoadSystemObject.transform;
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Add road to gameobject. Not sure if this is necessary. </summary>
|
||||
[MenuItem("Window/Road Architect/Add road")]
|
||||
public static void AddRoad()
|
||||
{
|
||||
Object[] allRoadSystemObjects = GameObject.FindObjectsOfType<RoadSystem>();
|
||||
if (allRoadSystemObjects != null && allRoadSystemObjects.Length == 0)
|
||||
{
|
||||
CreateRoadSystem();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RoadSystem firstRoadSystem = (RoadSystem)allRoadSystemObjects[0];
|
||||
Selection.activeGameObject = firstRoadSystem.AddRoad();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Updates all roads. Used when things get out of sync. </summary>
|
||||
[MenuItem("Window/Road Architect/Update All Roads")]
|
||||
public static void UpdateAllRoads()
|
||||
{
|
||||
Road[] allRoadObjects = GameObject.FindObjectsOfType<Road>();
|
||||
|
||||
int roadCount = allRoadObjects.Length;
|
||||
|
||||
Road singleRoad = null;
|
||||
SplineC[] tPiggys = null;
|
||||
if (roadCount > 1)
|
||||
{
|
||||
tPiggys = new SplineC[roadCount - 1];
|
||||
}
|
||||
|
||||
for (int count = 0; count < roadCount; count++)
|
||||
{
|
||||
singleRoad = allRoadObjects[count];
|
||||
if (count > 0)
|
||||
{
|
||||
tPiggys[count - 1] = singleRoad.spline;
|
||||
}
|
||||
}
|
||||
|
||||
singleRoad = allRoadObjects[0];
|
||||
if (tPiggys != null && tPiggys.Length > 0)
|
||||
{
|
||||
singleRoad.PiggyBacks = tPiggys;
|
||||
}
|
||||
singleRoad.UpdateRoad();
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Show the help screen. </summary>
|
||||
[MenuItem("Window/Road Architect/Help")]
|
||||
public static void ShowHelpWindow()
|
||||
{
|
||||
HelpWindow helpWindow = EditorWindow.GetWindow<HelpWindow>();
|
||||
helpWindow.Initialize();
|
||||
}
|
||||
|
||||
|
||||
/// <summary> WARNING: Only call this on an empty scene that has some terrains on it. We are not responsbile for data loss if this function is called by the user. </summary>
|
||||
[MenuItem("Window/Road Architect/Testing/Run all unit tests (caution)")]
|
||||
public static void TestProgram()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Warning !", "This will delete your RoadSystem 1, 6, 7, 8 and 9 and will create a lot of test roads.", "OK", "Cancel"))
|
||||
{
|
||||
RoadArchitect.Tests.UnitTests.RoadArchitectUnitTests();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Testing/Run unit test 1-5 (caution)")]
|
||||
public static void Test1To5()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Warning !", "This will delete your first RoadSystem and will create a lot of test roads.", "OK", "Cancel"))
|
||||
{
|
||||
RoadArchitect.Tests.UnitTests.RoadArchitectUnitTest1To5();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Testing/Run unit test 6 (caution)")]
|
||||
public static void Test6()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Warning !", "This will delete your sixth RoadSystem and will create a lot of test roads.", "OK", "Cancel"))
|
||||
{
|
||||
RoadArchitect.Tests.UnitTests.RoadArchitectUnitTest6();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Testing/Run unit test 7 (caution)")]
|
||||
public static void Test7()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Warning !", "This will delete your seventh RoadSystem and will create a lot of test roads.", "OK", "Cancel"))
|
||||
{
|
||||
RoadArchitect.Tests.UnitTests.RoadArchitectUnitTest7();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Testing/Run unit test 8 (caution)")]
|
||||
public static void Test8()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Warning !", "This will delete your eigth RoadSystem and will create a test roads.", "OK", "Cancel"))
|
||||
{
|
||||
RoadArchitect.Tests.UnitTests.RoadArchitectUnitTest8();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Testing/Run unit test 9 (caution)")]
|
||||
public static void Test9()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Warning !", "This will delete your RoadArchitectSystem9 and will create test roads.", "OK", "Cancel"))
|
||||
{
|
||||
RoadArchitect.Tests.UnitTests.RoadArchitectUnitTest9();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Testing/Run unit test 10 (caution)")]
|
||||
public static void Test10()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Warning !", "This will delete your RoadArchitectSystem10 and will create test roads.", "OK", "Cancel"))
|
||||
{
|
||||
RoadArchitect.Tests.UnitTests.RoadArchitectUnitTest10();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary> WARNING: Only call this on an empty scene that has some terrains on it. We are not responsbile for data loss if this function is called by the user. </summary>
|
||||
[MenuItem("Window/Road Architect/Testing/Clean up tests (caution)")]
|
||||
public static void TestCleanup()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Warning !", "This will delete your RoadSystem 1, 6, 7, 8 and 9", "OK", "Cancel"))
|
||||
{
|
||||
RoadArchitect.Tests.UnitTests.CleanupAllTests();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Get code line count for RA project </summary>
|
||||
[MenuItem("Window/Road Architect/Testing/Get line count of RA")]
|
||||
public static void TestCodeCount()
|
||||
{
|
||||
string mainDir = System.IO.Path.Combine(System.Environment.CurrentDirectory, RoadEditorUtility.GetBasePathForIO());
|
||||
string[] files = System.IO.Directory.GetFiles(mainDir, "*.cs", System.IO.SearchOption.AllDirectories);
|
||||
int lineCount = 0;
|
||||
foreach (string file in files)
|
||||
{
|
||||
lineCount += System.IO.File.ReadAllLines(file).Length;
|
||||
}
|
||||
Debug.Log(string.Format("{0:n0}", lineCount) + " lines of code in Road Architect.");
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Report a Bug")]
|
||||
public static void ReportBug()
|
||||
{
|
||||
Application.OpenURL("https://github.com/FritzsHero/RoadArchitect/issues");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09c94f91ab2d0d34c9c464536e8633e9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,60 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
/// <summary> Used for progress information for other areas of RA. </summary>
|
||||
public class EditorProgressWindow : EditorWindow
|
||||
{
|
||||
private float seconds = 10.0f;
|
||||
private float startValue = 0f;
|
||||
private float progress = 0f;
|
||||
|
||||
|
||||
private static void Init()
|
||||
{
|
||||
EditorProgressWindow window = (EditorProgressWindow)EditorWindow.GetWindow(typeof(EditorProgressWindow));
|
||||
window.Show();
|
||||
}
|
||||
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
seconds = EditorGUILayout.FloatField("Time to wait:", seconds);
|
||||
if (GUILayout.Button("Display bar"))
|
||||
{
|
||||
if (seconds < 1)
|
||||
{
|
||||
Debug.LogError("Seconds should be bigger than 1");
|
||||
return;
|
||||
}
|
||||
startValue = (float)EditorApplication.timeSinceStartup;
|
||||
}
|
||||
|
||||
if (progress < seconds)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar(
|
||||
"Simple Progress Bar",
|
||||
"Shows a progress bar for the given seconds",
|
||||
progress / seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
EngineIntegration.ClearProgressBar();
|
||||
}
|
||||
|
||||
progress = (float)(EditorApplication.timeSinceStartup - startValue);
|
||||
}
|
||||
|
||||
|
||||
private void OnInspectorUpdate()
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36611904ee7524a45afea00db85e5039
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,32 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
public class EditorUtilities
|
||||
{
|
||||
/// <summary> Opens the loacally stored manual </summary>
|
||||
public static void OpenOfflineManual()
|
||||
{
|
||||
Application.OpenURL(System.Environment.CurrentDirectory.Replace(@"\", "/") + "/" + RoadEditorUtility.GetBasePath() + "/RoadArchitectManual.htm");
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Loads the _texture from _path if necessary </summary>
|
||||
public static void LoadTexture<T>(ref T _texture, string _path) where T : Texture
|
||||
{
|
||||
_texture = EngineIntegration.LoadAssetFromPath<T>(_path);
|
||||
}
|
||||
|
||||
|
||||
public static void DrawLine(float _spacing = 4f, float _size = 1f)
|
||||
{
|
||||
//Horizontal bar
|
||||
GUILayout.Space(_spacing);
|
||||
GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(_size));
|
||||
GUILayout.Space(_spacing);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f40193a8b5e9ed84f9597bbaefb0635d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,70 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
public class HelpWindow : EditorWindow
|
||||
{
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorStyles.label.wordWrap = true;
|
||||
EditorStyles.miniLabel.wordWrap = true;
|
||||
|
||||
EditorGUILayout.LabelField("Road Architect Help", EditorStyles.boldLabel);
|
||||
GUILayout.Space(12f);
|
||||
EditorGUILayout.LabelField("Please visit the online manual for help.");
|
||||
GUILayout.Space(4f);
|
||||
|
||||
|
||||
if (GUILayout.Button("Click here to open online manual", EditorStyles.toolbarButton, GUILayout.Width(310f)))
|
||||
{
|
||||
Application.OpenURL("https://github.com/FritzsHero/RoadArchitect/wiki");
|
||||
}
|
||||
EditorGUILayout.LabelField("https://github.com/FritzsHero/RoadArchitect/wiki");
|
||||
|
||||
if (GUILayout.Button("Click here to open offline manual", EditorStyles.toolbarButton, GUILayout.Width(310f)))
|
||||
{
|
||||
EditorUtilities.OpenOfflineManual();
|
||||
}
|
||||
|
||||
|
||||
GUILayout.Space(12f);
|
||||
|
||||
|
||||
EditorGUILayout.LabelField("Please visit us or reach out to us on Github (links below) with any questions or comments.");
|
||||
EditorGUILayout.LabelField("If you encounter Bugs or have a Feature Suggestion, you can submit them on the following sites:");
|
||||
|
||||
|
||||
GUILayout.Space(12f);
|
||||
|
||||
if (GUILayout.Button("RoadArchitect Repository", EditorStyles.toolbarButton, GUILayout.Width(310f)))
|
||||
{
|
||||
Application.OpenURL("https://github.com/FritzsHero/RoadArchitect");
|
||||
}
|
||||
EditorGUILayout.LabelField("https://github.com/FritzsHero/RoadArchitect");
|
||||
|
||||
GUILayout.Space(4f);
|
||||
|
||||
if (GUILayout.Button("RoadArchitect Issues", EditorStyles.toolbarButton, GUILayout.Width(310f)))
|
||||
{
|
||||
Application.OpenURL("https://github.com/FritzsHero/RoadArchitect/issues");
|
||||
}
|
||||
EditorGUILayout.LabelField("https://github.com/FritzsHero/RoadArchitect/issues");
|
||||
GUILayout.Space(12f);
|
||||
}
|
||||
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
Rect rect = new Rect(340, 170, 400, 400);
|
||||
position = rect;
|
||||
Show();
|
||||
titleContent.text = "Help Info";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83a696e187e0572418fa95bc2a0cecd0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,395 @@
|
||||
/*
|
||||
Based on ObjExporter.cs, this "wrapper" lets you export to .OBJ directly from the editor menu.
|
||||
|
||||
Use by selecting the objects you want to export, and select the appropriate menu item from "Custom->Export".
|
||||
Exported models are put in a folder called "ExportedObj" in the root of your project.
|
||||
Textures should also be copied and placed in the same folder.
|
||||
*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
public class ObjExporter : ScriptableObject
|
||||
{
|
||||
private static int vertexOffset = 0;
|
||||
private static int normalOffset = 0;
|
||||
private static int uvOffset = 0;
|
||||
|
||||
|
||||
//User should probably be able to change this. It is currently left as an excercise for
|
||||
//the reader.
|
||||
private static string targetFolder = "ExportedObj";
|
||||
|
||||
|
||||
private struct ObjMaterial
|
||||
{
|
||||
public string name;
|
||||
public string textureName;
|
||||
}
|
||||
|
||||
|
||||
private static string MeshToString(MeshFilter _meshFilter, Dictionary<string, ObjMaterial> _materialList)
|
||||
{
|
||||
Mesh mesh = _meshFilter.sharedMesh;
|
||||
Renderer renderer = _meshFilter.GetComponent<Renderer>();
|
||||
//Material[] mats = mf.renderer.sharedMaterials;
|
||||
Material[] materials = renderer.sharedMaterials;
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
stringBuilder.Append("g ").Append(_meshFilter.name).Append("\n");
|
||||
foreach (Vector3 lv in mesh.vertices)
|
||||
{
|
||||
Vector3 wv = _meshFilter.transform.TransformPoint(lv);
|
||||
|
||||
//This is sort of ugly - inverting x-component since we're in
|
||||
//a different coordinate system than "everyone" is "used to".
|
||||
stringBuilder.Append(string.Format("v {0} {1} {2}\n", -wv.x, wv.y, wv.z));
|
||||
}
|
||||
stringBuilder.Append("\n");
|
||||
|
||||
foreach (Vector3 lv in mesh.normals)
|
||||
{
|
||||
Vector3 wv = _meshFilter.transform.TransformDirection(lv);
|
||||
|
||||
stringBuilder.Append(string.Format("vn {0} {1} {2}\n", -wv.x, wv.y, wv.z));
|
||||
}
|
||||
stringBuilder.Append("\n");
|
||||
|
||||
foreach (Vector3 v in mesh.uv)
|
||||
{
|
||||
stringBuilder.Append(string.Format("vt {0} {1}\n", v.x, v.y));
|
||||
}
|
||||
|
||||
for (int material = 0; material < mesh.subMeshCount; material++)
|
||||
{
|
||||
stringBuilder.Append("\n");
|
||||
stringBuilder.Append("usemtl ").Append(materials[material].name).Append("\n");
|
||||
stringBuilder.Append("usemap ").Append(materials[material].name).Append("\n");
|
||||
|
||||
//See if this material is already in the materiallist.
|
||||
try
|
||||
{
|
||||
ObjMaterial objMaterial = new ObjMaterial();
|
||||
|
||||
objMaterial.name = materials[material].name;
|
||||
|
||||
if (materials[material].mainTexture)
|
||||
{
|
||||
objMaterial.textureName = EngineIntegration.GetAssetPath(materials[material].mainTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
objMaterial.textureName = null;
|
||||
}
|
||||
|
||||
_materialList.Add(objMaterial.name, objMaterial);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
//Already in the dictionary
|
||||
}
|
||||
|
||||
|
||||
int[] triangles = mesh.GetTriangles(material);
|
||||
for (int index = 0; index < triangles.Length; index += 3)
|
||||
{
|
||||
//Because we inverted the x-component, we also needed to alter the triangle winding.
|
||||
stringBuilder.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n",
|
||||
triangles[index] + 1 + vertexOffset, triangles[index + 1] + 1 + normalOffset, triangles[index + 2] + 1 + uvOffset));
|
||||
}
|
||||
}
|
||||
|
||||
vertexOffset += mesh.vertices.Length;
|
||||
normalOffset += mesh.normals.Length;
|
||||
uvOffset += mesh.uv.Length;
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
|
||||
private static void Clear()
|
||||
{
|
||||
vertexOffset = 0;
|
||||
normalOffset = 0;
|
||||
uvOffset = 0;
|
||||
}
|
||||
|
||||
|
||||
private static Dictionary<string, ObjMaterial> PrepareFileWrite()
|
||||
{
|
||||
Clear();
|
||||
|
||||
return new Dictionary<string, ObjMaterial>();
|
||||
}
|
||||
|
||||
|
||||
private static void MaterialsToFile(Dictionary<string, ObjMaterial> _materialList, string _folder, string _fileName)
|
||||
{
|
||||
using (StreamWriter streamWriter = new StreamWriter(Path.Combine(_folder, _fileName) + ".mtl"))
|
||||
{
|
||||
foreach (KeyValuePair<string, ObjMaterial> kvp in _materialList)
|
||||
{
|
||||
streamWriter.Write("\n");
|
||||
streamWriter.Write("newmtl {0}\n", kvp.Key);
|
||||
streamWriter.Write("Ka 0.6 0.6 0.6\n");
|
||||
streamWriter.Write("Kd 0.6 0.6 0.6\n");
|
||||
streamWriter.Write("Ks 0.9 0.9 0.9\n");
|
||||
streamWriter.Write("d 1.0\n");
|
||||
streamWriter.Write("Ns 0.0\n");
|
||||
streamWriter.Write("illum 2\n");
|
||||
|
||||
if (kvp.Value.textureName != null)
|
||||
{
|
||||
string destinationFile = kvp.Value.textureName;
|
||||
|
||||
int stripIndex = destinationFile.LastIndexOf(Path.PathSeparator);
|
||||
|
||||
if (stripIndex >= 0)
|
||||
{
|
||||
destinationFile = destinationFile.Substring(stripIndex + 1).Trim();
|
||||
}
|
||||
|
||||
|
||||
string relativeFile = destinationFile;
|
||||
|
||||
destinationFile = Path.Combine(_folder, destinationFile);
|
||||
|
||||
//Debug.Log("Copying texture from " + kvp.Value.textureName + " to " + destinationFile);
|
||||
|
||||
try
|
||||
{
|
||||
//Copy the source file
|
||||
File.Copy(kvp.Value.textureName, destinationFile);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
streamWriter.Write("map_Kd {0}", relativeFile);
|
||||
}
|
||||
|
||||
streamWriter.Write("\n\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void MeshToFile(MeshFilter _meshFilter, string _folder, string _fileName)
|
||||
{
|
||||
Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
|
||||
|
||||
using (StreamWriter streamWriter = new StreamWriter(Path.Combine(_folder, _fileName) + ".obj"))
|
||||
{
|
||||
streamWriter.Write("mtllib ./" + _fileName + ".mtl\n");
|
||||
|
||||
streamWriter.Write(MeshToString(_meshFilter, materialList));
|
||||
}
|
||||
|
||||
MaterialsToFile(materialList, _folder, _fileName);
|
||||
}
|
||||
|
||||
|
||||
private static void MeshesToFile(MeshFilter[] _meshFilter, string _folder, string _fileName)
|
||||
{
|
||||
Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
|
||||
|
||||
using (StreamWriter streamWriter = new StreamWriter(Path.Combine(_folder, _fileName) + ".obj"))
|
||||
{
|
||||
streamWriter.Write("mtllib ./" + _fileName + ".mtl\n");
|
||||
|
||||
for (int index = 0; index < _meshFilter.Length; index++)
|
||||
{
|
||||
streamWriter.Write(MeshToString(_meshFilter[index], materialList));
|
||||
}
|
||||
}
|
||||
|
||||
MaterialsToFile(materialList, _folder, _fileName);
|
||||
}
|
||||
|
||||
|
||||
private static bool CreateTargetFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(targetFolder);
|
||||
}
|
||||
catch
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error!", "Failed to create target folder!", "");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Export/Export all MeshFilters in selection to separate OBJs")]
|
||||
private static void ExportSelectionToSeparate()
|
||||
{
|
||||
if (!CreateTargetFolder())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Transform[] selection = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
|
||||
|
||||
if (selection.Length == 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("No source object selected!", "Please select one or more target objects", "");
|
||||
return;
|
||||
}
|
||||
|
||||
int exportedObjects = 0;
|
||||
|
||||
for (int index = 0; index < selection.Length; index++)
|
||||
{
|
||||
Component[] meshfilter = selection[index].GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
for (int m = 0; m < meshfilter.Length; m++)
|
||||
{
|
||||
exportedObjects++;
|
||||
MeshToFile((MeshFilter)meshfilter[m], targetFolder, selection[index].name + "_" + index + "_" + m);
|
||||
}
|
||||
}
|
||||
|
||||
if (exportedObjects > 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Objects exported", "Exported " + exportedObjects + " objects", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Objects not exported", "Make sure at least some of your selected objects have mesh filters!", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Export/Export whole selection to single OBJ")]
|
||||
private static void ExportWholeSelectionToSingle()
|
||||
{
|
||||
if (!CreateTargetFolder())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Transform[] selection = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
|
||||
|
||||
if (selection.Length == 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("No source object selected!", "Please select one or more target objects", "");
|
||||
return;
|
||||
}
|
||||
|
||||
int exportedObjects = 0;
|
||||
|
||||
ArrayList mfList = new ArrayList();
|
||||
|
||||
for (int index = 0; index < selection.Length; index++)
|
||||
{
|
||||
Component[] meshfilter = selection[index].GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
for (int m = 0; m < meshfilter.Length; m++)
|
||||
{
|
||||
exportedObjects++;
|
||||
mfList.Add(meshfilter[m]);
|
||||
}
|
||||
}
|
||||
|
||||
if (exportedObjects > 0)
|
||||
{
|
||||
MeshFilter[] meshFilters = new MeshFilter[mfList.Count];
|
||||
|
||||
for (int index = 0; index < mfList.Count; index++)
|
||||
{
|
||||
meshFilters[index] = (MeshFilter)mfList[index];
|
||||
}
|
||||
|
||||
|
||||
string sceneName = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene().name;
|
||||
//string filename = EditorApplication.currentScene + "_" + exportedObjects;
|
||||
string filename = sceneName + "_" + exportedObjects;
|
||||
|
||||
int stripIndex = filename.LastIndexOf(Path.PathSeparator);
|
||||
|
||||
if (stripIndex >= 0)
|
||||
{
|
||||
filename = filename.Substring(stripIndex + 1).Trim();
|
||||
}
|
||||
|
||||
MeshesToFile(meshFilters, targetFolder, filename);
|
||||
|
||||
|
||||
EditorUtility.DisplayDialog("Objects exported", "Exported " + exportedObjects + " objects to " + filename, "");
|
||||
}
|
||||
else
|
||||
EditorUtility.DisplayDialog("Objects not exported", "Make sure at least some of your selected objects have mesh filters!", "");
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Export/Export each selected to single OBJ")]
|
||||
private static void ExportEachSelectionToSingle()
|
||||
{
|
||||
if (!CreateTargetFolder())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Transform[] selection = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
|
||||
|
||||
if (selection.Length == 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("No source object selected!", "Please select one or more target objects", "");
|
||||
return;
|
||||
}
|
||||
|
||||
int exportedObjects = 0;
|
||||
|
||||
|
||||
for (int index = 0; index < selection.Length; index++)
|
||||
{
|
||||
Component[] meshfilter = selection[index].GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
MeshFilter[] mf = new MeshFilter[meshfilter.Length];
|
||||
|
||||
for (int m = 0; m < meshfilter.Length; m++)
|
||||
{
|
||||
exportedObjects++;
|
||||
mf[m] = (MeshFilter)meshfilter[m];
|
||||
}
|
||||
|
||||
MeshesToFile(mf, targetFolder, selection[index].name + "_" + index);
|
||||
}
|
||||
|
||||
if (exportedObjects > 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Objects exported", "Exported " + exportedObjects + " objects", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Objects not exported", "Make sure at least some of your selected objects have mesh filters!", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Window/Road Architect/Export/Exporters by Hrafnkell Freyr Hlooversson from Unity3D wiki")]
|
||||
private static void OpenLink()
|
||||
{
|
||||
Application.OpenURL("http://wiki.unity3d.com/index.php?title=ObjExporter");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd895ddcc671fce4897906afe978103f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2d67b50d8bfdea40b03587f29096fa8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db6a849a9f10a2b4c947989f1bbf77a5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,378 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
[CustomEditor(typeof(RoadSystem))]
|
||||
public class RoadSystemEditor : Editor
|
||||
{
|
||||
#region "Vars"
|
||||
//Main target for this editor file:
|
||||
private RoadSystem roadSystem;
|
||||
|
||||
//Serialized properties:
|
||||
private SerializedProperty isAllowingUpdates;
|
||||
private SerializedProperty isTempMultithreading;
|
||||
private SerializedProperty isTempSaveMeshAssets;
|
||||
|
||||
//Editor only variables:
|
||||
private bool isInitialized;
|
||||
|
||||
// //Editor only camera variables:
|
||||
private RoadIntersection[] intersections = null;
|
||||
private int intersectionIndex = 0;
|
||||
private SplineN[] bridges = null;
|
||||
private int bridgesIndex = 0;
|
||||
private bool isBridgeInitialized = false;
|
||||
private bool isIntersectionInitialized = false;
|
||||
private bool isEditorCameraFlipped = false;
|
||||
private float cameraZoomFactor = 1f;
|
||||
private float cameraHeightOffset = 1f;
|
||||
private bool isCameraCustomRotated = false;
|
||||
private Vector3 customCameraRotation = new Vector3(0.5f, 0f, -0.5f);
|
||||
|
||||
//Editor only graphic variables:
|
||||
private Texture2D loadButtonBG = null;
|
||||
private Texture2D loadButtonBGGlow = null;
|
||||
private Texture2D warningLabelBG;
|
||||
private GUIStyle warningLabelStyle;
|
||||
private GUIStyle loadButton = null;
|
||||
#endregion
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
roadSystem = (RoadSystem)target;
|
||||
|
||||
isAllowingUpdates = serializedObject.FindProperty("isAllowingRoadUpdates");
|
||||
isTempMultithreading = serializedObject.FindProperty("isMultithreaded");
|
||||
isTempSaveMeshAssets = serializedObject.FindProperty("isSavingMeshes");
|
||||
}
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
EditorStyles.label.wordWrap = true;
|
||||
|
||||
if(!isInitialized)
|
||||
{
|
||||
isInitialized = true;
|
||||
InitChecks();
|
||||
}
|
||||
|
||||
//Add road button:
|
||||
RoadArchitect.EditorUtilities.DrawLine();
|
||||
if (GUILayout.Button("Add road", loadButton, GUILayout.Width(128f)))
|
||||
{
|
||||
Selection.activeObject = roadSystem.AddRoad();
|
||||
}
|
||||
RoadArchitect.EditorUtilities.DrawLine();
|
||||
|
||||
//Update all roads button:
|
||||
if (GUILayout.Button("Update all roads", EditorStyles.miniButton, GUILayout.Width(120f)))
|
||||
{
|
||||
roadSystem.UpdateAllRoads();
|
||||
}
|
||||
|
||||
isAllowingUpdates.boolValue = EditorGUILayout.Toggle("Allow Roads to Update", roadSystem.isAllowingRoadUpdates);
|
||||
|
||||
//Multi-threading input:
|
||||
isTempMultithreading.boolValue = EditorGUILayout.Toggle("Multi-threading enabled", roadSystem.isMultithreaded);
|
||||
if (isTempMultithreading.boolValue != roadSystem.isMultithreaded)
|
||||
{
|
||||
roadSystem.UpdateAllRoadsMultiThreadedOption(isTempMultithreading.boolValue);
|
||||
}
|
||||
|
||||
//Save mesh assets input:
|
||||
isTempSaveMeshAssets.boolValue = EditorGUILayout.Toggle("Save mesh assets: ", roadSystem.isSavingMeshes);
|
||||
if (isTempSaveMeshAssets.boolValue != roadSystem.isSavingMeshes)
|
||||
{
|
||||
roadSystem.UpdateAllRoadsSavingMeshesOption(isTempSaveMeshAssets.boolValue);
|
||||
}
|
||||
if (roadSystem.isSavingMeshes)
|
||||
{
|
||||
GUILayout.Label("WARNING: Saving meshes as assets is very slow and can increase road generation time by several minutes.", warningLabelStyle);
|
||||
}
|
||||
|
||||
//Online manual button:
|
||||
GUILayout.Space(4f);
|
||||
if (GUILayout.Button("Online manual", EditorStyles.miniButton, GUILayout.Width(120f)))
|
||||
{
|
||||
Application.OpenURL("https://github.com/MicroGSD/RoadArchitect/wiki");
|
||||
}
|
||||
|
||||
//Offline manual button:
|
||||
GUILayout.Space(4f);
|
||||
if (GUILayout.Button("Offline manual", EditorStyles.miniButton, GUILayout.Width(120f)))
|
||||
{
|
||||
RoadArchitect.EditorUtilities.OpenOfflineManual();
|
||||
}
|
||||
|
||||
if (roadSystem.editorPlayCamera == null)
|
||||
{
|
||||
roadSystem.EditorCameraSetSingle();
|
||||
}
|
||||
RoadArchitect.EditorUtilities.DrawLine();
|
||||
|
||||
//View intersection
|
||||
IntersectionView();
|
||||
//View bridges
|
||||
BridgeView();
|
||||
if(bridges.Length > 0 || intersections.Length > 0)
|
||||
{
|
||||
EditorGUILayout.LabelField("* Hotkeys only work when this RoadArchitectSystem object is selected and the scene view has focus", EditorStyles.miniLabel);
|
||||
}
|
||||
|
||||
|
||||
//Hotkey check:
|
||||
DoHotKeyCheck();
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(roadSystem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void InitChecks()
|
||||
{
|
||||
string basePath = RoadEditorUtility.GetBasePath();
|
||||
|
||||
RoadArchitect.EditorUtilities.LoadTexture(ref warningLabelBG, basePath + "/Editor/Icons/WarningLabelBG.png");
|
||||
RoadArchitect.EditorUtilities.LoadTexture(ref loadButtonBG, basePath + "/Editor/Icons/otherbg.png");
|
||||
RoadArchitect.EditorUtilities.LoadTexture(ref loadButtonBGGlow, basePath + "/Editor/Icons/otherbg2.png");
|
||||
|
||||
if (loadButton == null)
|
||||
{
|
||||
loadButton = new GUIStyle(GUI.skin.button);
|
||||
loadButton.contentOffset = new Vector2(0f, 1f);
|
||||
loadButton.normal.textColor = new Color(1f, 1f, 1f, 1f);
|
||||
loadButton.normal.background = loadButtonBG;
|
||||
loadButton.active.background = loadButtonBGGlow;
|
||||
loadButton.focused.background = loadButtonBGGlow;
|
||||
loadButton.hover.background = loadButtonBGGlow;
|
||||
loadButton.fixedHeight = 16f;
|
||||
loadButton.fixedWidth = 128f;
|
||||
loadButton.padding = new RectOffset(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (warningLabelStyle == null)
|
||||
{
|
||||
warningLabelStyle = new GUIStyle(GUI.skin.textArea);
|
||||
warningLabelStyle.normal.textColor = Color.red;
|
||||
warningLabelStyle.active.textColor = Color.red;
|
||||
warningLabelStyle.hover.textColor = Color.red;
|
||||
warningLabelStyle.normal.background = warningLabelBG;
|
||||
warningLabelStyle.active.background = warningLabelBG;
|
||||
warningLabelStyle.hover.background = warningLabelBG;
|
||||
warningLabelStyle.padding = new RectOffset(8, 8, 8, 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void IntersectionView()
|
||||
{
|
||||
//View intersection
|
||||
if (!isIntersectionInitialized)
|
||||
{
|
||||
isIntersectionInitialized = true;
|
||||
intersections = roadSystem.GetComponentsInChildren<RoadIntersection>();
|
||||
}
|
||||
if (intersections.Length > 0)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("View next intersection", GUILayout.Width(150f)))
|
||||
{
|
||||
IncrementIntersection();
|
||||
}
|
||||
EditorGUILayout.LabelField("Hotkey K");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void IncrementIntersection()
|
||||
{
|
||||
if (intersections.Length > 0)
|
||||
{
|
||||
intersectionIndex += 1;
|
||||
if (intersectionIndex >= intersections.Length)
|
||||
{
|
||||
intersectionIndex = 0;
|
||||
}
|
||||
ShowIntersection();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void BridgeView()
|
||||
{
|
||||
//View bridges
|
||||
if (!isBridgeInitialized)
|
||||
{
|
||||
isBridgeInitialized = true;
|
||||
SplineN[] nodes = roadSystem.transform.GetComponentsInChildren<SplineN>();
|
||||
List<SplineN> nodeList = new List<SplineN>();
|
||||
foreach (SplineN node in nodes)
|
||||
{
|
||||
if (node.isBridgeStart && node.isBridgeMatched)
|
||||
{
|
||||
nodeList.Add(node);
|
||||
}
|
||||
}
|
||||
bridges = nodeList.ToArray();
|
||||
bridgesIndex = 0;
|
||||
}
|
||||
|
||||
if (bridges.Length > 0)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("View next bridge", GUILayout.Width(150f)))
|
||||
{
|
||||
IncrementBridge();
|
||||
}
|
||||
EditorGUILayout.LabelField("Hotkey L");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
bool isCameraFlipped = EditorGUILayout.Toggle("Flip camera Y:", isEditorCameraFlipped);
|
||||
if (isCameraFlipped != isEditorCameraFlipped)
|
||||
{
|
||||
isEditorCameraFlipped = isCameraFlipped;
|
||||
ShowBridge();
|
||||
}
|
||||
|
||||
float changeChecker = EditorGUILayout.Slider("Zoom factor:", cameraZoomFactor, 0.02f, 10f);
|
||||
if (!RootUtils.IsApproximately(changeChecker, cameraZoomFactor, 0.001f))
|
||||
{
|
||||
cameraZoomFactor = changeChecker;
|
||||
ShowBridge();
|
||||
}
|
||||
changeChecker = EditorGUILayout.Slider("Height offset:", cameraHeightOffset, 0f, 8f);
|
||||
if (!RootUtils.IsApproximately(changeChecker, cameraHeightOffset, 0.001f))
|
||||
{
|
||||
cameraHeightOffset = changeChecker;
|
||||
ShowBridge();
|
||||
}
|
||||
|
||||
bool isCustomRotated = EditorGUILayout.Toggle("Custom camera rot:", isCameraCustomRotated);
|
||||
if (isCustomRotated != isCameraCustomRotated)
|
||||
{
|
||||
isCameraCustomRotated = isCustomRotated;
|
||||
ShowBridge();
|
||||
}
|
||||
if (isCameraCustomRotated)
|
||||
{
|
||||
Vector3 changedRotation = default(Vector3);
|
||||
changedRotation.x = EditorGUILayout.Slider("Rotation X:", customCameraRotation.x, -1f, 1f);
|
||||
changedRotation.z = EditorGUILayout.Slider("Rotation Z:", customCameraRotation.z, -1f, 1f);
|
||||
|
||||
if (changedRotation != customCameraRotation)
|
||||
{
|
||||
customCameraRotation = changedRotation;
|
||||
ShowBridge();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void IncrementBridge()
|
||||
{
|
||||
if (bridges.Length > 0)
|
||||
{
|
||||
bridgesIndex += 1;
|
||||
if (bridgesIndex >= bridges.Length)
|
||||
{
|
||||
bridgesIndex = 0;
|
||||
}
|
||||
ShowBridge();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ShowIntersection()
|
||||
{
|
||||
if (EditorApplication.isPlaying && roadSystem.editorPlayCamera != null)
|
||||
{
|
||||
roadSystem.editorPlayCamera.transform.position = intersections[intersectionIndex].transform.position + new Vector3(-40f, 20f, -40f);
|
||||
roadSystem.editorPlayCamera.transform.rotation = Quaternion.LookRotation(intersections[intersectionIndex].transform.position - (intersections[intersectionIndex].transform.position + new Vector3(-40f, 20f, -40f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneView.lastActiveSceneView.pivot = intersections[intersectionIndex].transform.position;
|
||||
SceneView.lastActiveSceneView.Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ShowBridge()
|
||||
{
|
||||
if (EditorApplication.isPlaying && roadSystem.editorPlayCamera != null)
|
||||
{
|
||||
Vector3 bridgePosition = ((bridges[bridgesIndex].pos - bridges[bridgesIndex].bridgeCounterpartNode.pos) * 0.5f) + bridges[bridgesIndex].bridgeCounterpartNode.pos;
|
||||
float bridgeLength = Vector3.Distance(bridges[bridgesIndex].pos, bridges[bridgesIndex].bridgeCounterpartNode.pos);
|
||||
|
||||
//Rotation:
|
||||
Vector3 cameraRotation = Vector3.Cross((bridges[bridgesIndex].pos - bridges[bridgesIndex].bridgeCounterpartNode.pos), Vector3.up);
|
||||
if (isCameraCustomRotated)
|
||||
{
|
||||
cameraRotation = customCameraRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraRotation = cameraRotation.normalized;
|
||||
}
|
||||
|
||||
//Calc offset:
|
||||
Vector3 bridgeOffset = cameraRotation * (bridgeLength * 0.5f * cameraZoomFactor);
|
||||
|
||||
//Height offset:
|
||||
bridgeOffset.y = Mathf.Lerp(20f, 120f, (bridgeLength * 0.001f)) * cameraZoomFactor * cameraHeightOffset;
|
||||
|
||||
roadSystem.editorPlayCamera.transform.position = bridgePosition + bridgeOffset;
|
||||
roadSystem.editorPlayCamera.transform.rotation = Quaternion.LookRotation(bridgePosition - (bridgePosition + bridgeOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneView.lastActiveSceneView.pivot = bridges[bridgesIndex].transform.position;
|
||||
SceneView.lastActiveSceneView.Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void OnSceneGUI()
|
||||
{
|
||||
DoHotKeyCheck();
|
||||
}
|
||||
|
||||
|
||||
private void DoHotKeyCheck()
|
||||
{
|
||||
Event current = Event.current;
|
||||
|
||||
if (current.type == EventType.KeyDown)
|
||||
{
|
||||
if (current.keyCode == KeyCode.K)
|
||||
{
|
||||
IncrementIntersection();
|
||||
}
|
||||
else if (current.keyCode == KeyCode.L)
|
||||
{
|
||||
IncrementBridge();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d698b63effc4b914e93d9826206bee51
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,297 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.IO;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
public class SaveWindow : EditorWindow
|
||||
{
|
||||
public enum WindowTypeEnum
|
||||
{
|
||||
Extrusion,
|
||||
Edge,
|
||||
BridgeWizard
|
||||
};
|
||||
|
||||
|
||||
#region "Vars"
|
||||
private WindowTypeEnum windowType = WindowTypeEnum.Extrusion;
|
||||
|
||||
private Texture2D temp2D = null;
|
||||
private Texture2D temp2D2 = null;
|
||||
private string thumbString = "";
|
||||
private string desc = "";
|
||||
private string fileName = "DefaultName";
|
||||
private string displayName = "DefaultName";
|
||||
private string displayName2 = "";
|
||||
private string titleText = "";
|
||||
// private string tPath = "";
|
||||
private bool isFileExisting = false;
|
||||
private bool isBridge = false;
|
||||
|
||||
private Splination.SplinatedMeshMaker[] tSMMs = null;
|
||||
private EdgeObjects.EdgeObjectMaker[] tEOMs = null;
|
||||
private string path = "";
|
||||
private const int titleLabelHeight = 20;
|
||||
#endregion
|
||||
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
GUILayout.Space(4f);
|
||||
EditorGUILayout.LabelField(titleText, EditorStyles.boldLabel);
|
||||
|
||||
temp2D2 = (Texture2D)EditorGUILayout.ObjectField("Square thumb (optional):", temp2D, typeof(Texture2D), false);
|
||||
if (temp2D2 != temp2D)
|
||||
{
|
||||
temp2D = temp2D2;
|
||||
thumbString = EngineIntegration.GetAssetPath(temp2D);
|
||||
}
|
||||
|
||||
if (path.Length < 5)
|
||||
{
|
||||
path = RootUtils.GetDirLibrary();
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("Short description (optional):");
|
||||
desc = EditorGUILayout.TextArea(desc, GUILayout.Height(40f));
|
||||
displayName2 = EditorGUILayout.TextField("Display name:", displayName);
|
||||
if (string.Compare(displayName2, displayName) != 0)
|
||||
{
|
||||
displayName = displayName2;
|
||||
SanitizeFilename();
|
||||
|
||||
CheckFileExistence();
|
||||
}
|
||||
|
||||
|
||||
if (isFileExisting)
|
||||
{
|
||||
EditorGUILayout.LabelField("File exists already!", EditorStyles.miniLabel);
|
||||
}
|
||||
|
||||
if (windowType == WindowTypeEnum.Edge)
|
||||
{
|
||||
EditorGUILayout.LabelField(Path.Combine(path, "EOM" + fileName + ".rao"), EditorStyles.miniLabel);
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
EditorGUILayout.LabelField(Path.Combine(path, "ESO" + fileName + ".rao"), EditorStyles.miniLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField(Path.Combine(Path.Combine(path, "Groups"), fileName + ".rao"), EditorStyles.miniLabel);
|
||||
}
|
||||
|
||||
GUILayout.Space(4f);
|
||||
|
||||
isBridge = EditorGUILayout.Toggle("Is bridge related:", isBridge);
|
||||
GUILayout.Space(8f);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Cancel"))
|
||||
{
|
||||
Close();
|
||||
}
|
||||
if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
DoExtrusion();
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Edge)
|
||||
{
|
||||
DoEdgeObject();
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.BridgeWizard)
|
||||
{
|
||||
DoBridge();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
private void DoExtrusion()
|
||||
{
|
||||
if (GUILayout.Button("Save extrusion"))
|
||||
{
|
||||
SanitizeFilename();
|
||||
tSMMs[0].isBridge = isBridge;
|
||||
tSMMs[0].thumbString = thumbString;
|
||||
tSMMs[0].desc = desc;
|
||||
tSMMs[0].displayName = displayName;
|
||||
tSMMs[0].SaveToLibrary(fileName, false);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DoEdgeObject()
|
||||
{
|
||||
if (GUILayout.Button("Save edge object"))
|
||||
{
|
||||
SanitizeFilename();
|
||||
tEOMs[0].isBridge = isBridge;
|
||||
tEOMs[0].thumbString = thumbString;
|
||||
tEOMs[0].desc = desc;
|
||||
tEOMs[0].displayName = displayName;
|
||||
tEOMs[0].SaveToLibrary(fileName, false);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DoBridge()
|
||||
{
|
||||
if (GUILayout.Button("Save group"))
|
||||
{
|
||||
SanitizeFilename();
|
||||
WizardObject WO = new WizardObject();
|
||||
WO.thumbString = thumbString;
|
||||
WO.desc = desc;
|
||||
WO.displayName = displayName;
|
||||
WO.fileName = fileName;
|
||||
WO.isBridge = isBridge;
|
||||
WO.isDefault = false;
|
||||
|
||||
RoadUtility.SaveNodeObjects(ref tSMMs, ref tEOMs, ref WO);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SanitizeFilename()
|
||||
{
|
||||
Regex regex = new Regex("[^a-zA-Z0-9 -]");
|
||||
fileName = regex.Replace(displayName, "");
|
||||
fileName = fileName.Replace(" ", "-");
|
||||
fileName = fileName.Replace("_", "-");
|
||||
}
|
||||
|
||||
|
||||
private void CheckFileExistence()
|
||||
{
|
||||
if (windowType == WindowTypeEnum.Edge)
|
||||
{
|
||||
if (File.Exists(Path.Combine(path, "EOM" + fileName + ".rao")))
|
||||
{
|
||||
isFileExisting = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isFileExisting = false;
|
||||
}
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
if (File.Exists(Path.Combine(path, "ESO" + fileName + ".rao")))
|
||||
{
|
||||
isFileExisting = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isFileExisting = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (File.Exists(Path.Combine(Path.Combine(path, "B"), fileName + ".rao")))
|
||||
{
|
||||
isFileExisting = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isFileExisting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region "Init"
|
||||
public void Initialize(ref Rect _rect, WindowTypeEnum _windowType, SplineN _node, Splination.SplinatedMeshMaker _SMM = null, EdgeObjects.EdgeObjectMaker _EOM = null)
|
||||
{
|
||||
int rectHeight = 300;
|
||||
int rectWidth = 360;
|
||||
float Rx = ((float)_rect.width / 2f) - ((float)rectWidth / 2f) + _rect.x;
|
||||
float Ry = ((float)_rect.height / 2f) - ((float)rectHeight / 2f) + _rect.y;
|
||||
|
||||
if (Rx < 0)
|
||||
{
|
||||
Rx = _rect.x;
|
||||
}
|
||||
if (Ry < 0)
|
||||
{
|
||||
Ry = _rect.y;
|
||||
}
|
||||
if (Rx > (_rect.width + _rect.x))
|
||||
{
|
||||
Rx = _rect.x;
|
||||
}
|
||||
if (Ry > (_rect.height + _rect.y))
|
||||
{
|
||||
Ry = _rect.y;
|
||||
}
|
||||
|
||||
Rect rect = new Rect(Rx, Ry, rectWidth, rectHeight);
|
||||
|
||||
if (rect.width < 300)
|
||||
{
|
||||
rect.width = 300;
|
||||
rect.x = _rect.x;
|
||||
}
|
||||
if (rect.height < 300)
|
||||
{
|
||||
rect.height = 300;
|
||||
rect.y = _rect.y;
|
||||
}
|
||||
|
||||
position = rect;
|
||||
windowType = _windowType;
|
||||
Show();
|
||||
titleContent.text = "Save";
|
||||
if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
titleText = "Save extrusion";
|
||||
tSMMs = new Splination.SplinatedMeshMaker[1];
|
||||
tSMMs[0] = _SMM;
|
||||
if (_SMM != null)
|
||||
{
|
||||
fileName = _SMM.objectName;
|
||||
displayName = fileName;
|
||||
}
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Edge)
|
||||
{
|
||||
titleText = "Save edge object";
|
||||
tEOMs = new EdgeObjects.EdgeObjectMaker[1];
|
||||
tEOMs[0] = _EOM;
|
||||
if (_EOM != null)
|
||||
{
|
||||
fileName = _EOM.objectName;
|
||||
displayName = fileName;
|
||||
}
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.BridgeWizard)
|
||||
{
|
||||
isBridge = true;
|
||||
tSMMs = _node.SplinatedObjects.ToArray();
|
||||
tEOMs = _node.EdgeObjects.ToArray();
|
||||
titleText = "Save group";
|
||||
fileName = "Group" + Random.Range(0, 10000).ToString();
|
||||
displayName = fileName;
|
||||
}
|
||||
|
||||
if (path.Length < 5)
|
||||
{
|
||||
path = RootUtils.GetDirLibrary();
|
||||
}
|
||||
|
||||
CheckFileExistence();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d228ad4f1407c8439cc06fbea6105f3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,41 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
[CustomEditor(typeof(SplineC))]
|
||||
public class SplineCEditor : Editor
|
||||
{
|
||||
private SplineC spline;
|
||||
private int browseNode = 0;
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
spline = (SplineC)target;
|
||||
}
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
#region NodeBrowser
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Browse to node:", EditorStyles.boldLabel);
|
||||
browseNode = EditorGUILayout.IntField(browseNode);
|
||||
if (GUILayout.Button("Browse"))
|
||||
{
|
||||
if (browseNode < spline.nodes.Count)
|
||||
{
|
||||
Selection.objects = new Object[1] { spline.nodes[browseNode] };
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d58d1757d440da4d888627fc1b0d993
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,27 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEditor;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
[CustomEditor(typeof(SplineF))]
|
||||
public class SplineFEditor : Editor
|
||||
{
|
||||
private SplineF splineF;
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
splineF = (SplineF)target;
|
||||
}
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
//Intentionally left empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dd0c2cac8820d84ea773a41ba7cde2f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,27 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEditor;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
[CustomEditor(typeof(SplineI))]
|
||||
public class SplineIEditor : Editor
|
||||
{
|
||||
private SplineI splineI;
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
splineI = (SplineI)target;
|
||||
}
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
//Intentionally left empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ca689edb7ae35b43b50bd73fc934e96
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b18264adf12b2e4fad840ded7592b28
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,304 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
[CustomEditor(typeof(RoadTerrain))]
|
||||
public class TerrainEditor : Editor
|
||||
{
|
||||
#region "Vars"
|
||||
private RoadTerrain terrain;
|
||||
|
||||
//Serialized properties:
|
||||
SerializedProperty splatImageWidth;
|
||||
SerializedProperty splatImageHeight;
|
||||
SerializedProperty splatBackgroundColor;
|
||||
SerializedProperty splatForegroundColor;
|
||||
SerializedProperty splatWidth;
|
||||
SerializedProperty isSkippingBridges;
|
||||
SerializedProperty isSkippingTunnels;
|
||||
SerializedProperty isSplatSingleRoad;
|
||||
SerializedProperty splatSingleChoiceIndex;
|
||||
SerializedProperty roadSingleChoiceUID;
|
||||
|
||||
//Editor only variables:
|
||||
private bool isInitialized;
|
||||
private string[] roads = null;
|
||||
private string[] roadsString = null;
|
||||
private Texture refreshButtonText = null;
|
||||
private GUIStyle imageButton = null;
|
||||
private Texture2D loadButtonBG = null;
|
||||
private Texture2D loadButtonBGGlow = null;
|
||||
private GUIStyle loadButton = null;
|
||||
SplatImageResoMatchingEnum splatReso = SplatImageResoMatchingEnum.None;
|
||||
#endregion
|
||||
|
||||
|
||||
public enum SplatImageResoMatchingEnum
|
||||
{
|
||||
None,
|
||||
Match512x512,
|
||||
Match1024x1024,
|
||||
Match2048x2048,
|
||||
Match4096x4096,
|
||||
MatchHeightmapResolution,
|
||||
MatchDetailResolution,
|
||||
MatchTerrainSize
|
||||
};
|
||||
|
||||
|
||||
private static string[] TheSplatResoOptions = new string[]{
|
||||
"Select option to match resolution",
|
||||
"512 x 512",
|
||||
"1024 x 1024",
|
||||
"2048 x 2048",
|
||||
"4096 x 4096",
|
||||
"Match heightmap resolution",
|
||||
"Match detail resolution",
|
||||
"Match terrain size"
|
||||
};
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
terrain = (RoadTerrain)target;
|
||||
|
||||
splatImageWidth = serializedObject.FindProperty("splatResoWidth");
|
||||
splatImageHeight = serializedObject.FindProperty("splatResoHeight");
|
||||
splatBackgroundColor = serializedObject.FindProperty("splatBackground");
|
||||
splatForegroundColor = serializedObject.FindProperty("splatForeground");
|
||||
splatWidth = serializedObject.FindProperty("splatWidth");
|
||||
isSkippingBridges = serializedObject.FindProperty("isSplatSkipBridges");
|
||||
isSkippingTunnels = serializedObject.FindProperty("isSplatSkipTunnels");
|
||||
isSplatSingleRoad = serializedObject.FindProperty("isSplatSingleRoad");
|
||||
splatSingleChoiceIndex = serializedObject.FindProperty("splatSingleChoiceIndex");
|
||||
roadSingleChoiceUID = serializedObject.FindProperty("roadSingleChoiceUID");
|
||||
}
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
if(!isInitialized)
|
||||
{
|
||||
isInitialized = true;
|
||||
InitNullChecks();
|
||||
}
|
||||
|
||||
RoadArchitect.EditorUtilities.DrawLine();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
//Main label:
|
||||
EditorGUILayout.LabelField("Splat map generation:", EditorStyles.boldLabel);
|
||||
//Online manual button:
|
||||
if (GUILayout.Button("Online manual", EditorStyles.miniButton, GUILayout.Width(120f)))
|
||||
{
|
||||
Application.OpenURL("https://github.com/MicroGSD/RoadArchitect/wiki");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.Space(6f);
|
||||
|
||||
//Splat Resolution input:
|
||||
splatImageWidth.intValue = terrain.splatResoWidth;
|
||||
splatImageHeight.intValue = terrain.splatResoHeight;
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
splatReso = (SplatImageResoMatchingEnum)EditorGUILayout.Popup("Match resolutions:", (int)splatReso, TheSplatResoOptions);
|
||||
if (GUILayout.Button(refreshButtonText, imageButton, GUILayout.Width(16f)))
|
||||
{
|
||||
splatImageWidth.intValue = 1024;
|
||||
splatImageHeight.intValue = 1024;
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (splatReso != SplatImageResoMatchingEnum.None)
|
||||
{
|
||||
if (splatReso == SplatImageResoMatchingEnum.MatchHeightmapResolution)
|
||||
{
|
||||
splatImageWidth.intValue = terrain.terrain.terrainData.heightmapResolution;
|
||||
splatImageHeight.intValue = terrain.terrain.terrainData.heightmapResolution;
|
||||
}
|
||||
else if (splatReso == SplatImageResoMatchingEnum.MatchDetailResolution)
|
||||
{
|
||||
splatImageWidth.intValue = terrain.terrain.terrainData.detailResolution;
|
||||
splatImageHeight.intValue = terrain.terrain.terrainData.detailResolution;
|
||||
}
|
||||
else if (splatReso == SplatImageResoMatchingEnum.MatchTerrainSize)
|
||||
{
|
||||
splatImageWidth.intValue = (int)terrain.terrain.terrainData.size.x;
|
||||
splatImageHeight.intValue = (int)terrain.terrain.terrainData.size.z;
|
||||
}
|
||||
else if (splatReso == SplatImageResoMatchingEnum.Match512x512)
|
||||
{
|
||||
splatImageWidth.intValue = 512;
|
||||
splatImageHeight.intValue = 512;
|
||||
}
|
||||
else if (splatReso == SplatImageResoMatchingEnum.Match1024x1024)
|
||||
{
|
||||
splatImageWidth.intValue = 1024;
|
||||
splatImageHeight.intValue = 1024;
|
||||
}
|
||||
else if (splatReso == SplatImageResoMatchingEnum.Match2048x2048)
|
||||
{
|
||||
splatImageWidth.intValue = 2048;
|
||||
splatImageHeight.intValue = 2048;
|
||||
}
|
||||
else if (splatReso == SplatImageResoMatchingEnum.Match4096x4096)
|
||||
{
|
||||
splatImageWidth.intValue = 4096;
|
||||
splatImageHeight.intValue = 4096;
|
||||
}
|
||||
splatReso = SplatImageResoMatchingEnum.None;
|
||||
}
|
||||
|
||||
//Splat image width input:
|
||||
splatImageWidth.intValue = EditorGUILayout.IntField("Splat image width:", splatImageWidth.intValue);
|
||||
//Splat image height input:
|
||||
splatImageHeight.intValue = EditorGUILayout.IntField("Splat image height:", splatImageHeight.intValue);
|
||||
|
||||
|
||||
//Splat background color input:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
splatBackgroundColor.colorValue = EditorGUILayout.ColorField("Splat background:", terrain.splatBackground);
|
||||
//Default button:
|
||||
if (GUILayout.Button(refreshButtonText, imageButton, GUILayout.Width(16f)))
|
||||
{
|
||||
splatBackgroundColor.colorValue = new Color(0f, 0f, 0f, 1f);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
//Splat foreground color input:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
splatForegroundColor.colorValue = EditorGUILayout.ColorField("Splat foreground:", terrain.splatForeground);
|
||||
//Default button:
|
||||
if (GUILayout.Button(refreshButtonText, imageButton, GUILayout.Width(16f)))
|
||||
{
|
||||
splatForegroundColor.colorValue = new Color(1f, 1f, 1f, 1f);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
//Splat width (meters) input:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
splatWidth.floatValue = EditorGUILayout.Slider("Splat width (meters):", terrain.splatWidth, 0.02f, 256f);
|
||||
//Default button:
|
||||
if (GUILayout.Button(refreshButtonText, imageButton, GUILayout.Width(16f)))
|
||||
{
|
||||
splatWidth.floatValue = 30f;
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
//Skip bridges:
|
||||
isSkippingBridges.boolValue = EditorGUILayout.Toggle("Skip bridges: ", terrain.isSplatSkipBridges);
|
||||
|
||||
//Skip tunnels:
|
||||
isSkippingTunnels.boolValue = EditorGUILayout.Toggle("Skip tunnels: ", terrain.isSplatSkipTunnels);
|
||||
|
||||
//Splat single road bool input:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
isSplatSingleRoad.boolValue = EditorGUILayout.Toggle("Splat a single road: ", terrain.isSplatSingleRoad);
|
||||
|
||||
//Splat single road , road input:
|
||||
if (terrain.isSplatSingleRoad)
|
||||
{
|
||||
LoadSplatSingleChoice();
|
||||
splatSingleChoiceIndex.intValue = EditorGUILayout.Popup(terrain.splatSingleChoiceIndex, roadsString, GUILayout.Width(150f));
|
||||
roadSingleChoiceUID.stringValue = roads[splatSingleChoiceIndex.intValue];
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
//Generate splatmap button:
|
||||
GUILayout.Space(8f);
|
||||
if (GUILayout.Button("Generate splatmap for this terrain"))
|
||||
{
|
||||
GenerateSplatMap();
|
||||
}
|
||||
GUILayout.Space(10f);
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
//Necessary?
|
||||
//EditorUtility.SetDirty(target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void InitNullChecks()
|
||||
{
|
||||
string basePath = RoadEditorUtility.GetBasePath();
|
||||
|
||||
RoadArchitect.EditorUtilities.LoadTexture(ref refreshButtonText, basePath + "/Editor/Icons/refresh2.png");
|
||||
RoadArchitect.EditorUtilities.LoadTexture(ref loadButtonBG, basePath + "/Editor/Icons/FlexBG.png");
|
||||
RoadArchitect.EditorUtilities.LoadTexture(ref loadButtonBGGlow, basePath + "/Editor/Icons/FlexBG.png");
|
||||
|
||||
if (imageButton == null)
|
||||
{
|
||||
imageButton = new GUIStyle(GUI.skin.button);
|
||||
imageButton.contentOffset = new Vector2(0f, 0f);
|
||||
imageButton.border = new RectOffset(0, 0, 0, 0);
|
||||
imageButton.fixedHeight = 16f;
|
||||
imageButton.padding = new RectOffset(0, 0, 0, 0);
|
||||
imageButton.normal.background = null;
|
||||
}
|
||||
|
||||
if (loadButton == null)
|
||||
{
|
||||
loadButton = new GUIStyle(GUI.skin.button);
|
||||
loadButton.contentOffset = new Vector2(0f, 1f);
|
||||
loadButton.normal.textColor = new Color(1f, 1f, 1f, 1f);
|
||||
loadButton.normal.background = loadButtonBG;
|
||||
loadButton.active.background = loadButtonBGGlow;
|
||||
loadButton.focused.background = loadButtonBGGlow;
|
||||
loadButton.hover.background = loadButtonBGGlow;
|
||||
loadButton.fixedHeight = 16f;
|
||||
loadButton.padding = new RectOffset(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void LoadSplatSingleChoice()
|
||||
{
|
||||
roads = null;
|
||||
roadsString = null;
|
||||
Object[] allRoads = GameObject.FindObjectsOfType<Road>();
|
||||
int roadsCount = allRoads.Length;
|
||||
roads = new string[roadsCount];
|
||||
roadsString = new string[roadsCount];
|
||||
int counter = 0;
|
||||
foreach (Road road in allRoads)
|
||||
{
|
||||
roads[counter] = road.UID;
|
||||
roadsString[counter] = road.transform.name;
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void GenerateSplatMap()
|
||||
{
|
||||
byte[] bytes = null;
|
||||
if (terrain.isSplatSingleRoad && terrain.roadSingleChoiceUID != "")
|
||||
{
|
||||
bytes = RoadUtility.MakeSplatMap(terrain.terrain, terrain.splatBackground, terrain.splatForeground, terrain.splatResoWidth, terrain.splatResoHeight, terrain.splatWidth, terrain.isSplatSkipBridges, terrain.isSplatSkipTunnels, terrain.roadSingleChoiceUID);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = RoadUtility.MakeSplatMap(terrain.terrain, terrain.splatBackground, terrain.splatForeground, terrain.splatResoWidth, terrain.splatResoHeight, terrain.splatWidth, terrain.isSplatSkipBridges, terrain.isSplatSkipTunnels);
|
||||
}
|
||||
|
||||
if (bytes != null && bytes.Length > 3)
|
||||
{
|
||||
string path = UnityEditor.EditorUtility.SaveFilePanel("Save splat map", Application.dataPath, "Splat", "png");
|
||||
if (path != null && path.Length > 3)
|
||||
{
|
||||
System.IO.File.WriteAllBytes(path, bytes);
|
||||
}
|
||||
bytes = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a8e0720738e16f42b9c3590ab753d23
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,559 @@
|
||||
#if UNITY_EDITOR
|
||||
#region "Imports"
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace RoadArchitect
|
||||
{
|
||||
public class Wizard : EditorWindow
|
||||
{
|
||||
public enum WindowTypeEnum
|
||||
{
|
||||
Extrusion,
|
||||
Edge,
|
||||
Groups,
|
||||
BridgeComplete,
|
||||
};
|
||||
|
||||
|
||||
private readonly string[] WindowTypeDescBridge = new string[]{
|
||||
"Extrusion items",
|
||||
"Edge objects",
|
||||
"Other groups",
|
||||
"Complete bridges",
|
||||
};
|
||||
|
||||
|
||||
private readonly string[] WindowTypeDesc = new string[]{
|
||||
"Extrusion items",
|
||||
"Edge objects",
|
||||
"Other groups"
|
||||
};
|
||||
|
||||
|
||||
#region "Vars"
|
||||
private WindowTypeEnum windowType = WindowTypeEnum.Extrusion;
|
||||
private WindowTypeEnum windowTypePrevious = WindowTypeEnum.Extrusion;
|
||||
private static string path = "";
|
||||
|
||||
private GUIStyle thumbStyle;
|
||||
private Vector2 scrollPos = new Vector2(0f, 25f);
|
||||
private SplineN thisNode = null;
|
||||
private List<WizardObject> objectList = null;
|
||||
private bool isUsingNoGUI = false;
|
||||
public Rect rect;
|
||||
#endregion
|
||||
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
DoGUI();
|
||||
}
|
||||
|
||||
|
||||
private void DoGUI()
|
||||
{
|
||||
if (isUsingNoGUI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (objectList == null)
|
||||
{
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.Space(4f);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
string[] options = thisNode.isBridgeStart ? WindowTypeDescBridge : WindowTypeDesc;
|
||||
if (!thisNode.isBridgeStart && windowType == WindowTypeEnum.BridgeComplete)
|
||||
{
|
||||
// Prevent category error when changing from bridge to normal node
|
||||
windowType = WindowTypeEnum.Extrusion;
|
||||
}
|
||||
windowType = (WindowTypeEnum)EditorGUILayout.Popup("Category: ", (int)windowType, options, GUILayout.Width(312f));
|
||||
|
||||
if (windowType != windowTypePrevious)
|
||||
{
|
||||
windowTypePrevious = windowType;
|
||||
InitWindow();
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("");
|
||||
EditorGUILayout.LabelField("Single-click items to load", EditorStyles.boldLabel, GUILayout.Width(200f));
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
if (objectList.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int objectCount = objectList.Count;
|
||||
|
||||
int spacingWidth = 160;
|
||||
int spacingHeight = 200;
|
||||
int heightOffset = 30;
|
||||
int scrollHeightOffset = 25;
|
||||
|
||||
int xCount = 0;
|
||||
int yCount = 0;
|
||||
int yMod = Mathf.FloorToInt((float)position.width / 142f) - 1;
|
||||
|
||||
int yMax = 0;
|
||||
if (yMod == 0)
|
||||
{
|
||||
yMax = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
yMax = Mathf.CeilToInt((float)objectCount / (float)yMod);
|
||||
}
|
||||
|
||||
bool isScrolling = false;
|
||||
if ((((yMax) * spacingHeight) + 25) > position.height)
|
||||
{
|
||||
scrollPos = GUI.BeginScrollView(new Rect(0, 25, position.width - 10, position.height - 30), scrollPos, new Rect(0, 0, (yMod * spacingWidth) + 25, (((yMax) * spacingHeight) + 50)));
|
||||
isScrolling = true;
|
||||
heightOffset = scrollHeightOffset;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
bool isClicked = false;
|
||||
for (int i = 0; i < objectCount; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
if (yMod == 0)
|
||||
{
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
yCount += 1;
|
||||
xCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i % yMod == 0)
|
||||
{
|
||||
EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); yCount += 1; xCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xCount == 0)
|
||||
{
|
||||
isClicked = DoItem((xCount * spacingWidth) + 5, (yCount * spacingHeight) + heightOffset, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
isClicked = DoItem(xCount * spacingWidth, (yCount * spacingHeight) + heightOffset, i);
|
||||
}
|
||||
|
||||
if (isClicked)
|
||||
{
|
||||
if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
Splination.SplinatedMeshMaker SMM = thisNode.AddSplinatedObject();
|
||||
SMM.SetDefaultTimes(thisNode.isEndPoint, thisNode.time, thisNode.nextTime, thisNode.idOnSpline, thisNode.spline.distance);
|
||||
SMM.LoadFromLibrary(objectList[i].fileName, objectList[i].isDefault);
|
||||
thisNode.CheckRenameSplinatedObject(SMM);
|
||||
SMM.isDefault = objectList[i].isDefault;
|
||||
SMM.Setup(true);
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Edge)
|
||||
{
|
||||
EdgeObjects.EdgeObjectMaker EOM = thisNode.AddEdgeObject();
|
||||
EOM.SetDefaultTimes(thisNode.isEndPoint, thisNode.time, thisNode.nextTime, thisNode.idOnSpline, thisNode.spline.distance);
|
||||
EOM.LoadFromLibrary(objectList[i].fileName, objectList[i].isDefault);
|
||||
thisNode.CheckRenameEdgeObject(EOM);
|
||||
EOM.isDefault = objectList[i].isDefault;
|
||||
EOM.Setup();
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Groups)
|
||||
{
|
||||
thisNode.LoadWizardObjectsFromLibrary(objectList[i].fileName, objectList[i].isDefault, objectList[i].isBridge);
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.BridgeComplete)
|
||||
{
|
||||
thisNode.LoadWizardObjectsFromLibrary(objectList[i].fileName, objectList[i].isDefault, objectList[i].isBridge);
|
||||
}
|
||||
objectList.Clear();
|
||||
objectList = null;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
if (isScrolling)
|
||||
{
|
||||
GUI.EndScrollView();
|
||||
}
|
||||
isUsingNoGUI = true;
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
xCount += 1;
|
||||
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (isScrolling)
|
||||
{
|
||||
GUI.EndScrollView();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool DoItem(int _x1, int _y1, int _i)
|
||||
{
|
||||
if (objectList[_i].thumb != null)
|
||||
{
|
||||
if (GUI.Button(new Rect(_x1, _y1, 132f, 132f), objectList[_i].thumb))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUI.Button(new Rect(_x1, _y1, 132f, 132f), "No image"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
GUI.Label(new Rect(_x1, _y1 + 132f, 148f, 20f), objectList[_i].displayName, EditorStyles.boldLabel);
|
||||
GUI.Label(new Rect(_x1, _y1 + 148f, 148f, 52f), objectList[_i].desc, EditorStyles.miniLabel);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#region "Init"
|
||||
/// <summary> Initializes the wizard </summary>
|
||||
public void Initialize(WindowTypeEnum _windowType, SplineN _node)
|
||||
{
|
||||
if (rect.width < 1f && rect.height < 1f)
|
||||
{
|
||||
rect.x = 275f;
|
||||
rect.y = 200f;
|
||||
rect.width = 860f;
|
||||
rect.height = 500f;
|
||||
}
|
||||
|
||||
position = rect;
|
||||
windowType = _windowType;
|
||||
windowTypePrevious = _windowType;
|
||||
thisNode = _node;
|
||||
InitWindow();
|
||||
Show();
|
||||
}
|
||||
|
||||
|
||||
private void InitWindow()
|
||||
{
|
||||
if (objectList != null)
|
||||
{
|
||||
objectList.Clear();
|
||||
objectList = null;
|
||||
}
|
||||
objectList = new List<WizardObject>();
|
||||
if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
titleContent.text = "Extrusion";
|
||||
InitObjs();
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Edge)
|
||||
{
|
||||
titleContent.text = "Edge objects";
|
||||
InitObjs();
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.BridgeComplete)
|
||||
{
|
||||
titleContent.text = "Bridges";
|
||||
InitGroups(true);
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Groups)
|
||||
{
|
||||
titleContent.text = "Groups";
|
||||
InitGroups(false);
|
||||
}
|
||||
|
||||
thumbStyle = new GUIStyle(GUI.skin.button);
|
||||
thumbStyle.contentOffset = new Vector2(0f, 0f);
|
||||
thumbStyle.border = new RectOffset(0, 0, 0, 0);
|
||||
thumbStyle.fixedHeight = 128f;
|
||||
thumbStyle.fixedWidth = 128f;
|
||||
thumbStyle.padding = new RectOffset(0, 0, 0, 0);
|
||||
thumbStyle.normal.background = null;
|
||||
thumbStyle.hover.background = null;
|
||||
thumbStyle.active.background = null;
|
||||
|
||||
EditorStyles.label.wordWrap = true;
|
||||
EditorStyles.miniLabel.wordWrap = true;
|
||||
GUI.skin.label.wordWrap = true;
|
||||
}
|
||||
|
||||
|
||||
#region "Init complete bridges"
|
||||
private void InitGroups(bool _isBridge)
|
||||
{
|
||||
string[] names = null;
|
||||
string[] paths = null;
|
||||
//Load user custom ones first:
|
||||
GetGroupListing(out names, out paths, thisNode.spline.road.laneAmount, false);
|
||||
LoadGroupObjs(ref names, ref paths, _isBridge);
|
||||
//Load RoadArchitect ones last:
|
||||
GetGroupListing(out names, out paths, thisNode.spline.road.laneAmount, true);
|
||||
LoadGroupObjs(ref names, ref paths, _isBridge);
|
||||
}
|
||||
|
||||
|
||||
private void LoadGroupObjs(ref string[] _names, ref string[] _paths, bool _isBridge)
|
||||
{
|
||||
int nameCount = _names.Length;
|
||||
string path = "";
|
||||
//string thumbString = "";
|
||||
for (int index = 0; index < nameCount; index++)
|
||||
{
|
||||
WizardObject tO = WizardObject.LoadFromLibrary(_paths[index]);
|
||||
if (tO == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (tO.isBridge != _isBridge)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
tO.thumb = EngineIntegration.LoadAssetFromPath<Texture2D>(tO.thumbString);
|
||||
}
|
||||
catch
|
||||
{
|
||||
tO.thumb = null;
|
||||
}
|
||||
tO.fileName = _names[index];
|
||||
tO.FullPath = path;
|
||||
|
||||
objectList.Add(tO);
|
||||
}
|
||||
oListSort();
|
||||
}
|
||||
|
||||
|
||||
public static void GetGroupListing(out string[] _names, out string[] _paths, int _lanes, bool _isDefault = false)
|
||||
{
|
||||
path = RootUtils.GetDirLibrary();
|
||||
Debug.Log(path);
|
||||
|
||||
string laneText = "-2L";
|
||||
if (_lanes == 4)
|
||||
{
|
||||
laneText = "-4L";
|
||||
}
|
||||
else if (_lanes == 6)
|
||||
{
|
||||
laneText = "-6L";
|
||||
}
|
||||
|
||||
_names = null;
|
||||
_paths = null;
|
||||
DirectoryInfo info;
|
||||
if (_isDefault)
|
||||
{
|
||||
// W folder is now the Default folder
|
||||
info = new DirectoryInfo(Path.Combine(Path.Combine(path, "Groups"), "Default"));
|
||||
}
|
||||
else
|
||||
{
|
||||
info = new DirectoryInfo(Path.Combine(path, "Groups"));
|
||||
}
|
||||
|
||||
FileInfo[] fileInfo = info.GetFiles();
|
||||
int count = 0;
|
||||
foreach (FileInfo tInfo in fileInfo)
|
||||
{
|
||||
if (tInfo.Extension.ToLower().Contains("rao"))
|
||||
{
|
||||
if (!_isDefault)
|
||||
{
|
||||
count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tInfo.Name.Contains(laneText))
|
||||
{
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_names = new string[count];
|
||||
_paths = new string[count];
|
||||
count = 0;
|
||||
foreach (FileInfo tInfo in fileInfo)
|
||||
{
|
||||
if (tInfo.Extension.ToLower().Contains("rao"))
|
||||
{
|
||||
if (!_isDefault)
|
||||
{
|
||||
_names[count] = tInfo.Name.Replace(".rao", "");
|
||||
_paths[count] = tInfo.FullName;
|
||||
count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tInfo.Name.Contains(laneText))
|
||||
{
|
||||
_names[count] = tInfo.Name.Replace(".rao", "");
|
||||
_paths[count] = tInfo.FullName;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region "Init objs"
|
||||
private void InitObjs()
|
||||
{
|
||||
string[] names = null;
|
||||
string[] paths = null;
|
||||
|
||||
//Load user custom ones first:
|
||||
if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
Splination.SplinatedMeshMaker.GetLibraryFiles(out names, out paths, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
EdgeObjects.EdgeObjectMaker.GetLibraryFiles(out names, out paths, false);
|
||||
}
|
||||
LoadObjs(ref names, ref paths, false);
|
||||
|
||||
|
||||
//Load RoadArchitect ones last:
|
||||
if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
Splination.SplinatedMeshMaker.GetLibraryFiles(out names, out paths, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
EdgeObjects.EdgeObjectMaker.GetLibraryFiles(out names, out paths, true);
|
||||
}
|
||||
LoadObjs(ref names, ref paths, true);
|
||||
}
|
||||
|
||||
|
||||
private void LoadObjs(ref string[] _names, ref string[] _paths, bool _isDefault = false)
|
||||
{
|
||||
int namesCount = _names.Length;
|
||||
string path = "";
|
||||
string stringPath = "";
|
||||
string desc = "";
|
||||
string displayName = "";
|
||||
string thumbString = "";
|
||||
bool isBridge;
|
||||
|
||||
for (int i = 0; i < namesCount; i++)
|
||||
{
|
||||
isBridge = false;
|
||||
path = _paths[i];
|
||||
|
||||
if (windowType == WindowTypeEnum.Extrusion)
|
||||
{
|
||||
Splination.SplinatedMeshMaker.SplinatedMeshLibraryMaker SLM = RootUtils.LoadXML<Splination.SplinatedMeshMaker.SplinatedMeshLibraryMaker>(ref path);
|
||||
if (SLM == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
stringPath = SLM.CurrentSplinationString;
|
||||
desc = SLM.desc;
|
||||
displayName = SLM.displayName;
|
||||
thumbString = SLM.thumbString;
|
||||
isBridge = SLM.isBridge;
|
||||
}
|
||||
else if (windowType == WindowTypeEnum.Edge)
|
||||
{
|
||||
EdgeObjects.EdgeObjectMaker.EdgeObjectLibraryMaker ELM = RootUtils.LoadXML<EdgeObjects.EdgeObjectMaker.EdgeObjectLibraryMaker>(ref path);
|
||||
if (ELM == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
stringPath = ELM.edgeObjectString;
|
||||
desc = ELM.desc;
|
||||
displayName = ELM.displayName;
|
||||
thumbString = ELM.thumbString;
|
||||
isBridge = ELM.isBridge;
|
||||
}
|
||||
|
||||
//Don't continue if bridge pieces and this is not a bridge piece:
|
||||
if (windowType == WindowTypeEnum.Extrusion && isBridge)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
WizardObject tO = new WizardObject();
|
||||
#region "Image"
|
||||
try
|
||||
{
|
||||
tO.thumb = EngineIntegration.LoadAssetFromPath<Texture2D>(thumbString);
|
||||
}
|
||||
catch
|
||||
{
|
||||
tO.thumb = null;
|
||||
}
|
||||
|
||||
|
||||
if (tO.thumb == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
GameObject xObj = EngineIntegration.LoadAssetFromPath<GameObject>(stringPath);
|
||||
tO.thumb = AssetPreview.GetAssetPreview(xObj);
|
||||
}
|
||||
catch
|
||||
{
|
||||
tO.thumb = null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
tO.displayName = displayName;
|
||||
tO.fileName = _names[i];
|
||||
tO.FullPath = path;
|
||||
tO.desc = desc;
|
||||
tO.isDefault = _isDefault;
|
||||
|
||||
objectList.Add(tO);
|
||||
}
|
||||
oListSort();
|
||||
}
|
||||
|
||||
|
||||
private void oListSort()
|
||||
{
|
||||
objectList.Sort((WizardObject object1, WizardObject object2) =>
|
||||
{
|
||||
if (object1.isDefault != object2.isDefault)
|
||||
{
|
||||
return object1.isDefault.CompareTo(object2.isDefault);
|
||||
}
|
||||
else if (object1.sortID != object2.sortID)
|
||||
{
|
||||
return object1.sortID.CompareTo(object2.sortID);
|
||||
}
|
||||
else
|
||||
{
|
||||
return object1.displayName.CompareTo(object2.displayName);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ed90bd0a0e8eca4788cb2fc0a693239
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
Reference in New Issue
Block a user