diff options
Diffstat (limited to 'Assets/Packages/Lean/Common/Examples/Scripts')
8 files changed, 855 insertions, 0 deletions
diff --git a/Assets/Packages/Lean/Common/Examples/Scripts/LeanCircuit.cs b/Assets/Packages/Lean/Common/Examples/Scripts/LeanCircuit.cs new file mode 100644 index 0000000..4c77ab1 --- /dev/null +++ b/Assets/Packages/Lean/Common/Examples/Scripts/LeanCircuit.cs @@ -0,0 +1,372 @@ +using UnityEngine; +using System.Collections.Generic; +#if UNITY_EDITOR +using UnityEditor; + +namespace Lean.Common.Examples +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(LeanCircuit))] + public class LeanCircuit_Inspector : LeanInspector<LeanCircuit> + { + private int currentPath; + + protected override void DrawInspector() + { + if (Target.Paths != null) + { + currentPath = EditorGUILayout.IntSlider(currentPath, 0, Target.Paths.Count - 1); + } + + EditorGUILayout.Separator(); + + Draw("LineRadius"); + Draw("PointRadius"); + Draw("ShadowColor"); + Draw("ShadowOffset"); + + EditorGUILayout.Separator(); + + Draw("Paths"); + + Target.UpdateMesh(); + } + + protected override void DrawScene() + { + var dirty = false; + var matrix = Target.transform.localToWorldMatrix; + + Undo.RecordObject(Target, "Points Changed"); + + if (Target.Paths != null && currentPath >= 0 && currentPath < Target.Paths.Count) + { + var path = Target.Paths[currentPath]; + + if (path.Points != null) + { + Handles.matrix = matrix; + + Handles.BeginGUI(); + { + for (var i = 0; i < path.Points.Count; i++) + { + var point = path.Points[i]; + var pointName = "Point " + i; + var scrPoint = Camera.current.WorldToScreenPoint(matrix.MultiplyPoint(point)); + var rect = new Rect(0.0f, 0.0f, 50.0f, 20.0f); rect.center = new Vector2(scrPoint.x, Screen.height - scrPoint.y - 35.0f); + var rect1 = rect; rect.x += 1.0f; + var rect2 = rect; rect.x -= 1.0f; + var rect3 = rect; rect.y += 1.0f; + var rect4 = rect; rect.y -= 1.0f; + + GUI.Label(rect1, pointName, EditorStyles.miniBoldLabel); + GUI.Label(rect2, pointName, EditorStyles.miniBoldLabel); + GUI.Label(rect3, pointName, EditorStyles.miniBoldLabel); + GUI.Label(rect4, pointName, EditorStyles.miniBoldLabel); + GUI.Label(rect, pointName, EditorStyles.whiteMiniLabel); + } + + for (var i = 1; i < path.Points.Count; i++) + { + var pointA = path.Points[i - 1]; + var pointB = path.Points[i]; + var midPoint = (pointA + pointB) * 0.5f; + var scrPoint = Camera.current.WorldToScreenPoint(matrix.MultiplyPoint(midPoint)); + + if (GUI.Button(new Rect(scrPoint.x - 5.0f, Screen.height - scrPoint.y - 45.0f, 20.0f, 20.0f), "+") == true) + { + path.Points.Insert(i, midPoint); dirty = true; + } + } + } + Handles.EndGUI(); + + for (var i = 0; i < path.Points.Count; i++) + { + var oldPoint = path.Points[i]; + var newPoint = Handles.PositionHandle(oldPoint, Quaternion.identity); + + if (oldPoint != newPoint) + { + newPoint.x = Mathf.Round(newPoint.x); + newPoint.y = Mathf.Round(newPoint.y); + newPoint.z = Mathf.Round(newPoint.z); + + path.Points[i] = newPoint; dirty = true; + } + } + } + } + + if (dirty == true) + { + EditorUtility.SetDirty(Target); + } + } + } +} +#endif + +namespace Lean.Common.Examples +{ + /// <summary>This component generates a basic circuit mesh based on the specified paths, with circles at the end of each path, unless they intersect another.</summary> + [ExecuteInEditMode] + [DisallowMultipleComponent] + [RequireComponent(typeof(MeshFilter))] + [AddComponentMenu("")] + public class LeanCircuit : MonoBehaviour + { + [System.Serializable] + public class Path + { + public List<Vector3> Points; + } + + class Node + { + public Vector3 Point; + public int Count; + + public bool Increment(Vector3 p) + { + if (Point == p) + { + Count += 1; + + return true; + } + + return false; + } + } + + public List<Path> Paths; + + public float LineRadius = 0.2f; + + public float PointRadius = 0.5f; + + public Color ShadowColor = Color.black; + + public Vector3 ShadowOffset = Vector3.right; + + [System.NonSerialized] + private MeshFilter cachedMeshFilter; + + [System.NonSerialized] + private bool cachedMeshFilterSet; + + [System.NonSerialized] + private Mesh mesh; + + private static List<Vector3> positions = new List<Vector3>(); + + private static List<Vector3> normals = new List<Vector3>(); + + private static List<Color> colors = new List<Color>(); + + private static List<Vector2> coords = new List<Vector2>(); + + private static List<int> indices = new List<int>(); + + private static List<Node> nodes = new List<Node>(); + + [ContextMenu("Update Mesh")] + public void UpdateMesh() + { + if (cachedMeshFilterSet == false) + { + cachedMeshFilter = GetComponent<MeshFilter>(); + cachedMeshFilterSet = true; + } + + if (mesh == null) + { + mesh = new Mesh(); +#if UNITY_EDITOR + mesh.hideFlags = HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild; +#endif + mesh.name = "Circuit"; + + cachedMeshFilter.sharedMesh = mesh; + } + + positions.Clear(); + normals.Clear(); + colors.Clear(); + coords.Clear(); + indices.Clear(); + nodes.Clear(); + + if (Paths != null) + { + Populate(); + } + + mesh.Clear(); + mesh.SetVertices(positions); + mesh.SetColors(colors); + mesh.SetNormals(normals); + mesh.SetUVs(0, coords); + mesh.SetTriangles(indices, 0); + } + + private void Populate() + { + // Write shadows + foreach (var path in Paths) + { + if (path.Points != null) + { + for (var j = 1; j < path.Points.Count; j++) + { + var pointA = path.Points[j - 1]; + var pointB = path.Points[j]; + + AddNode(pointA); + AddNode(pointB); + + AddLine(ShadowOffset + pointA, ShadowOffset + pointB, ShadowColor); + } + } + } + + foreach (var node in nodes) + { + if (node.Count == 1) + { + AddPoint(node.Point + ShadowOffset, PointRadius, ShadowColor); + } + else + { + AddPoint(node.Point + ShadowOffset, LineRadius, ShadowColor); + } + } + + // Write main + foreach (var path in Paths) + { + if (path.Points != null) + { + for (var j = 1; j < path.Points.Count; j++) + { + var pointA = path.Points[j - 1]; + var pointB = path.Points[j]; + + AddLine(pointA, pointB, Color.white); + } + } + } + + foreach (var node in nodes) + { + if (node.Count == 1) + { + AddPoint(node.Point, PointRadius, Color.white); + } + else + { + AddPoint(node.Point, LineRadius, Color.white); + } + } + } + + protected virtual void Start() + { + UpdateMesh(); + } +#if UNITY_EDITOR + protected virtual void OnValidate() + { + if (mesh != null) + { + UpdateMesh(); + } + } +#endif + private void AddLine(Vector3 a, Vector3 b, Color color) + { + if (a != b) + { + var right = Vector3.Cross(a - b, Vector3.up).normalized * LineRadius; + var index = positions.Count; + + positions.Add(a - right); + positions.Add(a + right); + positions.Add(b + right); + positions.Add(b - right); + + colors.Add(color); + colors.Add(color); + colors.Add(color); + colors.Add(color); + + normals.Add(Vector3.up); + normals.Add(Vector3.up); + normals.Add(Vector3.up); + normals.Add(Vector3.up); + + coords.Add(Vector2.zero); + coords.Add(Vector2.one); + coords.Add(Vector2.one); + coords.Add(Vector2.zero); + + indices.Add(index + 2); + indices.Add(index + 1); + indices.Add(index ); + + indices.Add(index + 3); + indices.Add(index + 2); + indices.Add(index ); + } + } + + private void AddPoint(Vector3 a, float radius, Color color) + { + var index = positions.Count; + var count = 36; + var step = Mathf.PI * 2.0f / count; + + for (var i = 0; i < count; i++) + { + var angle = i * step; + + positions.Add(a + new Vector3(Mathf.Sin(angle) * radius, 0.0f, Mathf.Cos(angle) * radius)); + + colors.Add(color); + + normals.Add(Vector3.up); + + coords.Add(new Vector2(0.5f, 0.5f)); + } + + for (var i = 2; i < count; i++) + { + indices.Add(index ); + indices.Add(index + i - 1); + indices.Add(index + i); + } + } + + private void AddNode(Vector3 point) + { + for (var i = nodes.Count - 1; i >= 0; i--) + { + var node = nodes[i]; + + if (node.Increment(point) == true) + { + return; + } + } + + var addNode = new Node(); + + addNode.Point = point; + addNode.Count = 1; + + nodes.Add(addNode); + } + } +}
\ No newline at end of file diff --git a/Assets/Packages/Lean/Common/Examples/Scripts/LeanCircuit.cs.meta b/Assets/Packages/Lean/Common/Examples/Scripts/LeanCircuit.cs.meta new file mode 100644 index 0000000..50a877d --- /dev/null +++ b/Assets/Packages/Lean/Common/Examples/Scripts/LeanCircuit.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 18dbf1393b026d842b87a9b5cad94260 +timeCreated: 1552361716 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Packages/Lean/Common/Examples/Scripts/LeanDocumentation.cs b/Assets/Packages/Lean/Common/Examples/Scripts/LeanDocumentation.cs new file mode 100644 index 0000000..5818f48 --- /dev/null +++ b/Assets/Packages/Lean/Common/Examples/Scripts/LeanDocumentation.cs @@ -0,0 +1,234 @@ +#if UNITY_EDITOR +using UnityEngine; +using UnityEditor; +using UnityEditor.Callbacks; +using System.Collections.Generic; + +namespace Lean.Common.Examples +{ + [CustomEditor(typeof(TextAsset))] + public class LeanDocumentation_Inspector : Editor + { + private static GUIStyle titleStyle; + + private static GUIStyle headerStyle; + + private static GUIStyle bodyStyle; + + private static GUIStyle rateStyle; + + private Dictionary<string, string> infos = new Dictionary<string, string>(); + + private Texture2D icon; + + private Texture2D thumb; + + public static void UpdateStyles() + { + if (bodyStyle == null) + { + bodyStyle = new GUIStyle(EditorStyles.label); + bodyStyle.wordWrap = true; + bodyStyle.fontSize = 14; + + titleStyle = new GUIStyle(bodyStyle); + titleStyle.fontSize = 26; + titleStyle.alignment = TextAnchor.MiddleCenter; + + headerStyle = new GUIStyle(bodyStyle); + headerStyle.fontSize = 18 ; + + rateStyle = new GUIStyle(EditorStyles.toolbarButton); + + rateStyle.fontSize = 20; + } + } + + public override void OnInspectorGUI() + { + var path = AssetDatabase.GetAssetPath(target); + + if (path.Contains("Lean") == true && path.EndsWith("DOCUMENTATION.html") == true) + { + UpdateStyles(); + + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.LabelField("Thank You For Using " + Info("Title", "this asset") + "!", headerStyle); + EditorGUILayout.LabelField("The documentation is in HTML format. You can open it by double clicking on this file, or by clicking below.", bodyStyle); + + if (GUILayout.Button(new GUIContent("Open Documentation", "Open In Web Browser")) == true) + { + System.Diagnostics.Process.Start(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), path)); + } + + EditorGUILayout.Separator(); + EditorGUILayout.Separator(); + + EditorGUILayout.LabelField("Need Help?", headerStyle); + EditorGUILayout.LabelField("If you read the documentation and still have questions, feel free to ask!", bodyStyle); + + if (infos.ContainsKey("Forum") == true) + { + if (GUILayout.Button("Forum Thread") == true) + { + Application.OpenURL(Info("Forum")); + } + } + + if (infos.ContainsKey("YouTube") == true) + { + if (GUILayout.Button("YouTube Channel") == true) + { + Application.OpenURL(Info("YouTube")); + } + } + + if (GUILayout.Button(new GUIContent("E-Mail Me", "carlos.wilkes@gmail.com")) == true) + { + Application.OpenURL("mailto:carlos.wilkes@gmail.com"); + } + + if (GUILayout.Button(new GUIContent("Private Message", "Unity Forum Profile")) == true) + { + Application.OpenURL("http://forum.unity.com/members/41960"); + } + + EditorGUILayout.Separator(); + EditorGUILayout.Separator(); + + EditorGUILayout.LabelField("You're Awesome!", headerStyle); + EditorGUILayout.LabelField("If you haven't already, please consider rating this asset. It really helps me out!", bodyStyle); + + if (GUILayout.Button(new GUIContent("Rate This Asset", Info("Title") + " Asset Page")) == true) + { + Application.OpenURL("http://CarlosWilkes.com/Get/" + Info("Link")); + } + + EditorGUILayout.Separator(); + EditorGUILayout.Separator(); + + EditorGUILayout.LabelField("Made Something Cool?", headerStyle); + EditorGUILayout.LabelField("If you've finished a project using " + Info("Title") + " then let me know! I can shout you out, link to you from my website, and much more!", bodyStyle); + + if (GUILayout.Button(new GUIContent("E-Mail Me", "carlos.wilkes@gmail.com")) == true) + { + Application.OpenURL("mailto:carlos.wilkes@gmail.com"); + } + + EditorGUILayout.Separator(); + EditorGUILayout.Separator(); + + EditorGUILayout.LabelField("Want More?", headerStyle); + EditorGUILayout.LabelField("Check out all my other great assets, I'm sure there's something there that can help you!", bodyStyle); + + if (GUILayout.Button(new GUIContent("My Website", "CarlosWilkes.com")) == true) + { + Application.OpenURL("http://CarlosWilkes.com" + Info("Link")); + } + } + else + { + base.OnInspectorGUI(); + } + } + + protected override void OnHeaderGUI() + { + UpdateStyles(); + + GUILayout.BeginHorizontal("In BigTitle"); + { + var iconWidth = Mathf.Min(EditorGUIUtility.currentViewWidth/3f - 20f, 128f); + var content = new GUIContent(Info("Title", "Documentation").Replace(' ', '\n')); + + var height = Mathf.Max(titleStyle.CalcHeight(content, EditorGUIUtility.currentViewWidth - iconWidth), iconWidth); + + if (icon != null) + { + GUILayout.Label(icon, EditorStyles.centeredGreyMiniLabel, GUILayout.Width(iconWidth), GUILayout.Height(iconWidth)); + } + + GUILayout.Label(content, titleStyle, GUILayout.Height(height)); + } + GUILayout.EndHorizontal(); + } + + protected virtual void OnEnable() + { + var textAsset = (TextAsset)target; + var text = textAsset.text; + var blockA = text.IndexOf("<!--"); + var blockB = text.IndexOf("-->"); + + if (blockA >= 0 && blockB >= 0) + { + var section = text.Substring(blockA, blockB - blockA); + var lines = section.Split('\r', '\n'); + + foreach (var line in lines) + { + var tokens = line.Split(':'); + + if (tokens.Length == 2) + { + var k = tokens[0]; + var v = tokens[1]; + + if (k == "Icon") + { + icon = new Texture2D(1, 1); + + icon.LoadImage(System.Convert.FromBase64String(v)); + } + else if (k == "Thumb") + { + thumb = new Texture2D(1, 1); + + thumb.LoadImage(System.Convert.FromBase64String(v)); + } + else + { + infos.Add(k, v); + } + } + } + } + } + + private string Info(string key, string fallback = null) + { + var value = default(string); + + if (infos.TryGetValue(key, out value) == false) + { + value = fallback; + } + + return value; + } + } +} + +namespace Lean.Common.Examples +{ + /// <summary>Unity hijacks html file opening and passes it to the default text editor. For documentation files we want to use an actual browser for this, so hijack it back!</summary> + public static class LeanDocumentation + { + [OnOpenAsset(1)] + public static bool step1(int instanceID, int line) + { + var path = AssetDatabase.GetAssetPath(instanceID); + + if (path.Contains("Lean") == true && path.EndsWith("DOCUMENTATION.html") == true) + { + System.Diagnostics.Process.Start(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), path)); + + return true; + } + + return false; + } + } +} +#endif
\ No newline at end of file diff --git a/Assets/Packages/Lean/Common/Examples/Scripts/LeanDocumentation.cs.meta b/Assets/Packages/Lean/Common/Examples/Scripts/LeanDocumentation.cs.meta new file mode 100644 index 0000000..c512636 --- /dev/null +++ b/Assets/Packages/Lean/Common/Examples/Scripts/LeanDocumentation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 65f14352023e7024bbd09d26a3e8379e +timeCreated: 1547108494 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Packages/Lean/Common/Examples/Scripts/LeanMarker.cs b/Assets/Packages/Lean/Common/Examples/Scripts/LeanMarker.cs new file mode 100644 index 0000000..08c84fd --- /dev/null +++ b/Assets/Packages/Lean/Common/Examples/Scripts/LeanMarker.cs @@ -0,0 +1,187 @@ +using UnityEngine; +using System.Collections.Generic; +#if UNITY_EDITOR +using UnityEditor; + +namespace Lean.Common.Examples +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(LeanMarker))] + public class LeanMarker_Inspector : LeanInspector<LeanMarker> + { + protected override void DrawInspector() + { + BeginError(Any(t => t.Target == null)); + Draw("target"); + EndError(); + } + } +} +#endif + +namespace Lean.Common.Examples +{ + /// <summary>This component marks the Target object using the current GameObject name. + /// This allows you to quickly find and access it from anywhere using the LeanMarker.Reference component.</summary> + [ExecuteInEditMode] + [DisallowMultipleComponent] + [AddComponentMenu("Lean/Common/Lean Marker")] + public class LeanMarker : MonoBehaviour + { + /// <summary>This struct can be added to your custom components, allowing you to quickly find and efficiently access a marked GameObject.</summary> + public class Reference<T> + where T : Object + { + public Reference(string newName) + { + if (string.IsNullOrEmpty(newName) == true) + { + throw new System.ArgumentException("Cannot reference a null or empty marker!"); + } + + name = newName; + } + + protected string name; + + protected bool cached; + + protected T instance; + + public T Instance + { + get + { + if (cached == false) + { + Find(); + } + + return instance; + } + } + + protected virtual void Build(LeanMarker marker) + { + if (typeof(T) == typeof(GameObject)) + { + if (marker.target != null) + { + if (marker.target is GameObject) + { + instance = (T)marker.target; return; + } + else if (marker.target is Component) + { + instance = (T)(Object)((Component)marker.target).gameObject; return; + } + } + else + { + instance = (T)(Object)marker.gameObject; return; + } + } + else if (typeof(T).IsSubclassOf(typeof(Component))) + { + if (marker.target != null) + { + if (marker.target is T) + { + instance = (T)marker.target; return; + } + else if (marker.target is GameObject) + { + var component = ((GameObject)marker.target).GetComponent<T>(); + + if (component != null) + { + instance = component; return; + } + } + else if (marker.target is Component) + { + var component = ((Component)marker.target).GetComponent<T>(); + + if (component != null) + { + instance = component; return; + } + } + } + else + { + var component = marker.gameObject.GetComponent<T>(); + + if (component != null) + { + instance = component; return; + } + } + } + else if (marker.target != null && marker.target is T) + { + instance = (T)marker.target; return; + } + + throw new System.MissingMemberException(); + } + + protected void Find() + { + var marker = default(LeanMarker); + + if (instances.TryGetValue(name, out marker) == true) + { + Build(marker); + + return; + } + else + { + var markers = FindObjectsOfType<LeanMarker>(); + + for (var i = markers.Length - 1; i >= 0; i--) + { + marker = markers[i]; + + if (marker.name == name) + { + Build(marker); + + return; + } + } + } + + throw new System.NullReferenceException("Failed to find LeanMarker in scene with name: " + name); + } + } + + /// <summary>This stores all active an enables LeanMarker instances by their GameObject name.</summary> + private static Dictionary<string, LeanMarker> instances = new Dictionary<string, LeanMarker>(); + + /// <summary>The marker is pointing to this Object.</summary> + public Object Target { set { target = value; } get { return target; } } [SerializeField] private Object target; + + [System.NonSerialized] + private string registeredName; + + protected virtual void OnEnable() + { + registeredName = name; + + instances.Add(registeredName, this); + } + + protected virtual void OnDisable() + { + instances.Remove(registeredName); + } +#if UNITY_EDITOR + protected virtual void Reset() + { + target = gameObject; + } +#endif + } +}
\ No newline at end of file diff --git a/Assets/Packages/Lean/Common/Examples/Scripts/LeanMarker.cs.meta b/Assets/Packages/Lean/Common/Examples/Scripts/LeanMarker.cs.meta new file mode 100644 index 0000000..3ebb4f9 --- /dev/null +++ b/Assets/Packages/Lean/Common/Examples/Scripts/LeanMarker.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 92c28bfb30939ec488369dd7c86076bc +timeCreated: 1552361716 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Packages/Lean/Common/Examples/Scripts/LeanOpenUrl.cs b/Assets/Packages/Lean/Common/Examples/Scripts/LeanOpenUrl.cs new file mode 100644 index 0000000..487d691 --- /dev/null +++ b/Assets/Packages/Lean/Common/Examples/Scripts/LeanOpenUrl.cs @@ -0,0 +1,14 @@ +using UnityEngine; + +namespace Lean.Common.Examples +{ + /// <summary>This component allows you to open a URL using Unity events (e.g. a button).</summary> + [AddComponentMenu("Lean/Common/Lean Open URL")] + public class LeanOpenUrl : MonoBehaviour + { + public void Open(string url) + { + Application.OpenURL(url); + } + } +}
\ No newline at end of file diff --git a/Assets/Packages/Lean/Common/Examples/Scripts/LeanOpenUrl.cs.meta b/Assets/Packages/Lean/Common/Examples/Scripts/LeanOpenUrl.cs.meta new file mode 100644 index 0000000..0edd39e --- /dev/null +++ b/Assets/Packages/Lean/Common/Examples/Scripts/LeanOpenUrl.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ade1290dfbabb0c48b773644d6d4bdf6 +timeCreated: 1474724095 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |
