This commit is contained in:
PC-20230316NUNE\Administrator
2024-02-01 19:06:51 +08:00
parent aa4d6c3ce2
commit 877dca3b43
7518 changed files with 653768 additions and 162059 deletions

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0cbdf52f81d0d4ce7860eab2a4d018cd
folderAsset: yes
timeCreated: 1500391729
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,315 @@
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>();
Dictionary<string, string> localTooltips = new Dictionary<string, string>();
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 {
cachedURLs = System.IO.File.ReadAllLines(filePath).Select(l => l.Split('\t')).Where(l => l.Length == 2).ToDictionary(l => l[0], l => l[1]);
cachedTooltips = new System.Collections.Generic.Dictionary<string, string>();
} catch {
cachedURLs = new System.Collections.Generic.Dictionary<string, string>();
cachedTooltips = new System.Collections.Generic.Dictionary<string, string>();
}
}
}
static string FindURL (System.Type type, string path) {
// 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) {
var url = FindURL(type.FullName + "." + path);
if (url != null) return url;
type = type.BaseType;
}
return null;
}
static string FindURL (string path) {
LoadMeta();
string url;
cachedURLs.TryGetValue(path, out url);
return url;
}
static string FindTooltip (string path) {
LoadMeta();
string tooltip;
cachedTooltips.TryGetValue(path, out tooltip);
return tooltip;
}
string FindLocalTooltip (string path) {
string result;
if (!localTooltips.TryGetValue(path, out result)) {
var fullPath = target.GetType().Name + "." + path;
result = localTooltips[path] = FindTooltip(fullPath);
}
return result;
}
protected virtual void OnEnable () {
foreach (var target in targets) if (target != null) (target as IVersionedMonoBehaviourInternal).UpgradeFromUnityThread();
}
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);
}
/// <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);
var contextClick = IsContextClick();
EditorGUILayout.PropertyField(prop, content, true, noOptions);
// Disable context clicking on arrays (as Unity has its own very useful context menu for the array elements)
if (contextClick && !prop.isArray && Event.current.type == EventType.Used) CaptureContextClick(propertyPath);
return prop.propertyType == SerializedPropertyType.Boolean ? !prop.hasMultipleDifferentValues && prop.boolValue : true;
}
bool IsContextClick () {
// Capturing context clicks turned out to be a bad idea.
// It prevents things like reverting to prefab values and other nice things.
return false;
// return Event.current.type == EventType.ContextClick;
}
void CaptureContextClick (string propertyPath) {
var url = FindURL(target.GetType(), propertyPath);
if (url != null && getDocumentationURL != null) {
Event.current.Use();
var menu = new GenericMenu();
menu.AddItem(showInDocContent, false, () => Application.OpenURL(getDocumentationURL() + url));
menu.ShowAsContext();
}
}
protected void Popup (string propertyPath, GUIContent[] options, string label = null) {
var prop = FindProperty(propertyPath);
content.text = label ?? prop.displayName;
content.tooltip = FindTooltip(propertyPath);
var contextClick = IsContextClick();
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
int newVal = EditorGUILayout.Popup(content, prop.propertyType == SerializedPropertyType.Enum ? prop.enumValueIndex : prop.intValue, options);
if (EditorGUI.EndChangeCheck()) {
if (prop.propertyType == SerializedPropertyType.Enum) prop.enumValueIndex = newVal;
else prop.intValue = newVal;
}
EditorGUI.showMixedValue = false;
if (contextClick && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) CaptureContextClick(propertyPath);
}
protected void Mask (string propertyPath, string[] options, string label = null) {
var prop = FindProperty(propertyPath);
content.text = label ?? prop.displayName;
content.tooltip = FindTooltip(propertyPath);
var contextClick = IsContextClick();
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
int newVal = EditorGUILayout.MaskField(content, prop.intValue, options);
if (EditorGUI.EndChangeCheck()) {
prop.intValue = newVal;
}
EditorGUI.showMixedValue = false;
if (contextClick && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) CaptureContextClick(propertyPath);
}
protected void IntSlider (string propertyPath, int left, int right) {
var contextClick = IsContextClick();
var prop = FindProperty(propertyPath);
content.text = prop.displayName;
content.tooltip = FindTooltip(propertyPath);
EditorGUILayout.IntSlider(prop, left, right, content, noOptions);
if (contextClick && Event.current.type == EventType.Used) CaptureContextClick(propertyPath);
}
protected void Slider (string propertyPath, float left, float right) {
var contextClick = IsContextClick();
var prop = FindProperty(propertyPath);
content.text = prop.displayName;
content.tooltip = FindTooltip(propertyPath);
EditorGUILayout.Slider(prop, left, right, content, noOptions);
if (contextClick && Event.current.type == EventType.Used) CaptureContextClick(propertyPath);
}
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);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 58753931a68ae48b3973d0ce32d1a760
timeCreated: 1495461526
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,245 @@
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();
}
}
/// <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;
/// <summary>
/// Tag names and an additional 'Edit Tags...' entry.
/// Used for SingleTagField
/// </summary>
static string[] tagNamesAndEditTagsButton;
/// <summary>
/// Last time tagNamesAndEditTagsButton was updated.
/// Uses EditorApplication.timeSinceStartup
/// </summary>
static double timeLastUpdatedTagNames;
public static int TagField (string label, int value, System.Action editCallback) {
// Make sure the tagNamesAndEditTagsButton is relatively up to date
if (tagNamesAndEditTagsButton == null || EditorApplication.timeSinceStartup - timeLastUpdatedTagNames > 1) {
timeLastUpdatedTagNames = EditorApplication.timeSinceStartup;
var tagNames = AstarPath.FindTagNames();
tagNamesAndEditTagsButton = new string[tagNames.Length+1];
tagNames.CopyTo(tagNamesAndEditTagsButton, 0);
tagNamesAndEditTagsButton[tagNamesAndEditTagsButton.Length-1] = "Edit Tags...";
}
// Tags are between 0 and 31
value = Mathf.Clamp(value, 0, 31);
var newValue = EditorGUILayout.IntPopup(label, value, tagNamesAndEditTagsButton, new [] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1 });
// Last element corresponds to the 'Edit Tags...' entry. Open the tag editor
if (newValue == -1) {
editCallback();
} else {
value = newValue;
}
return value;
}
public static bool UnityTagMaskList (GUIContent label, bool foldout, List<string> tagMask) {
if (tagMask == null) throw new System.ArgumentNullException("tagMask");
if (EditorGUILayout.Foldout(foldout, label)) {
EditorGUI.indentLevel++;
GUILayout.BeginVertical();
for (int i = 0; i < tagMask.Count; i++) {
tagMask[i] = EditorGUILayout.TagField(tagMask[i]);
}
GUILayout.BeginHorizontal();
if (GUILayout.Button("Add Tag")) tagMask.Add("Untagged");
EditorGUI.BeginDisabledGroup(tagMask.Count == 0);
if (GUILayout.Button("Remove Last")) tagMask.RemoveAt(tagMask.Count-1);
EditorGUI.EndDisabledGroup();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
EditorGUI.indentLevel--;
return true;
}
return false;
}
/// <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 = Pathfinding.Util.ListPool<string>.Claim();
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();
Pathfinding.Util.ListPool<string>.Release(ref layers);
}
selected.value = EditorGUILayout.MaskField(label, selected.value, currentLayerNames);
return selected;
}
}
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2b6b4977544da4af3a4fe9e895fb6888
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 616267fcc419f44ea929599afa5c6aa2
timeCreated: 1500392257
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ec7eea22fd1c74193aa7d047949503e7
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@@ -0,0 +1,20 @@
{
"name": "PackageToolsEditor",
"rootNamespace": "",
"references": [
"AstarPathfindingProject",
"App",
"JNGame"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 774e21169c4ac4ec8a01db9cdb98d33b
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
using UnityEngine;
namespace Pathfinding {
/// <summary>\author http://wiki.unity3d.com/index.php/EnumFlagPropertyDrawer</summary>
public class EnumFlagAttribute : PropertyAttribute {
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e1a464aa9d87d439d9b54e2ed9027f5f
timeCreated: 1500392257
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
namespace Pathfinding {
[System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)]
public class UniqueComponentAttribute : System.Attribute {
public string tag;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e256d5533142c4434897b4da38791511
timeCreated: 1513613274
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using Game.Plugins.App;
using Game.Plugins.App.Sync;
using UnityEngine;
namespace Pathfinding {
/// <summary>Exposes internal methods from <see cref="Pathfinding.VersionedMonoBehaviour"/></summary>
public interface IVersionedMonoBehaviourInternal {
void UpgradeFromUnityThread();
}
/// <summary>Base class for all components in the package</summary>
public abstract class VersionedMonoBehaviour : JNGSyncFrameDefault, ISerializationCallbackReceiver, IVersionedMonoBehaviourInternal {
/// <summary>Version of the serialized data. Used for script upgrades.</summary>
[SerializeField]
[HideInInspector]
int version = 0;
public override void OnSyncLoad()
{
// Make sure the version field is up to date for components created during runtime.
// Reset is not called when in play mode.
// If the data had to be upgraded then OnAfterDeserialize would have been called earlier.
if (Application.isPlaying) version = OnUpgradeSerializedData(int.MaxValue, true);
}
/// <summary>Handle serialization backwards compatibility</summary>
protected virtual void Reset () {
// Set initial version when adding the component for the first time
version = OnUpgradeSerializedData(int.MaxValue, true);
}
/// <summary>Handle serialization backwards compatibility</summary>
void ISerializationCallbackReceiver.OnBeforeSerialize () {
}
/// <summary>Handle serialization backwards compatibility</summary>
void ISerializationCallbackReceiver.OnAfterDeserialize () {
UpgradeSerializedData(false);
}
protected void UpgradeSerializedData (bool isUnityThread) {
var r = OnUpgradeSerializedData(version, isUnityThread);
// Negative values (-1) indicate that the version number should not be updated
if (r >= 0) version = r;
}
/// <summary>Handle serialization backwards compatibility</summary>
protected virtual int OnUpgradeSerializedData (int version, bool unityThread) {
return 1;
}
void IVersionedMonoBehaviourInternal.UpgradeFromUnityThread () {
var r = OnUpgradeSerializedData(version, true);
if (r < 0) throw new System.Exception();
version = r;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6cce6945a1cc843b997a7abeb3a5013e
timeCreated: 1491213149
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: