summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor
diff options
context:
space:
mode:
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor')
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/DependencyCheck.cs66
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/DependencyCheck.cs.meta11
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorBase.cs300
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorBase.cs.meta12
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorGUIx.cs198
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorGUIx.cs.meta7
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EnumFlagDrawer.cs39
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EnumFlagDrawer.cs.meta12
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/LegacyEditorHelper.cs29
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/LegacyEditorHelper.cs.meta12
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs164
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs.meta7
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/PackageToolsEditor.asmdef44
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/PackageToolsEditor.asmdef.meta7
14 files changed, 908 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/DependencyCheck.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/DependencyCheck.cs
new file mode 100644
index 0000000..b7f2cb1
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/DependencyCheck.cs
@@ -0,0 +1,66 @@
+// Disable the warning: "Field 'DependencyCheck.Dependency.name' is never assigned to, and will always have its default value null"
+#pragma warning disable 649
+using UnityEditor;
+using System.Linq;
+using UnityEngine;
+
+namespace Pathfinding.Util {
+ [InitializeOnLoad]
+ static class DependencyCheck {
+ struct Dependency {
+ public string name;
+ public string version;
+ }
+
+ static DependencyCheck() {
+ var missingDependencies = new Dependency[] {
+#if !MODULE_BURST
+ new Dependency {
+ name = "com.unity.burst",
+ version = "1.8.3",
+ },
+#endif
+#if !MODULE_MATHEMATICS
+ new Dependency {
+ name = "com.unity.mathematics",
+ version = "1.2.6",
+ },
+#endif
+#if !MODULE_COLLECTIONS
+ new Dependency {
+ name = "com.unity.collections",
+ version = "1.5.1",
+ },
+#endif
+ // #if !MODULE_ENTITIES
+ // new Dependency {
+ // name = "com.unity.entities",
+ // version = "1.0.0-pre.47",
+ // },
+ // #endif
+ };
+
+ if (missingDependencies.Length > 0) {
+ string missing = string.Join(", ", missingDependencies.Select(p => p.name + " (" + p.version + ")"));
+ bool res = EditorUtility.DisplayDialog("Missing dependencies", "The packages " + missing + " are required by the A* Pathfinding Project but they are not installed, or the installed versions are too old. Do you want to install the latest versions of the packages?", "Ok", "Cancel");
+ if (res) {
+ foreach (var dep in missingDependencies) {
+ UnityEditor.PackageManager.Client.Add(dep.name);
+ }
+ }
+ }
+
+ // E.g. 2023.3.0b8
+ var v = Application.unityVersion.Split('.');
+ UnityEngine.Assertions.Assert.IsTrue(v.Length >= 3, "Unity version string is not in the expected format");
+ var major = int.Parse(v[0]);
+ var minor = int.Parse(v[1]);
+ // Filter out non-digits from v[2]
+ v[2] = new string(v[2].TakeWhile(char.IsDigit).ToArray());
+ var patch = int.Parse(v[2]);
+ if (major == 2022 && minor == 3 && patch < 21) {
+ Debug.LogError("This version of Unity has a bug which causes components in the A* Pathfinding Project to randomly stop working. Please update to unity 2022.3.21 or later.");
+ }
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/DependencyCheck.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/DependencyCheck.cs.meta
new file mode 100644
index 0000000..4aa5da4
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/DependencyCheck.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 13cd4e1cd3bf242b3a58eb62092ce599
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorBase.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorBase.cs
new file mode 100644
index 0000000..19efef1
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorBase.cs
@@ -0,0 +1,300 @@
+using UnityEditor;
+using UnityEngine;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Pathfinding {
+ /// <summary>Helper for creating editors</summary>
+ [CustomEditor(typeof(VersionedMonoBehaviour), true)]
+ [CanEditMultipleObjects]
+ public class EditorBase : Editor {
+ static System.Collections.Generic.Dictionary<string, string> cachedTooltips;
+ static System.Collections.Generic.Dictionary<string, string> cachedURLs;
+ Dictionary<string, SerializedProperty> props = new Dictionary<string, SerializedProperty>();
+
+ static GUIContent content = new GUIContent();
+ static GUIContent showInDocContent = new GUIContent("Show in online documentation", "");
+ static GUILayoutOption[] noOptions = new GUILayoutOption[0];
+ public static System.Func<string> getDocumentationURL;
+
+ protected HashSet<string> remainingUnhandledProperties;
+
+
+ static void LoadMeta () {
+ if (cachedTooltips == null) {
+ var filePath = EditorResourceHelper.editorAssets + "/tooltips.tsv";
+
+ try {
+ var lines = System.IO.File.ReadAllLines(filePath).Select(l => l.Split('\t', 3)).Where(l => l.Length == 3).ToArray();
+ cachedURLs = lines.ToDictionary(l => l[0], l => l[1]);
+ cachedTooltips = lines.ToDictionary(l => l[0], l => l[2].Replace("\\n", "\n"));
+ } catch (System.Exception e) {
+ Debug.LogWarning("Could not load tooltips from " + filePath + "\n" + e);
+ cachedURLs = new System.Collections.Generic.Dictionary<string, string>();
+ cachedTooltips = new System.Collections.Generic.Dictionary<string, string>();
+ }
+ }
+ }
+
+
+ static string LookupPath (System.Type type, string path, Dictionary<string, string> lookupData) {
+ // Find the correct type if the path was not an immediate member of #type
+ while (true) {
+ var index = path.IndexOf('.');
+ if (index == -1) break;
+ var fieldName = path.Substring(0, index);
+ var remaining = path.Substring(index + 1);
+ var field = type.GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
+ if (field != null) {
+ type = field.FieldType;
+ path = remaining;
+ } else {
+ // Could not find the correct field
+ return null;
+ }
+ }
+
+ // Find a documentation entry for the field, fall back to parent classes if necessary
+ while (type != null) {
+ if (lookupData.TryGetValue(type.FullName + "." + path, out var value)) {
+ return value;
+ }
+ type = type.BaseType;
+ }
+ return null;
+ }
+
+ string FindTooltip (string path) {
+ LoadMeta();
+ return LookupPath(target.GetType(), path, cachedTooltips);
+ }
+
+ protected virtual void OnEnable () {
+ foreach (var target in targets) if (target != null) (target as IVersionedMonoBehaviourInternal).UpgradeFromUnityThread();
+ EditorApplication.contextualPropertyMenu += OnContextMenu;
+ }
+
+ protected virtual void OnDisable () {
+ EditorApplication.contextualPropertyMenu -= OnContextMenu;
+ }
+
+ void OnContextMenu (GenericMenu menu, SerializedProperty property) {
+ if (property.serializedObject != this.serializedObject) return;
+
+ LoadMeta();
+ var url = LookupPath(target.GetType(), property.propertyPath, cachedURLs);
+
+ if (url != null && getDocumentationURL != null) {
+ menu.AddItem(showInDocContent, false, () => Application.OpenURL(getDocumentationURL() + url));
+ }
+ }
+
+ public sealed override void OnInspectorGUI () {
+ EditorGUI.indentLevel = 0;
+ serializedObject.Update();
+ try {
+ Inspector();
+ InspectorForRemainingAttributes(false, true);
+ } catch (System.Exception e) {
+ // This exception type should never be caught. See https://docs.unity3d.com/ScriptReference/ExitGUIException.html
+ if (e is ExitGUIException) throw e;
+ Debug.LogException(e, target);
+ }
+ serializedObject.ApplyModifiedProperties();
+ if (targets.Length == 1 && (target as MonoBehaviour).enabled) {
+ var attr = target.GetType().GetCustomAttributes(typeof(UniqueComponentAttribute), true);
+ for (int i = 0; i < attr.Length; i++) {
+ string tag = (attr[i] as UniqueComponentAttribute).tag;
+ foreach (var other in (target as MonoBehaviour).GetComponents<MonoBehaviour>()) {
+ // Note: other can be null if some scripts are missing references
+ if (other == null || !other.enabled || other == target) continue;
+ if (other.GetType().GetCustomAttributes(typeof(UniqueComponentAttribute), true).Where(c => (c as UniqueComponentAttribute).tag == tag).Any()) {
+ EditorGUILayout.HelpBox("This component and " + other.GetType().Name + " cannot be used at the same time", MessageType.Warning);
+ }
+ }
+ }
+ }
+ }
+
+
+ protected virtual void Inspector () {
+ InspectorForRemainingAttributes(true, false);
+ }
+
+ /// <summary>Draws an inspector for all fields that are likely not handled by the editor script itself</summary>
+ protected virtual void InspectorForRemainingAttributes (bool showHandled, bool showUnhandled) {
+ if (remainingUnhandledProperties == null) {
+ remainingUnhandledProperties = new HashSet<string>();
+
+ var tp = serializedObject.targetObject.GetType();
+ var handledAssemblies = new List<System.Reflection.Assembly>();
+
+ // Find all types for which we have a [CustomEditor(type)] attribute.
+ // Unity hides this field, so we have to use reflection to get it.
+ var customEditorAttrs = this.GetType().GetCustomAttributes(typeof(CustomEditor), true).Cast<CustomEditor>().ToArray();
+ foreach (var attr in customEditorAttrs) {
+ var inspectedTypeField = attr.GetType().GetField("m_InspectedType", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+ var inspectedType = inspectedTypeField.GetValue(attr) as System.Type;
+ if (!handledAssemblies.Contains(inspectedType.Assembly)) {
+ handledAssemblies.Add(inspectedType.Assembly);
+ }
+ }
+ bool enterChildren = true;
+ for (var prop = serializedObject.GetIterator(); prop.NextVisible(enterChildren); enterChildren = false) {
+ var name = prop.propertyPath;
+ var field = tp.GetField(name, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+ if (field == null) {
+ // Can happen for some built-in Unity fields. They are not important
+ continue;
+ } else {
+ var declaringType = field.DeclaringType;
+ var foundOtherAssembly = false;
+ var foundThisAssembly = false;
+ while (declaringType != null) {
+ if (handledAssemblies.Contains(declaringType.Assembly)) {
+ foundThisAssembly = true;
+ break;
+ } else {
+ foundOtherAssembly = true;
+ }
+ declaringType = declaringType.BaseType;
+ }
+ if (foundOtherAssembly && foundThisAssembly) {
+ // This is a field in a class in a different assembly, which inherits from a class in one of the handled assemblies.
+ // That probably means the editor script doesn't explicitly know about that field and we should show it anyway.
+ remainingUnhandledProperties.Add(prop.propertyPath);
+ }
+ }
+ }
+ }
+
+ // Basically the same as DrawDefaultInspector, but with tooltips
+ bool enterChildren2 = true;
+
+ for (var prop = serializedObject.GetIterator(); prop.NextVisible(enterChildren2); enterChildren2 = false) {
+ var handled = !remainingUnhandledProperties.Contains(prop.propertyPath);
+ if ((showHandled && handled) || (showUnhandled && !handled)) {
+ PropertyField(prop.propertyPath);
+ }
+ }
+ }
+
+ protected SerializedProperty FindProperty (string name) {
+ if (!props.TryGetValue(name, out SerializedProperty res)) res = props[name] = serializedObject.FindProperty(name);
+ if (res == null) throw new System.ArgumentException(name);
+ return res;
+ }
+
+ protected void Section (string label) {
+ EditorGUILayout.Separator();
+ EditorGUILayout.LabelField(label, EditorStyles.boldLabel);
+ }
+
+ protected bool SectionEnableable (string label, string enabledProperty) {
+ EditorGUILayout.Separator();
+ var v = EditorGUILayout.ToggleLeft(label, FindProperty(enabledProperty).boolValue, EditorStyles.boldLabel);
+ FindProperty(enabledProperty).boolValue = v;
+ return v;
+ }
+
+ /// <summary>Bounds field using center/size instead of center/extent</summary>
+ protected void BoundsField (string propertyPath) {
+ PropertyField(propertyPath + ".m_Center", "Center");
+ var extentsProp = FindProperty(propertyPath + ".m_Extent");
+ var r = EditorGUILayout.GetControlRect();
+ var label = EditorGUI.BeginProperty(r, new GUIContent("Size"), extentsProp);
+ extentsProp.vector3Value = 0.5f * EditorGUI.Vector3Field(r, label, extentsProp.vector3Value * 2.0f);
+ EditorGUI.EndProperty();
+ }
+
+ protected void FloatField (string propertyPath, string label = null, string tooltip = null, float min = float.NegativeInfinity, float max = float.PositiveInfinity) {
+ PropertyField(propertyPath, label, tooltip);
+ Clamp(propertyPath, min, max);
+ }
+
+ protected void FloatField (SerializedProperty prop, string label = null, string tooltip = null, float min = float.NegativeInfinity, float max = float.PositiveInfinity) {
+ PropertyField(prop, label, tooltip);
+ Clamp(prop, min, max);
+ }
+
+ protected bool PropertyField (string propertyPath, string label = null, string tooltip = null) {
+ return PropertyField(FindProperty(propertyPath), label, tooltip, propertyPath);
+ }
+
+ protected bool PropertyField (SerializedProperty prop, string label = null, string tooltip = null) {
+ return PropertyField(prop, label, tooltip, prop.propertyPath);
+ }
+
+ bool PropertyField (SerializedProperty prop, string label, string tooltip, string propertyPath) {
+ content.text = label ?? prop.displayName;
+ content.tooltip = tooltip ?? FindTooltip(propertyPath);
+ EditorGUILayout.PropertyField(prop, content, true, noOptions);
+ return prop.propertyType == SerializedPropertyType.Boolean ? !prop.hasMultipleDifferentValues && prop.boolValue : true;
+ }
+
+ protected void Popup (string propertyPath, GUIContent[] options, string label = null) {
+ var prop = FindProperty(propertyPath);
+
+ content.text = label ?? prop.displayName;
+ content.tooltip = FindTooltip(propertyPath);
+ EditorGUI.BeginChangeCheck();
+ var r = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight, EditorStyles.popup);
+ r = EditorGUI.PrefixLabel(r, EditorGUI.BeginProperty(r, content, prop));
+ var tmpIndent = EditorGUI.indentLevel;
+ EditorGUI.indentLevel = 0;
+ int newVal = EditorGUI.Popup(r, prop.propertyType == SerializedPropertyType.Enum ? prop.enumValueIndex : prop.intValue, options);
+ EditorGUI.indentLevel = tmpIndent;
+ if (EditorGUI.EndChangeCheck()) {
+ if (prop.propertyType == SerializedPropertyType.Enum) prop.enumValueIndex = newVal;
+ else prop.intValue = newVal;
+ }
+ EditorGUI.EndProperty();
+ }
+
+ protected void IntSlider (string propertyPath, int left, int right) {
+ var prop = FindProperty(propertyPath);
+
+ content.text = prop.displayName;
+ content.tooltip = FindTooltip(propertyPath);
+ EditorGUILayout.IntSlider(prop, left, right, content, noOptions);
+ }
+
+ protected void Slider (string propertyPath, float left, float right) {
+ var prop = FindProperty(propertyPath);
+
+ content.text = prop.displayName;
+ content.tooltip = FindTooltip(propertyPath);
+ EditorGUILayout.Slider(prop, left, right, content, noOptions);
+ }
+
+ protected bool ByteAsToggle (string propertyPath, string label) {
+ var prop = FindProperty(propertyPath);
+
+ content.text = label;
+ content.tooltip = FindTooltip(propertyPath);
+ EditorGUI.BeginChangeCheck();
+ var r = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight, EditorStyles.popup);
+ r = EditorGUI.PrefixLabel(r, EditorGUI.BeginProperty(r, content, prop));
+ var tmpIndent = EditorGUI.indentLevel;
+ EditorGUI.indentLevel = 0;
+ prop.intValue = EditorGUI.Toggle(r, prop.intValue != 0) ? 1 : 0;
+ EditorGUI.indentLevel = tmpIndent;
+ EditorGUI.EndProperty();
+ return prop.intValue != 0;
+ }
+
+ protected void Clamp (SerializedProperty prop, float min, float max = float.PositiveInfinity) {
+ if (!prop.hasMultipleDifferentValues) prop.floatValue = Mathf.Clamp(prop.floatValue, min, max);
+ }
+
+ protected void Clamp (string name, float min, float max = float.PositiveInfinity) {
+ Clamp(FindProperty(name), min, max);
+ }
+
+ protected void ClampInt (string name, int min, int max = int.MaxValue) {
+ var prop = FindProperty(name);
+
+ if (!prop.hasMultipleDifferentValues) prop.intValue = Mathf.Clamp(prop.intValue, min, max);
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorBase.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorBase.cs.meta
new file mode 100644
index 0000000..fe26580
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorBase.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 58753931a68ae48b3973d0ce32d1a760
+timeCreated: 1495461526
+licenseType: Store
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorGUIx.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorGUIx.cs
new file mode 100644
index 0000000..3a0a3f0
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorGUIx.cs
@@ -0,0 +1,198 @@
+using UnityEngine;
+using System.Collections.Generic;
+using UnityEditor;
+
+namespace Pathfinding {
+ /// <summary>Simple GUI utility functions</summary>
+ public static class GUIUtilityx {
+ static Stack<Color> colors = new Stack<Color>();
+
+ public static void PushTint (Color tint) {
+ colors.Push(GUI.color);
+ GUI.color *= tint;
+ }
+
+ public static void PopTint () {
+ GUI.color = colors.Pop();
+ }
+
+ public static Rect SliceRow (ref Rect rect, float height) {
+ var r = new Rect(rect.x, rect.y, rect.width, height);
+ rect.yMin += height + EditorGUIUtility.standardVerticalSpacing;
+ return r;
+ }
+
+ public static Rect SliceColumn (ref Rect rect, float width, float spacing = 0) {
+ var r = new Rect(rect.x, rect.y, width, rect.height);
+ rect.xMin += width + spacing;
+ return r;
+ }
+ }
+
+ /// <summary>
+ /// Editor helper for hiding and showing a group of GUI elements.
+ /// Call order in OnInspectorGUI should be:
+ /// - Begin
+ /// - Header/HeaderLabel (optional)
+ /// - BeginFade
+ /// - [your gui elements] (if BeginFade returns true)
+ /// - End
+ /// </summary>
+ public class FadeArea {
+ Rect lastRect;
+ float value;
+ float lastUpdate;
+ GUIStyle labelStyle;
+ GUIStyle areaStyle;
+ bool visible;
+ Editor editor;
+
+ /// <summary>
+ /// Is this area open.
+ /// This is not the same as if any contents are visible, use <see cref="BeginFade"/> for that.
+ /// </summary>
+ public bool open;
+
+ /// <summary>Animate dropdowns when they open and close</summary>
+ public static bool fancyEffects;
+ const float animationSpeed = 100f;
+
+ public FadeArea (bool open, Editor editor, GUIStyle areaStyle, GUIStyle labelStyle = null) {
+ this.areaStyle = areaStyle;
+ this.labelStyle = labelStyle;
+ this.editor = editor;
+ visible = this.open = open;
+ value = open ? 1 : 0;
+ }
+
+ void Tick () {
+ if (Event.current.type == EventType.Repaint) {
+ float deltaTime = Time.realtimeSinceStartup-lastUpdate;
+
+ // Right at the start of a transition the deltaTime will
+ // not be reliable, so use a very small value instead
+ // until the next repaint
+ if (value == 0f || value == 1f) deltaTime = 0.001f;
+ deltaTime = Mathf.Clamp(deltaTime, 0.00001F, 0.1F);
+
+ // Larger regions fade slightly slower
+ deltaTime /= Mathf.Sqrt(Mathf.Max(lastRect.height, 100));
+
+ lastUpdate = Time.realtimeSinceStartup;
+
+
+ float targetValue = open ? 1F : 0F;
+ if (!Mathf.Approximately(targetValue, value)) {
+ value += deltaTime*animationSpeed*Mathf.Sign(targetValue-value);
+ value = Mathf.Clamp01(value);
+ editor.Repaint();
+
+ if (!fancyEffects) {
+ value = targetValue;
+ }
+ } else {
+ value = targetValue;
+ }
+ }
+ }
+
+ public void Begin () {
+ if (areaStyle != null) {
+ lastRect = EditorGUILayout.BeginVertical(areaStyle);
+ } else {
+ lastRect = EditorGUILayout.BeginVertical();
+ }
+ }
+
+ public void HeaderLabel (string label) {
+ GUILayout.Label(label, labelStyle);
+ }
+
+ public void Header (string label) {
+ Header(label, ref open);
+ }
+
+ public void Header (string label, ref bool open) {
+ if (GUILayout.Button(label, labelStyle)) {
+ open = !open;
+ editor.Repaint();
+ }
+ this.open = open;
+ }
+
+ /// <summary>Hermite spline interpolation</summary>
+ static float Hermite (float start, float end, float value) {
+ return Mathf.Lerp(start, end, value * value * (3.0f - 2.0f * value));
+ }
+
+ public bool BeginFade () {
+ var hermite = Hermite(0, 1, value);
+
+ visible = EditorGUILayout.BeginFadeGroup(hermite);
+ GUIUtilityx.PushTint(new Color(1, 1, 1, hermite));
+ Tick();
+
+ // Another vertical group is necessary to work around
+ // a kink of the BeginFadeGroup implementation which
+ // causes the padding to change when value!=0 && value!=1
+ EditorGUILayout.BeginVertical();
+
+ return visible;
+ }
+
+ public void End () {
+ EditorGUILayout.EndVertical();
+
+ if (visible) {
+ // Some space that cannot be placed in the GUIStyle unfortunately
+ GUILayout.Space(4);
+ }
+
+ EditorGUILayout.EndFadeGroup();
+ EditorGUILayout.EndVertical();
+ GUIUtilityx.PopTint();
+ }
+ }
+ /// <summary>Handles fading effects and also some custom GUI functions such as LayerMaskField</summary>
+ public static class EditorGUILayoutx {
+ static Dictionary<int, string[]> layerNames = new Dictionary<int, string[]>();
+ static long lastUpdateTick;
+ static List<string> dummyList = new List<string>();
+
+ /// <summary>Displays a LayerMask field.</summary>
+ /// <param name="label">Label to display</param>
+ /// <param name="selected">Current LayerMask</param>
+ public static LayerMask LayerMaskField (string label, LayerMask selected) {
+ if (Event.current.type == EventType.Layout && System.DateTime.UtcNow.Ticks - lastUpdateTick > 10000000L) {
+ layerNames.Clear();
+ lastUpdateTick = System.DateTime.UtcNow.Ticks;
+ }
+
+ string[] currentLayerNames;
+ if (!layerNames.TryGetValue(selected.value, out currentLayerNames)) {
+ var layers = dummyList;
+ layers.Clear();
+
+ int emptyLayers = 0;
+ for (int i = 0; i < 32; i++) {
+ string layerName = LayerMask.LayerToName(i);
+
+ if (layerName != "") {
+ for (; emptyLayers > 0; emptyLayers--) layers.Add("Layer "+(i-emptyLayers));
+ layers.Add(layerName);
+ } else {
+ emptyLayers++;
+ if (((selected.value >> i) & 1) != 0 && selected.value != -1) {
+ for (; emptyLayers > 0; emptyLayers--) layers.Add("Layer "+(i+1-emptyLayers));
+ }
+ }
+ }
+
+ currentLayerNames = layerNames[selected.value] = layers.ToArray();
+ }
+
+ selected.value = EditorGUILayout.MaskField(label, selected.value, currentLayerNames);
+ return selected;
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorGUIx.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorGUIx.cs.meta
new file mode 100644
index 0000000..c27c695
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EditorGUIx.cs.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 2b6b4977544da4af3a4fe9e895fb6888
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EnumFlagDrawer.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EnumFlagDrawer.cs
new file mode 100644
index 0000000..8e14970
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EnumFlagDrawer.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine;
+
+namespace Pathfinding {
+ [CustomPropertyDrawer(typeof(EnumFlagAttribute))]
+ public class EnumFlagDrawer : PropertyDrawer {
+ public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
+ Enum targetEnum = GetBaseProperty<Enum>(property);
+
+ EditorGUI.BeginProperty(position, label, property);
+ EditorGUI.BeginChangeCheck();
+#if UNITY_2017_3_OR_NEWER
+ Enum enumNew = EditorGUI.EnumFlagsField(position, label, targetEnum);
+#else
+ Enum enumNew = EditorGUI.EnumMaskField(position, label, targetEnum);
+#endif
+ if (EditorGUI.EndChangeCheck() || !property.hasMultipleDifferentValues) {
+ property.intValue = (int)Convert.ChangeType(enumNew, targetEnum.GetType());
+ }
+ EditorGUI.EndProperty();
+ }
+
+ static T GetBaseProperty<T>(SerializedProperty prop) {
+ // Separate the steps it takes to get to this property
+ string[] separatedPaths = prop.propertyPath.Split('.');
+
+ // Go down to the root of this serialized property
+ System.Object reflectionTarget = prop.serializedObject.targetObject as object;
+ // Walk down the path to get the target object
+ foreach (var path in separatedPaths) {
+ FieldInfo fieldInfo = reflectionTarget.GetType().GetField(path, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ reflectionTarget = fieldInfo.GetValue(reflectionTarget);
+ }
+ return (T)reflectionTarget;
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EnumFlagDrawer.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EnumFlagDrawer.cs.meta
new file mode 100644
index 0000000..1d12a74
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/EnumFlagDrawer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 616267fcc419f44ea929599afa5c6aa2
+timeCreated: 1500392257
+licenseType: Store
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/LegacyEditorHelper.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/LegacyEditorHelper.cs
new file mode 100644
index 0000000..45d2dab
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/LegacyEditorHelper.cs
@@ -0,0 +1,29 @@
+using UnityEngine;
+using UnityEditor;
+using System.Linq;
+
+namespace Pathfinding.Legacy {
+ public static class LegacyEditorHelper {
+ public static void UpgradeDialog (Object[] targets, System.Type upgradeType) {
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ var gui = EditorGUIUtility.IconContent("console.warnicon");
+ gui.text = "You are using the compatibility version of this component. It is recommended that you upgrade to the newer version. This may change the component's behavior.";
+ EditorGUILayout.LabelField(GUIContent.none, gui, EditorStyles.wordWrappedMiniLabel);
+ if (GUILayout.Button("Upgrade")) {
+ Undo.RecordObjects(targets.Select(s => (s as Component).gameObject).ToArray(), "Upgrade from Legacy Component");
+ foreach (var tg in targets) {
+ var comp = tg as Component;
+ var components = comp.gameObject.GetComponents<Component>();
+ int index = System.Array.IndexOf(components, comp);
+ var newRVO = Undo.AddComponent(comp.gameObject, upgradeType);
+ foreach (var field in newRVO.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)) {
+ field.SetValue(newRVO, field.GetValue(comp));
+ }
+ Undo.DestroyObjectImmediate(comp);
+ for (int i = components.Length - 1; i > index; i--) UnityEditorInternal.ComponentUtility.MoveComponentUp(newRVO);
+ }
+ }
+ EditorGUILayout.EndVertical();
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/LegacyEditorHelper.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/LegacyEditorHelper.cs.meta
new file mode 100644
index 0000000..99b9e67
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/LegacyEditorHelper.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: a97cec2d4f06c4d0eb0068c24cb47ca1
+timeCreated: 1490879139
+licenseType: Store
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs
new file mode 100644
index 0000000..e3f1666
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs
@@ -0,0 +1,164 @@
+using UnityEngine;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using UnityEditor;
+
+namespace Pathfinding {
+ /// <summary>
+ /// Helper for enabling or disabling compiler directives.
+ /// Used only in the editor.
+ /// </summary>
+ public static class OptimizationHandler {
+ public class DefineDefinition {
+ public string name;
+ public string description;
+ public bool enabled;
+ public bool consistent;
+ }
+
+ /// <summary>
+ /// Various build targets that Unity have deprecated.
+ /// There is apparently no way to figure out which these are without hard coding them.
+ /// </summary>
+ static readonly BuildTargetGroup[] deprecatedBuildTargets = new BuildTargetGroup[] {
+ BuildTargetGroup.Unknown,
+#if UNITY_5_4_OR_NEWER
+ (BuildTargetGroup)16, /* BlackBerry */
+#endif
+#if UNITY_5_5_OR_NEWER
+ (BuildTargetGroup)5, /* PS3 */
+ (BuildTargetGroup)6, /* XBox360 */
+ (BuildTargetGroup)15, /* WP8 */
+#endif
+#if UNITY_2017_4_OR_NEWER
+ (BuildTargetGroup)2, /* WebPlayer */
+ (BuildTargetGroup)20, /* PSM */
+#endif
+#if UNITY_2018_1_OR_NEWER
+ (BuildTargetGroup)22, /* SamsungTV */
+ (BuildTargetGroup)24, /* WiiU */
+#endif
+#if UNITY_2018_2_OR_NEWER
+ (BuildTargetGroup)17, /* Tizen */
+#endif
+#if UNITY_2018_3_OR_NEWER
+ (BuildTargetGroup)18, /* PSP2 */
+ (BuildTargetGroup)23, /* Nintendo3DS */
+#endif
+ };
+
+ static string GetPackageRootDirectory () {
+ var rootDir = EditorResourceHelper.editorAssets + "/../../";
+
+ return rootDir;
+ }
+
+ static Dictionary<BuildTargetGroup, List<string> > GetDefineSymbols () {
+ var result = new Dictionary<BuildTargetGroup, List<string> >();
+
+ var nonDeprecatedBuildTypes = typeof(BuildTargetGroup)
+ .GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)
+ .Where(fieldInfo => fieldInfo.GetCustomAttributes(typeof(System.ObsoleteAttribute), false).Length == 0)
+ .Select(fieldInfo => (BuildTargetGroup)fieldInfo.GetValue(null)).ToArray();
+
+ for (int i = 0; i < nonDeprecatedBuildTypes.Length; i++) {
+ // Kept for compatibility with older versions of Unity which did not always accurately add Obsolete attributes
+ // (in particular Unity 2017.4 seems to miss marking the PSM build target as obsolete, the other ones seem accurate)
+ if (deprecatedBuildTargets.Contains(nonDeprecatedBuildTypes[i])) continue;
+
+#if UNITY_2021_3_OR_NEWER
+ PlayerSettings.GetScriptingDefineSymbols(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(nonDeprecatedBuildTypes[i]), out var defines);
+#else
+ string defineString = PlayerSettings.GetScriptingDefineSymbolsForGroup(nonDeprecatedBuildTypes[i]);
+ if (defineString == null) continue;
+
+ var defines = defineString.Split(';').Select(s => s.Trim());
+#endif
+ result[nonDeprecatedBuildTypes[i]] = defines.ToList();
+ }
+ return result;
+ }
+
+ static void SetDefineSymbols (Dictionary<BuildTargetGroup, List<string> > symbols) {
+ foreach (var pair in symbols) {
+#if UNITY_2021_3_OR_NEWER
+ string[] symbolsArr = pair.Value.Distinct().ToArray();
+ PlayerSettings.SetScriptingDefineSymbols(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(pair.Key), symbolsArr);
+#else
+ var defineString = string.Join(";", pair.Value.Distinct().ToArray());
+ PlayerSettings.SetScriptingDefineSymbolsForGroup(pair.Key, defineString);
+#endif
+ }
+ }
+
+ public static void EnableDefine (string name) {
+ name = name.Trim();
+ var newSymbols = GetDefineSymbols().ToDictionary(pair => pair.Key, pair => {
+ pair.Value.Add(name);
+ return pair.Value;
+ });
+ SetDefineSymbols(newSymbols);
+ }
+
+ public static void DisableDefine (string name) {
+ name = name.Trim();
+ var newSymbols = GetDefineSymbols().ToDictionary(pair => pair.Key, pair => {
+ pair.Value.Remove(name);
+ return pair.Value;
+ });
+ SetDefineSymbols(newSymbols);
+ }
+
+ public static void IsDefineEnabled (string name, out bool enabled, out bool consistent) {
+ name = name.Trim();
+ int foundEnabled = 0;
+ int foundDisabled = 0;
+
+ foreach (var pair in GetDefineSymbols()) {
+ if (pair.Value.Contains(name)) {
+ foundEnabled++;
+ } else {
+ foundDisabled++;
+ }
+ }
+
+ enabled = foundEnabled > foundDisabled;
+ consistent = (foundEnabled > 0) != (foundDisabled > 0);
+ }
+
+ public static List<DefineDefinition> FindDefines () {
+ var path = GetPackageRootDirectory()+"/defines.csv";
+
+ if (File.Exists(path)) {
+ // Read a file consisting of lines with the format
+ // NAME;Description
+ // Ignore empty lines and lines which do not contain exactly 1 ';'
+ var definePairs = File.ReadAllLines(path)
+ .Select(line => line.Trim())
+ .Where(line => line.Length > 0)
+ .Select(line => line.Split(';'))
+ .Where(opts => opts.Length == 2);
+
+ return definePairs.Select(opts => {
+ var def = new DefineDefinition { name = opts[0].Trim(), description = opts[1].Trim() };
+ IsDefineEnabled(def.name, out def.enabled, out def.consistent);
+ return def;
+ }).ToList();
+ }
+
+ Debug.LogError("Could not find file '"+path+"'");
+ return new List<DefineDefinition>();
+ }
+
+ public static void ApplyDefines (List<DefineDefinition> defines) {
+ foreach (var define in defines) {
+ if (define.enabled) {
+ EnableDefine(define.name);
+ } else {
+ DisableDefine(define.name);
+ }
+ }
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs.meta
new file mode 100644
index 0000000..6ece61e
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: ec7eea22fd1c74193aa7d047949503e7
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/PackageToolsEditor.asmdef b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/PackageToolsEditor.asmdef
new file mode 100644
index 0000000..ded42ec
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/PackageToolsEditor.asmdef
@@ -0,0 +1,44 @@
+{
+ "name": "AstarPackageToolsEditor",
+ "rootNamespace": "",
+ "references": [
+ "GUID:f4059aaf6c60a4a58a177a2609feb769"
+ ],
+ "includePlatforms": [
+ "Editor"
+ ],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": true,
+ "precompiledReferences": [],
+ "autoReferenced": true,
+ "defineConstraints": [],
+ "versionDefines": [
+ {
+ "name": "com.unity.burst",
+ "expression": "1.8.3",
+ "define": "MODULE_BURST"
+ },
+ {
+ "name": "com.unity.mathematics",
+ "expression": "1.2.6",
+ "define": "MODULE_MATHEMATICS"
+ },
+ {
+ "name": "com.unity.collections",
+ "expression": "1.5.1",
+ "define": "MODULE_COLLECTIONS"
+ },
+ {
+ "name": "com.unity.collections",
+ "expression": "0.11-preview",
+ "define": "MODULE_COLLECTIONS_0_11_OR_NEWER"
+ },
+ {
+ "name": "com.unity.entities",
+ "expression": "1.0.0-pre.47",
+ "define": "MODULE_ENTITIES"
+ }
+ ],
+ "noEngineReferences": false
+} \ No newline at end of file
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/PackageToolsEditor.asmdef.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/PackageToolsEditor.asmdef.meta
new file mode 100644
index 0000000..6f9de39
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/PackageToolsEditor.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 774e21169c4ac4ec8a01db9cdb98d33b
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant: