├── .gitignore
├── Assets
├── Editor.meta
├── Editor
│ ├── OTIEditorBase.cs
│ ├── OTIEditorBase.cs.meta
│ ├── OTIEditorUtility.cs
│ ├── OTIEditorUtility.cs.meta
│ ├── WorldMonitorsEditor.cs
│ └── WorldMonitorsEditor.cs.meta
├── Gizmos.meta
├── Gizmos
│ ├── marker.tif
│ └── marker.tif.meta
├── License.meta
├── License
│ ├── UnityOctree.meta
│ └── UnityOctree
│ │ ├── LICENCE
│ │ ├── LICENCE.meta
│ │ ├── README.md
│ │ └── README.md.meta
├── Materials.meta
├── Materials
│ ├── Black.mat
│ ├── Black.mat.meta
│ ├── Blue.mat
│ ├── Blue.mat.meta
│ ├── Bright.mat
│ ├── Bright.mat.meta
│ ├── ChocBlk.mat
│ ├── ChocBlk.mat.meta
│ ├── Dark Transparent.mat
│ ├── Dark Transparent.mat.meta
│ ├── Light Blue.mat
│ ├── Light Blue.mat.meta
│ ├── Lime Green.mat
│ ├── Lime Green.mat.meta
│ ├── Orange.mat
│ ├── Orange.mat.meta
│ ├── Pink.mat
│ ├── Pink.mat.meta
│ ├── Purple.mat
│ ├── Purple.mat.meta
│ ├── Yellow.mat
│ └── Yellow.mat.meta
├── OTIJob.cs
├── OTIJob.cs.meta
├── OTIUtilities.cs
├── OTIUtilities.cs.meta
├── Octree.meta
├── Octree
│ ├── Octree.cs
│ └── Octree.cs.meta
├── Scenes.meta
├── Scenes
│ ├── Example Scenes.meta
│ └── Example Scenes
│ │ ├── ExampleNavigator.cs
│ │ ├── ExampleNavigator.cs.meta
│ │ ├── SmallTrackingExample.unity
│ │ ├── SmallTrackingExample.unity.meta
│ │ ├── Tracker.cs
│ │ ├── Tracker.cs.meta
│ │ ├── TrackingExample.unity
│ │ └── TrackingExample.unity.meta
├── TrackedObjectTriggers.cs
├── TrackedObjectTriggers.cs.meta
├── UnityOctree.meta
├── UnityOctree
│ ├── BoundsOctree.cs
│ ├── BoundsOctree.cs.meta
│ ├── BoundsOctreeNode.cs
│ ├── BoundsOctreeNode.cs.meta
│ ├── PointOctree.cs
│ ├── PointOctree.cs.meta
│ ├── PointOctreeNode.cs
│ └── PointOctreeNode.cs.meta
├── WorldMonitor.cs
├── WorldMonitor.cs.meta
├── WorldMonitors.cs
└── WorldMonitors.cs.meta
├── Images
├── 20k.PNG
├── exampleTrack.PNG
├── inspInitial.PNG
├── inspSymmetricObjects.PNG
├── smallScene.PNG
├── trackingScene.PNG
├── triggerVsOctreeConflict.PNG
└── worldMonitor.PNG
├── LICENSE
├── Packages
└── manifest.json
├── ProjectSettings
├── AudioManager.asset
├── ClusterInputManager.asset
├── DynamicsManager.asset
├── EditorBuildSettings.asset
├── EditorSettings.asset
├── GraphicsSettings.asset
├── InputManager.asset
├── NavMeshAreas.asset
├── NetworkManager.asset
├── Physics2DSettings.asset
├── PresetManager.asset
├── ProjectSettings.asset
├── ProjectVersion.txt
├── QualitySettings.asset
├── TagManager.asset
├── TimeManager.asset
└── UnityConnectSettings.asset
├── README.md
└── THIRD_PARTY_NOTICES.md
/.gitignore:
--------------------------------------------------------------------------------
1 | [Ll]ibrary/
2 | [Tt]emp/
3 | [Oo]bj/
4 | [Bb]uild/
5 | [Bb]uilds/
6 | Assets/AssetStoreTools*
7 |
8 | # Visual Studio cache directory
9 | .vs/
10 |
11 | # Autogenerated VS/MD/Consulo solution and project files
12 | ExportedObj/
13 | .consulo/
14 | *.csproj
15 | *.unityproj
16 | *.sln
17 | *.suo
18 | *.tmp
19 | *.user
20 | *.userprefs
21 | *.pidb
22 | *.booproj
23 | *.svd
24 | *.pdb
25 | *.opendb
26 |
27 | # Unity3D generated meta files
28 | *.pidb.meta
29 | *.pdb.meta
30 |
31 | # Unity3D Generated File On Crash Reports
32 | sysinfo.txt
33 |
34 | # Builds
35 | *.apk
36 | *.unitypackage
37 |
--------------------------------------------------------------------------------
/Assets/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9c657c6e0fb80574cae875ec85a97935
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Editor/OTIEditorBase.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEditor;
5 | using oti.AI;
6 |
7 | namespace oti.Editors
8 | {
9 | ///
10 | /// This class is part of a much larger repository, not all of this may be used here.
11 | /// Feel free to use them if you wish.
12 | ///
13 | public class OTIEditorBase : Editor
14 | {
15 | public void Enable()
16 | {
17 | if (!OTIEditorUtility.Instance)
18 | {
19 | OTIEditorUtility AIE = ScriptableObject.CreateInstance();
20 | OTIEditorUtility.Instance = AIE;
21 | }
22 |
23 | EditorFormat = OTIEditorFormat._ReturnSet(this, "The component that factors into this behavior's cost during decision making");
24 | setFormats();
25 | }
26 |
27 | public void spaces(int numberOfSpaces)
28 | {
29 | for (int i = 0; i < numberOfSpaces; i++)
30 | EditorGUILayout.Space();
31 | }
32 |
33 | public OTIEditorFormat EditorFormat;
34 | public GUIStyle headingStyle;
35 | public GUIStyle subHeadingStyle;
36 | public GUIStyle guiStyle;
37 | public GUIStyle contentStyle;
38 | public GUIContent guiContent;
39 | public GUIContent gtSuccess;
40 | public GUIContent gtFailure;
41 | public GUIContent gtDestinations;
42 |
43 | void setFormats()
44 | {
45 | headingStyle = EditorFormat.HeaderFormat;
46 | subHeadingStyle = EditorFormat.SubHeaderFormat;
47 | contentStyle = EditorFormat.ContentStyle;
48 |
49 | guiStyle = new GUIStyle
50 | {
51 | fontSize = 16,
52 | fontStyle = FontStyle.Bold
53 | };
54 |
55 | guiContent = new GUIContent
56 | {
57 | text = " Costs",
58 | tooltip = "The component that factors into this behavior's cost during decision making"
59 | };
60 |
61 | gtSuccess = new GUIContent
62 | {
63 | text = "Successes",
64 | };
65 |
66 | gtFailure = new GUIContent
67 | {
68 | text = " Failures",
69 | };
70 |
71 | gtDestinations = new GUIContent
72 | {
73 | text = "Destinations",
74 | };
75 |
76 | headingStyle.normal.textColor = OTIEditorFormat.OTINavy;
77 | contentStyle.normal.textColor = OTIEditorFormat.OTINavy;
78 | }
79 |
80 | public static string _WorldMonitoringExplanation = "Use this utility to give the agent awareness of events going on in the environment.";
81 |
82 | public static string _WorldMonitorSingleton = "The World Monitor: choose the parameters for your tracking system here.";
83 | }
84 |
85 | public struct OTIEditorFormat
86 | {
87 | public GUIStyle HeaderFormat;
88 | public GUIStyle SubHeaderFormat;
89 | public GUIStyle ContentStyle;
90 | public GUIContent GUIText;
91 | public static Color OTINavy = new Color(0, 0, 0.42f, 1);
92 | public static Color OTIOrange = new Color(1, 0.45f, 0, 1);
93 |
94 | public static OTIEditorFormat _ReturnSet(object sender, string _tooltip, int overrideFontSize = default(int))
95 | {
96 | OTIEditorFormat ef = new OTIEditorFormat();
97 | bool overFont = overrideFontSize != default(int);
98 | ef.HeaderFormat = new GUIStyle
99 | {
100 | fontSize = overFont ? overrideFontSize : 15,
101 | fontStyle = FontStyle.Bold,
102 | alignment = TextAnchor.MiddleCenter
103 | };
104 | ef.SubHeaderFormat = new GUIStyle
105 | {
106 | fontSize = overFont ? overrideFontSize : 14,
107 | alignment = TextAnchor.LowerLeft,
108 | fontStyle = FontStyle.Bold,
109 | wordWrap = true
110 | };
111 | ef.ContentStyle = new GUIStyle
112 | {
113 | fontSize = 11,
114 | alignment = TextAnchor.MiddleLeft,
115 | wordWrap = true
116 | };
117 | ef.GUIText = new GUIContent
118 | {
119 | text = sender.ToString(),
120 | tooltip = _tooltip
121 | };
122 | return ef;
123 | }
124 | }
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/Assets/Editor/OTIEditorBase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 15911c7ddd311bf448347301b984de4a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/Editor/OTIEditorUtility.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEditor;
3 | using UnityEngine;
4 | using System.Collections.Generic;
5 | using oti.Editors;
6 |
7 | namespace oti.AI
8 | {
9 | ///
10 | /// This class is part of a much larger repository, many of these methods are not used in this repo.
11 | /// Feel free to use them if you wish.
12 | ///
13 | public class OTIEditorUtility : Editor
14 | {
15 | ///
16 | /// Singleton implementation
17 | ///
18 | private static OTIEditorUtility _instance = null;
19 |
20 | public static OTIEditorUtility Instance
21 | {
22 | get
23 | {
24 | return _instance;
25 | }
26 | set
27 | {
28 | _instance = value;
29 | }
30 | }
31 |
32 | public void OnEnable()
33 | {
34 | if (_instance != null && _instance != this)
35 | {
36 | DestroyImmediate(this);
37 | return;
38 | }
39 | if (headingStyle == null)
40 | setFormats();
41 | }
42 |
43 | public static void _Enable()
44 | {
45 | _instance = new OTIEditorUtility();
46 | }
47 |
48 | ///
49 | /// Style used for OTI headers
50 | ///
51 | private GUIStyle headingStyle;
52 |
53 | ///
54 | /// Style used for inspector content
55 | ///
56 | private GUIStyle contentStyle;
57 |
58 | ///
59 | /// Places consistent format title on each OTI inspector.
60 | ///
61 | public void OTIHead(string title, string explanation, int padding = default(int))
62 | {
63 | spaces(2);
64 |
65 | if (headingStyle == null)
66 | setFormats();
67 |
68 | headingStyle.normal.textColor = OTIEditorFormat.OTINavy;
69 | Color ctemp = contentStyle.normal.textColor;
70 | contentStyle.normal.textColor = OTIEditorFormat.OTINavy;
71 |
72 | EditorGUILayout.LabelField("| " + title + " |", headingStyle);
73 | contentStyle.fontStyle = FontStyle.Italic;
74 | EditorGUILayout.LabelField(explanation, contentStyle);
75 | contentStyle.fontStyle = FontStyle.Normal;
76 |
77 | contentStyle.normal.textColor = ctemp;
78 | spaces(padding);
79 | }
80 |
81 | void setFormats()
82 | {
83 | headingStyle = new GUIStyle
84 | {
85 | fontSize = 15,
86 | fontStyle = FontStyle.Bold,
87 | alignment = TextAnchor.MiddleCenter
88 | };
89 | contentStyle = new GUIStyle
90 | {
91 | fontSize = 11,
92 | alignment = TextAnchor.MiddleLeft,
93 | wordWrap = true
94 | };
95 | }
96 |
97 | private void spaces(int numberOfSpaces)
98 | {
99 | for(int i = 0; i < numberOfSpaces; i++)
100 | EditorGUILayout.Space();
101 | }
102 |
103 | ///
104 | /// Places a horizontal bar in editor.
105 | ///
106 | /// (opt) Places bold text directly above bar.
107 | /// (opt) Helpful for elaborating on the title.
108 | /// (opt for title - default = 2)
109 | public void HorizontalLine(string titleBar = default(string), string appendedText = default(string), int padding = 2)
110 | {
111 | spaces(2);
112 | GUIStyle TitleStyle = new GUIStyle
113 | {
114 | fontSize = 9,
115 | fontStyle = FontStyle.Bold,
116 | alignment = TextAnchor.LowerLeft
117 | };
118 | if(titleBar != default(string))
119 | {
120 | spaces(padding);
121 | EditorGUILayout.LabelField(titleBar, TitleStyle);
122 | }
123 |
124 | EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
125 | if(appendedText != default(string))
126 | {
127 | Color cTemp = contentStyle.normal.textColor;
128 | contentStyle.normal.textColor = OTIEditorFormat.OTINavy;
129 | EditorGUILayout.LabelField(appendedText, contentStyle);
130 | contentStyle.normal.textColor = cTemp;
131 | spaces(1);
132 | }
133 | }
134 |
135 | ///
136 | /// Places a horizontal bar in editor with a float property.
137 | ///
138 | /// (opt) Places bold text directly above bar.
139 | /// (opt) Helpful for elaborating on the title.
140 | /// (opt for title - default = 2)
141 | public void HorizontalLineProperty(ref List components, int index, string titleBar = default(string), string fieldTitle = default(string), string appendedText = default(string), int padding = 2)
142 | {
143 | spaces(2);
144 | EditorGUIUtility.fieldWidth = 42;
145 |
146 | GUIStyle TitleStyle = new GUIStyle
147 | {
148 | fontSize = 9,
149 | fontStyle = FontStyle.Bold,
150 | alignment = TextAnchor.MiddleLeft
151 | };
152 |
153 | if (titleBar != default(string))
154 | {
155 | spaces(padding);
156 | EditorGUILayout.BeginHorizontal();
157 | EditorGUILayout.LabelField(titleBar, TitleStyle);
158 |
159 | TitleStyle.alignment = TextAnchor.MiddleRight;
160 | TitleStyle.fontStyle = FontStyle.Normal;
161 |
162 | EditorGUILayout.PrefixLabel(fieldTitle, TitleStyle);
163 | components[index] = EditorGUILayout.FloatField(components[index]);
164 | EditorGUILayout.EndHorizontal();
165 | }
166 |
167 | EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
168 | if (appendedText != default(string))
169 | {
170 | Color cTemp = contentStyle.normal.textColor;
171 | contentStyle.normal.textColor = OTIEditorFormat.OTINavy;
172 | EditorGUILayout.LabelField(appendedText, contentStyle);
173 | contentStyle.normal.textColor = cTemp;
174 | spaces(1);
175 | }
176 | }
177 |
178 | }
179 | }
--------------------------------------------------------------------------------
/Assets/Editor/OTIEditorUtility.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ff2b0c03a4895475bbb554a95947de6e
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/Editor/WorldMonitorsEditor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 | using UnityEditor;
4 | using oti.AI;
5 | using oti.Editors;
6 | using oti.Utilities;
7 |
8 | namespace oti.Editors
9 | {
10 | [CanEditMultipleObjects]
11 | [CustomEditor(typeof(WorldMonitors))]
12 | public class WorldMonitorsEditor : OTIEditorBase
13 | {
14 | ///
15 | /// Number of distinct tracked object fields
16 | ///
17 | private int numberTrackedFields;
18 |
19 | ///
20 | /// A limit imposed for performance.
21 | ///
22 | private int maxNumberTrackedFields;
23 |
24 | ///
25 | /// Used to determine if field inspector should be exposed
26 | ///
27 | bool[] show = new bool[701]; //limit 701 sets of tracked objects
28 |
29 | ///
30 | /// Access to components in WorldMonitors
31 | ///
32 | WorldMonitors instance;
33 |
34 | private void OnEnable()
35 | {
36 | instance = target as WorldMonitors;
37 |
38 | maxNumberTrackedFields = show.Length;
39 | numberTrackedFields = Mathf.Max(1, numberTrackedFields);
40 |
41 | if (instance.TrackedObjects.Count == 0)
42 | instance.TrackedObjects.Add(new TrackedObjectContainer());
43 |
44 | base.Enable();
45 | if (!OTIEditorUtility.Instance)
46 | {
47 | OTIEditorUtility AIE = ScriptableObject.CreateInstance();
48 | OTIEditorUtility.Instance = AIE;
49 | }
50 |
51 | serializedObject.ApplyModifiedProperties();
52 | }
53 |
54 | public override void OnInspectorGUI()
55 | {
56 | OTIEditorUtility.Instance.OTIHead("Agent World Monitoring", _WorldMonitoringExplanation);
57 | OTIEditorUtility.Instance.HorizontalLine();
58 |
59 | numberTrackedFields = Mathf.Max(1, instance.TrackedObjects.Count);
60 |
61 | if (numberTrackedFields >= 701)
62 | Debug.LogWarning("701 tracked fields is the limit, additional fields must be added at runtime.");
63 |
64 | if (instance.TrackedObjects.Count == 0)
65 | instance.TrackedObjects.Add(new TrackedObjectContainer());
66 |
67 | if (instance.ThresholdSet.Count == 0)
68 | instance.ThresholdSet.Add(new float());
69 |
70 | addMinusIntValueButtons(ref numberTrackedFields, ref instance.TrackedObjects, ref instance.ThresholdSet, "Add Tracked Field", "Remove Tracked Field", maxNumber: maxNumberTrackedFields);
71 |
72 | if (instance.ThresholdSet.Count > 0)
73 | {
74 | float tThreshold = instance.ThresholdSet[0];
75 | OTIEditorUtility.Instance.HorizontalLineProperty(ref instance.ThresholdSet, 0, "Tracked Object Set A", "Threshold Distance A", "Assign objects for tracking against each other. Set A will be tracked against all others.");
76 | trackedObjectListManager(0, guiContent, headingStyle, subHeadingStyle, "", "Tracked Objects", ref show[0], padding: 1);
77 |
78 | if (instance.ThresholdSet[0] != tThreshold)
79 | enforceStaticThreshold(0, instance.ThresholdSet[0]);
80 |
81 | for (int i = 1; i < numberTrackedFields; i++)
82 | {
83 | tThreshold = instance.ThresholdSet[i];
84 | OTIEditorUtility.Instance.HorizontalLineProperty(ref instance.ThresholdSet, i, "Tracked Object Set " + OTIUtilities._AlphabetAssembler(i), "Threshold Distance " + OTIUtilities._AlphabetAssembler(i), "Assign objects for tracking against each other. Set " + OTIUtilities._AlphabetAssembler(i) + " will be tracked against all others.");
85 | trackedObjectListManager(i, guiContent, headingStyle, subHeadingStyle, "", "Tracked Objects", ref show[i], padding: 1);
86 | serializedObject.ApplyModifiedProperties();
87 |
88 | if (instance.ThresholdSet[i] != tThreshold)
89 | enforceStaticThreshold(i, instance.ThresholdSet[i]);
90 | }
91 | }
92 |
93 | serializedObject.ApplyModifiedProperties();
94 | }
95 |
96 | ///
97 | /// Ensures threshold sizes are consistent across all instances
98 | ///
99 | private void enforceStaticThreshold(int index, float threshold)
100 | {
101 | WorldMonitors[] agentMonitors = GameObject.FindObjectsOfType();
102 |
103 | for (int i = 0; i < agentMonitors.Length; i++)
104 | {
105 | if (index < agentMonitors[i].ThresholdSet.Count)
106 | agentMonitors[i].ThresholdSet[index] = threshold;
107 | }
108 | }
109 |
110 |
111 | ///
112 | /// Similar to method in AIEditor class but modified for WorldMonitors.
113 | ///
114 | /// Current index of TrackedObjects list.
115 | private void trackedObjectListManager(int i, GUIContent guiText, GUIStyle headingStyle, GUIStyle subHeadingStyle, string typeOfFactor, string head, ref bool showField, int padding = default(int))
116 | {
117 | Rect plotSpace = new Rect();
118 | plotSpace = GUILayoutUtility.GetLastRect();
119 |
120 | float viewWidth = EditorGUIUtility.currentViewWidth;
121 | plotSpace = new Rect(0, plotSpace.yMax + 2, 500, 1000);
122 |
123 | GUIStyle gs = headingStyle;
124 | Color ogc = gs.normal.textColor;
125 | gs.alignment = TextAnchor.MiddleLeft;
126 |
127 | EditorGUILayout.BeginHorizontal();
128 |
129 | string buttonDisp = showField ? "-" : "+";
130 | bool input = GUILayout.Button(buttonDisp, EditorStyles.miniButton, GUILayout.Width(42));
131 | EditorGUILayout.LabelField(head, subHeadingStyle);
132 | EditorGUILayout.EndHorizontal();
133 |
134 | if (input && showField)
135 | {
136 | showField = false;
137 | EditorGUILayout.EndHorizontal();
138 | }
139 | else if (input || showField)
140 | {
141 | showField = true;
142 | GUILayoutOption miniButtonWidth = GUILayout.Width(viewWidth / 2 - 20);
143 | EditorGUILayout.BeginHorizontal();
144 |
145 | if (GUILayout.Button("Add " + typeOfFactor, EditorStyles.miniButton, miniButtonWidth))
146 | {
147 | instance.TrackedObjects[i].TrackedObjects.Add(null);
148 | }
149 |
150 | if (GUILayout.Button("Delete " + typeOfFactor, EditorStyles.miniButton, miniButtonWidth))
151 | {
152 | if (instance.TrackedObjects[i].TrackedObjects.Count - 1 >= 0)
153 | instance.TrackedObjects[i].TrackedObjects.RemoveAt(instance.TrackedObjects[i].TrackedObjects.Count - 1);
154 | }
155 |
156 | EditorGUILayout.EndHorizontal();
157 | for (int j = 0; j < instance.TrackedObjects[i].TrackedObjects.Count; j++)
158 | {
159 | EditorGUILayout.BeginHorizontal();
160 | instance.TrackedObjects[i].TrackedObjects[j] = (GameObject)EditorGUILayout.ObjectField(instance.TrackedObjects[i].TrackedObjects[j], typeof(GameObject), true);//EditorGUILayout.PropertyField(so, new GUIContent(typeOfFactor), true);
161 | EditorGUILayout.EndHorizontal();
162 | }
163 | }
164 |
165 | gs.normal.textColor = ogc;
166 | gs.alignment = TextAnchor.MiddleCenter;
167 | spaces(numberOfSpaces: padding);
168 | }
169 |
170 | ///
171 | /// Similar to method in AIEditor class but modified for WorldMonitors.
172 | ///
173 | private void addMinusIntValueButtons(ref int intComponent, ref List p1, ref List p2, string addButtonLabel = default(string), string minusButtonLabel = default(string), int minNumber = 1, int maxNumber = 4)
174 | {
175 | if (intComponent == maxNumber)
176 | return;
177 |
178 | addButtonLabel = addButtonLabel == default(string) ? "+" : addButtonLabel;
179 | minusButtonLabel = minusButtonLabel == default(string) ? "-" : minusButtonLabel;
180 |
181 | EditorGUILayout.BeginHorizontal();
182 | if (GUILayout.Button(addButtonLabel, EditorStyles.miniButtonLeft, GUILayout.Width(142)))
183 | {
184 | p1.Add(new TrackedObjectContainer());
185 | p2.Add(new float());
186 | intComponent += 1;
187 | }
188 |
189 | if (GUILayout.Button(minusButtonLabel, EditorStyles.miniButtonRight, GUILayout.Width(142)) && intComponent != minNumber - 1)
190 | {
191 | p1.RemoveAt(p1.Count - 1);
192 | p2.RemoveAt(p2.Count - 1);
193 | intComponent -= 1;
194 | }
195 | EditorGUILayout.EndHorizontal();
196 | }
197 | }
198 | }
--------------------------------------------------------------------------------
/Assets/Editor/WorldMonitorsEditor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0c17e869e55910e439359242288ae258
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/Gizmos.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ef897eb1e3ed2e94d93e0ec89883675b
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Gizmos/marker.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Assets/Gizmos/marker.tif
--------------------------------------------------------------------------------
/Assets/Gizmos/marker.tif.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1107feee395f6bf449de6678527683c0
3 | timeCreated: 1481513783
4 | licenseType: Pro
5 | TextureImporter:
6 | fileIDToRecycleName: {}
7 | serializedVersion: 2
8 | mipmaps:
9 | mipMapMode: 0
10 | enableMipMap: 1
11 | linearTexture: 0
12 | correctGamma: 0
13 | fadeOut: 0
14 | borderMipMap: 0
15 | mipMapFadeDistanceStart: 1
16 | mipMapFadeDistanceEnd: 3
17 | bumpmap:
18 | convertToNormalMap: 0
19 | externalNormalMap: 0
20 | heightScale: 0.25
21 | normalMapFilter: 0
22 | isReadable: 0
23 | grayScaleToAlpha: 0
24 | generateCubemap: 0
25 | cubemapConvolution: 0
26 | cubemapConvolutionSteps: 7
27 | cubemapConvolutionExponent: 1.5
28 | seamlessCubemap: 0
29 | textureFormat: -1
30 | maxTextureSize: 2048
31 | textureSettings:
32 | filterMode: -1
33 | aniso: -1
34 | mipBias: -1
35 | wrapMode: -1
36 | nPOTScale: 1
37 | lightmap: 0
38 | rGBM: 0
39 | compressionQuality: 50
40 | allowsAlphaSplitting: 0
41 | spriteMode: 0
42 | spriteExtrude: 1
43 | spriteMeshType: 1
44 | alignment: 0
45 | spritePivot: {x: 0.5, y: 0.5}
46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
47 | spritePixelsToUnits: 100
48 | alphaIsTransparency: 0
49 | spriteTessellationDetail: -1
50 | textureType: -1
51 | buildTargetSettings: []
52 | spriteSheet:
53 | serializedVersion: 2
54 | sprites: []
55 | outline: []
56 | spritePackingTag:
57 | userData:
58 | assetBundleName:
59 | assetBundleVariant:
60 |
--------------------------------------------------------------------------------
/Assets/License.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f304f146495c9c34c8edfff896cdaf72
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/License/UnityOctree.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 51f605a23c45c584685d0c696fc6f5d8
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/License/UnityOctree/LICENCE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014, Nition
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/Assets/License/UnityOctree/LICENCE.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: eca63f5432115bf49955c8431cc5852f
3 | timeCreated: 1481513782
4 | licenseType: Pro
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/License/UnityOctree/README.md:
--------------------------------------------------------------------------------
1 | UnityOctree
2 | ===========
3 |
4 | A dynamic octree implementation for Unity written in C#.
5 | Originally written for my game [Scraps](http://www.scrapsgame.com) but intended to be general-purpose.
6 |
7 | There are two octree implementations here:
8 | **BoundsOctree** stores any type of object, with the object boundaries defined as an axis-aligned bounding box. It's a dynamic octree and can also be a loose octree.
9 | **PointOctree** is the same basic implementation, but stores objects as a point in space instead of bounds. This allows some simplification of the code. It's a dynamic octree as well.
10 |
11 | **Octree:** An octree a tree data structure which divides 3D space into smaller partitions (nodes) and places objects into the appropriate nodes. This allows fast access to objects in an area of interest without having to check every object.
12 |
13 | **Dynamic:** The octree grows or shrinks as required when objects are added or removed. It also splits and merges nodes as appropriate. There is no maximum depth. Nodes have a constant (*numObjectsAllowed*) which sets the amount of items allowed in a node before it splits.
14 |
15 | **Loose:** The octree's nodes can be larger than 1/2 their parent's length and width, so they overlap to some extent. This can alleviate the problem of even tiny objects ending up in large nodes if they're near boundaries. A looseness value of 1.0 will make it a "normal" octree.
16 |
17 | **A few functions are implemented:**
18 |
19 | With BoundsOctree, you can pass in bounds and get a true/false answer for if it's colliding with anything (IsColliding), or get a list of everything it's collising with (GetColliding).
20 | With PointOctree, you can cast a ray and get a list of objects that are within x distance of that ray (GetNearby). You may also get a list of objects that are within x distance from a specified origin point.
21 |
22 | It shouldn't be too hard to implement additional functions if needed. For instance, PointOctree could check for points that fall inside a given bounds.
23 |
24 | **Considerations:**
25 |
26 | Tree searches are recursive, so there is technically the potential for a stack overflow on very large trees. The minNodeSize parameter limits node side and hence the depth of the tree, putting a cap on recursion.
27 |
28 | I tried switching to an iterative solution using my own stack, but creating and manipulating the stack made the results generally slower than the simple recursive solution. However, I wouldn't be surprised it someone smarter than me can come up with a faster solution.
29 |
30 | Another note: You may notice when viewing the bounds visualisation that the child nodes' outer edges are all inside the parent nodes. But loose octrees are meant to make the inner nodes bigger... aren't they? The answer is yes, but the parent nodes are *also* bigger, and e.g. ((1.2 * 10) - 10) is bigger than ((1.2 * 5) - 5), so the parent node ends up being bigger overall.
31 |
32 | This seems to be the standard way that loose octrees are done. I did an experiment: I tried making the child node dimensions looseness * the parent's actual size, instead of looseness * the parent's base size before looseness is applied. This seems more intuitively correct to me, but performance seems to be about the same.
33 |
34 | Example Usage
35 | ===========
36 |
37 | **Create An Octree**
38 |
39 | ```C#
40 | // Initial size (metres), initial centre position, minimum node size (metres), looseness
41 | BoundsOctree boundsTree = new BoundsOctree(15, MyContainer.position, 1, 1.25f);
42 | // Initial size (metres), initial centre position, minimum node size (metres)
43 | PointOctree pointTree = new PointOctree(15, MyContainer.position, 1);
44 | ```
45 |
46 | - Here I've used GameObject, but the tree's content can be any type you like (as long as it's all the *same* type
47 | - The initial size should ideally cover an area just encompassing all your objects. If you guess too small, the octree will grow automatically, but it will be eight times the size (double dimensions), which could end up covering a large area unnecessarily. At the same time, the octree will be able to shrink down again if the outlying objects are removed. If you guess an initial size that's too big, it won't be able to shrink down, but that may be the safer option. Don't worry too much: In reality the starting value isn't hugely important for performance.
48 | - The initial position should ideally be in the centre of where your objects are.
49 | - The minimum node size is effectively a depth limit; it limits how many times the tree can divide. If all your objects are e.g. 1m+ wide, you wouldn't want to set it smaller than 1m.
50 | - The best way to choose a looseness value is to try different values (between 1 and maybe 1.5) and check the performance with your particular data. Generally around 1.2 is good.
51 |
52 | **Add And Remove**
53 |
54 | ```C#
55 | boundsTree.Add(myObject, myBounds);
56 | boundsTree.Remove(myObject);
57 |
58 | pointTree.Add(myObject, myVector3);
59 | boundsTree.Remove(myObject);
60 | ```
61 | - The object's type depends on the tree's type.
62 | - The bounds or point determine where it's inserted.
63 |
64 | **Built-in Functions**
65 |
66 | ```C#
67 | bool isColliding = boundsTree.IsColliding(bounds);
68 | ```
69 |
70 | ```C#
71 | List collidingWith = new List();
72 | boundsTree.GetColliding(collidingWith, bounds);
73 | ```
74 | - Where GameObject is the type of the octree
75 |
76 | ```C#
77 | pointTree.GetNearby(myRay, 4);
78 | ```
79 | - Where myRay is a [Ray](http://docs.unity3d.com/Documentation/ScriptReference/Ray.html)
80 | - In this case we're looking for any point within 4m of the closest point on the ray
81 |
82 | ```C#
83 | pointTree.GetNearby(myPos, 4);
84 | ```
85 | - Where myPos is a [Vector3](http://docs.unity3d.com/Documentation/ScriptReference/Vector3.html)
86 |
87 | **Debugging Visuals**
88 |
89 | 
90 |
91 | ```C#
92 | void OnDrawGizmos() {
93 | boundsTree.DrawAllBounds(); // Draw node boundaries
94 | boundsTree.DrawAllObjects(); // Draw object boundaries
95 | boundsTree.DrawCollisionChecks(); // Draw the last *numCollisionsToSave* collision check boundaries
96 |
97 | pointTree.DrawAllBounds(); // Draw node boundaries
98 | pointTree.DrawAllObjects(); // Mark object positions
99 | }
100 | ```
101 | - Must be in Unity's OnDrawGizmos() method in a class that inherits from MonoBehaviour
102 | - Point octrees need the marker.tif file to be in your Unity /Assets/Gizmos subfolder for DrawAllObjects to work
103 |
104 |
105 | **Potential Improvements**
106 |
107 | A significant portion of the octree's time is taken just to traverse through the nodes themselves. There's potential for a performance increase there, maybe by linearising the tree - that is, representing all the nodes as a one-dimensional array lookup.
108 |
109 |
--------------------------------------------------------------------------------
/Assets/License/UnityOctree/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4fc9af6064d57b64781077cf839a35f5
3 | timeCreated: 1481513780
4 | licenseType: Pro
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 01e1b0d2efacb0149b62c3fd3152c2e2
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Black.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Black
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _ALPHAPREMULTIPLY_ON _EMISSION _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: 3000
16 | stringTagMap:
17 | RenderType: Transparent
18 | disabledShaderPasses: []
19 | m_SavedProperties:
20 | serializedVersion: 3
21 | m_TexEnvs:
22 | - _BumpMap:
23 | m_Texture: {fileID: 0}
24 | m_Scale: {x: 1, y: 1}
25 | m_Offset: {x: 0, y: 0}
26 | - _DetailAlbedoMap:
27 | m_Texture: {fileID: 0}
28 | m_Scale: {x: 1, y: 1}
29 | m_Offset: {x: 0, y: 0}
30 | - _DetailMask:
31 | m_Texture: {fileID: 0}
32 | m_Scale: {x: 1, y: 1}
33 | m_Offset: {x: 0, y: 0}
34 | - _DetailNormalMap:
35 | m_Texture: {fileID: 0}
36 | m_Scale: {x: 1, y: 1}
37 | m_Offset: {x: 0, y: 0}
38 | - _EmissionMap:
39 | m_Texture: {fileID: 0}
40 | m_Scale: {x: 1, y: 1}
41 | m_Offset: {x: 0, y: 0}
42 | - _MainTex:
43 | m_Texture: {fileID: 0}
44 | m_Scale: {x: 1, y: 1}
45 | m_Offset: {x: 0, y: 0}
46 | - _MetallicGlossMap:
47 | m_Texture: {fileID: 0}
48 | m_Scale: {x: 1, y: 1}
49 | m_Offset: {x: 0, y: 0}
50 | - _OcclusionMap:
51 | m_Texture: {fileID: 0}
52 | m_Scale: {x: 1, y: 1}
53 | m_Offset: {x: 0, y: 0}
54 | - _ParallaxMap:
55 | m_Texture: {fileID: 0}
56 | m_Scale: {x: 1, y: 1}
57 | m_Offset: {x: 0, y: 0}
58 | m_Floats:
59 | - _BumpScale: 1
60 | - _Cutoff: 0.5
61 | - _DetailNormalMapScale: 1
62 | - _DstBlend: 10
63 | - _GlossMapScale: 0.383
64 | - _Glossiness: 1
65 | - _GlossyReflections: 1
66 | - _Metallic: 1
67 | - _Mode: 3
68 | - _OcclusionStrength: 1
69 | - _Parallax: 0.02
70 | - _SmoothnessTextureChannel: 1
71 | - _SpecularHighlights: 1
72 | - _SrcBlend: 1
73 | - _UVSec: 0
74 | - _ZWrite: 0
75 | m_Colors:
76 | - _Color: {r: 0.09433961, g: 0.06710268, b: 0.030704873, a: 0.007843138}
77 | - _EmissionColor: {r: 0.8796968, g: 0.9696658, b: 1.9093419, a: 1}
78 |
--------------------------------------------------------------------------------
/Assets/Materials/Black.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d6b586e5d1add28469f11f754f0df37f
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Blue.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Blue
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _EMISSION
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 1
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 0.15953684, g: 0, b: 1, a: 1}
76 | - _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
77 |
--------------------------------------------------------------------------------
/Assets/Materials/Blue.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 33970c7b922d139448ee24fd7e7fc0f1
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Bright.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Bright
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _EMISSION _GLOSSYREFLECTIONS_OFF _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
12 | _SPECULARHIGHLIGHTS_OFF
13 | m_LightmapFlags: 2
14 | m_EnableInstancingVariants: 0
15 | m_DoubleSidedGI: 0
16 | m_CustomRenderQueue: -1
17 | stringTagMap: {}
18 | disabledShaderPasses: []
19 | m_SavedProperties:
20 | serializedVersion: 3
21 | m_TexEnvs:
22 | - _BumpMap:
23 | m_Texture: {fileID: 0}
24 | m_Scale: {x: 1, y: 1}
25 | m_Offset: {x: 0, y: 0}
26 | - _DetailAlbedoMap:
27 | m_Texture: {fileID: 0}
28 | m_Scale: {x: 1, y: 1}
29 | m_Offset: {x: 0, y: 0}
30 | - _DetailMask:
31 | m_Texture: {fileID: 0}
32 | m_Scale: {x: 1, y: 1}
33 | m_Offset: {x: 0, y: 0}
34 | - _DetailNormalMap:
35 | m_Texture: {fileID: 0}
36 | m_Scale: {x: 1, y: 1}
37 | m_Offset: {x: 0, y: 0}
38 | - _EmissionMap:
39 | m_Texture: {fileID: 10305, guid: 0000000000000000f000000000000000, type: 0}
40 | m_Scale: {x: 1, y: 1}
41 | m_Offset: {x: 0, y: 0}
42 | - _MainTex:
43 | m_Texture: {fileID: 0}
44 | m_Scale: {x: 1, y: 1}
45 | m_Offset: {x: 0, y: 0}
46 | - _MetallicGlossMap:
47 | m_Texture: {fileID: 0}
48 | m_Scale: {x: 1, y: 1}
49 | m_Offset: {x: 0, y: 0}
50 | - _OcclusionMap:
51 | m_Texture: {fileID: 0}
52 | m_Scale: {x: 1, y: 1}
53 | m_Offset: {x: 0, y: 0}
54 | - _ParallaxMap:
55 | m_Texture: {fileID: 0}
56 | m_Scale: {x: 1, y: 1}
57 | m_Offset: {x: 0, y: 0}
58 | m_Floats:
59 | - _BumpScale: 1
60 | - _Cutoff: 0.5
61 | - _DetailNormalMapScale: 1
62 | - _DstBlend: 0
63 | - _GlossMapScale: 1
64 | - _Glossiness: 0
65 | - _GlossyReflections: 0
66 | - _Metallic: 0
67 | - _Mode: 0
68 | - _OcclusionStrength: 1
69 | - _Parallax: 0.02
70 | - _SmoothnessTextureChannel: 1
71 | - _SpecularHighlights: 0
72 | - _SrcBlend: 1
73 | - _UVSec: 0
74 | - _ZWrite: 1
75 | m_Colors:
76 | - _Color: {r: 1, g: 1, b: 1, a: 1}
77 | - _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
78 |
--------------------------------------------------------------------------------
/Assets/Materials/Bright.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 08f8ce90b7528de41bd41945833c323c
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/ChocBlk.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: ChocBlk
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _ALPHAPREMULTIPLY_ON
12 | m_LightmapFlags: 6
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: 3000
16 | stringTagMap:
17 | RenderType: Transparent
18 | disabledShaderPasses: []
19 | m_SavedProperties:
20 | serializedVersion: 3
21 | m_TexEnvs:
22 | - _BumpMap:
23 | m_Texture: {fileID: 0}
24 | m_Scale: {x: 1, y: 1}
25 | m_Offset: {x: 0, y: 0}
26 | - _DetailAlbedoMap:
27 | m_Texture: {fileID: 0}
28 | m_Scale: {x: 1, y: 1}
29 | m_Offset: {x: 0, y: 0}
30 | - _DetailMask:
31 | m_Texture: {fileID: 0}
32 | m_Scale: {x: 1, y: 1}
33 | m_Offset: {x: 0, y: 0}
34 | - _DetailNormalMap:
35 | m_Texture: {fileID: 0}
36 | m_Scale: {x: 1, y: 1}
37 | m_Offset: {x: 0, y: 0}
38 | - _EmissionMap:
39 | m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
40 | m_Scale: {x: 1, y: 1}
41 | m_Offset: {x: 0, y: 0}
42 | - _MainTex:
43 | m_Texture: {fileID: 0}
44 | m_Scale: {x: 1, y: 1}
45 | m_Offset: {x: 0, y: 0}
46 | - _MetallicGlossMap:
47 | m_Texture: {fileID: 0}
48 | m_Scale: {x: 1, y: 1}
49 | m_Offset: {x: 0, y: 0}
50 | - _OcclusionMap:
51 | m_Texture: {fileID: 0}
52 | m_Scale: {x: 1, y: 1}
53 | m_Offset: {x: 0, y: 0}
54 | - _ParallaxMap:
55 | m_Texture: {fileID: 0}
56 | m_Scale: {x: 1, y: 1}
57 | m_Offset: {x: 0, y: 0}
58 | m_Floats:
59 | - _BumpScale: 1
60 | - _Cutoff: 0.5
61 | - _DetailNormalMapScale: 1
62 | - _DstBlend: 10
63 | - _GlossMapScale: 1
64 | - _Glossiness: 1
65 | - _GlossyReflections: 1
66 | - _Metallic: 0
67 | - _Mode: 3
68 | - _OcclusionStrength: 1
69 | - _Parallax: 0.02
70 | - _SmoothnessTextureChannel: 0
71 | - _SpecularHighlights: 1
72 | - _SrcBlend: 1
73 | - _UVSec: 0
74 | - _ZWrite: 0
75 | m_Colors:
76 | - _Color: {r: 0.09433961, g: 0.06710268, b: 0.030704873, a: 0.007843138}
77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
78 |
--------------------------------------------------------------------------------
/Assets/Materials/ChocBlk.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1d0082690775b4b47b0f4927c9934d20
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Dark Transparent.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Dark Transparent
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _ALPHAPREMULTIPLY_ON _EMISSION
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: 3000
16 | stringTagMap:
17 | RenderType: Transparent
18 | disabledShaderPasses: []
19 | m_SavedProperties:
20 | serializedVersion: 3
21 | m_TexEnvs:
22 | - _BumpMap:
23 | m_Texture: {fileID: 0}
24 | m_Scale: {x: 1, y: 1}
25 | m_Offset: {x: 0, y: 0}
26 | - _DetailAlbedoMap:
27 | m_Texture: {fileID: 0}
28 | m_Scale: {x: 1, y: 1}
29 | m_Offset: {x: 0, y: 0}
30 | - _DetailMask:
31 | m_Texture: {fileID: 0}
32 | m_Scale: {x: 1, y: 1}
33 | m_Offset: {x: 0, y: 0}
34 | - _DetailNormalMap:
35 | m_Texture: {fileID: 0}
36 | m_Scale: {x: 1, y: 1}
37 | m_Offset: {x: 0, y: 0}
38 | - _EmissionMap:
39 | m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
40 | m_Scale: {x: 1, y: 1}
41 | m_Offset: {x: 0, y: 0}
42 | - _MainTex:
43 | m_Texture: {fileID: 0}
44 | m_Scale: {x: 1, y: 1}
45 | m_Offset: {x: 0, y: 0}
46 | - _MetallicGlossMap:
47 | m_Texture: {fileID: 0}
48 | m_Scale: {x: 1, y: 1}
49 | m_Offset: {x: 0, y: 0}
50 | - _OcclusionMap:
51 | m_Texture: {fileID: 0}
52 | m_Scale: {x: 1, y: 1}
53 | m_Offset: {x: 0, y: 0}
54 | - _ParallaxMap:
55 | m_Texture: {fileID: 0}
56 | m_Scale: {x: 1, y: 1}
57 | m_Offset: {x: 0, y: 0}
58 | m_Floats:
59 | - _BumpScale: 1
60 | - _Cutoff: 0.5
61 | - _DetailNormalMapScale: 1
62 | - _DstBlend: 10
63 | - _GlossMapScale: 1
64 | - _Glossiness: 0.5
65 | - _GlossyReflections: 1
66 | - _Metallic: 0
67 | - _Mode: 3
68 | - _OcclusionStrength: 1
69 | - _Parallax: 0.02
70 | - _SmoothnessTextureChannel: 0
71 | - _SpecularHighlights: 1
72 | - _SrcBlend: 1
73 | - _UVSec: 0
74 | - _ZWrite: 0
75 | m_Colors:
76 | - _Color: {r: 0.1981132, g: 0.14671591, b: 0.14671591, a: 0.32156864}
77 | - _EmissionColor: {r: 0.0625, g: 0.0625, b: 0.0625, a: 1}
78 |
--------------------------------------------------------------------------------
/Assets/Materials/Dark Transparent.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 06b149c62298ef147b389f3cdd47d54a
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Light Blue.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Light Blue
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _EMISSION
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 1
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 0, g: 0.8982549, b: 1, a: 1}
76 | - _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
77 |
--------------------------------------------------------------------------------
/Assets/Materials/Light Blue.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 261946f79a335714eae1a475e8e4d69b
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Lime Green.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Lime Green
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _EMISSION
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 10914, guid: 0000000000000000f000000000000000, type: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 1
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 0.16239214, g: 1, b: 0, a: 1}
76 | - _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
77 |
--------------------------------------------------------------------------------
/Assets/Materials/Lime Green.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a83a6eb254d82db4d9a3b42c4727bcc3
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Orange.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Orange
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _EMISSION
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 10900, guid: 0000000000000000f000000000000000, type: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 1
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 1, g: 0.449203, b: 0, a: 1}
76 | - _EmissionColor: {r: 0.2462014, g: 0.2462014, b: 0.2462014, a: 1}
77 |
--------------------------------------------------------------------------------
/Assets/Materials/Orange.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e5f7b92cecf5fc448965070f100e7125
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Pink.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Pink
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _EMISSION
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 1
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 1, g: 0.11372548, b: 0.8656726, a: 1}
76 | - _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
77 |
--------------------------------------------------------------------------------
/Assets/Materials/Pink.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 417e24f513c60dc41bf805d9aa3baa27
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Purple.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Purple
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _EMISSION
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 10900, guid: 0000000000000000f000000000000000, type: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 1
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 0.49497414, g: 0.11372549, b: 1, a: 1}
76 | - _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
77 |
--------------------------------------------------------------------------------
/Assets/Materials/Purple.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0f24ee3757d512847b34accda43131a4
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Materials/Yellow.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_PrefabParentObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Yellow
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords: _EMISSION
12 | m_LightmapFlags: 2
13 | m_EnableInstancingVariants: 1
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 1
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 1, g: 0.974868, b: 0.11372548, a: 1}
76 | - _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
77 |
--------------------------------------------------------------------------------
/Assets/Materials/Yellow.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1b6ed89a57154524ebca90be889fc3cf
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 2100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/OTIJob.cs:
--------------------------------------------------------------------------------
1 | namespace oti.AI
2 | {
3 | using UnityEngine;
4 | using System.Threading;
5 | using System.Collections.Generic;
6 |
7 | public class OctreeThreadParameters
8 | {
9 | public int TotalTrackedObjects;
10 | public List ObjectIDs;
11 | public Dictionary> Coordinates;
12 | public Dictionary DynamicObjects;
13 |
14 | }
15 |
16 | public class OTIJob
17 | {
18 | private bool JobIsDone = false;
19 |
20 | private readonly object JobHandle = new object();
21 |
22 | private Thread JobThread = null;
23 |
24 | public bool IsDone
25 | {
26 | get
27 | {
28 | bool tmp;
29 | lock (JobHandle)
30 | {
31 | tmp = JobIsDone;
32 | }
33 | return tmp;
34 | }
35 | set
36 | {
37 | lock (JobHandle)
38 | {
39 | JobIsDone = value;
40 | }
41 | }
42 | }
43 |
44 | public virtual void StartOctree(OctreeThreadParameters otp)
45 | {
46 | JobThread = new Thread(new ParameterizedThreadStart(runOctree));
47 | JobThread.Start(otp);
48 | }
49 |
50 | public virtual void Abort()
51 | {
52 | JobThread?.Abort();
53 | }
54 |
55 | protected virtual void ThreadOctree(OctreeThreadParameters otp) { }
56 |
57 | protected virtual void OctreeThreadFinished() { }
58 |
59 | public virtual bool UpdateOctree()
60 | {
61 | if (IsDone)
62 | {
63 | OctreeThreadFinished();
64 | return true;
65 | }
66 | return false;
67 | }
68 |
69 | private void runOctree(object otp)
70 | {
71 | ThreadOctree((OctreeThreadParameters)otp);
72 | }
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/Assets/OTIJob.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7450d06bb0e3e2d41a38d34c778cbb88
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/OTIUtilities.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace oti.Utilities
4 | {
5 | public static class OTIUtilities
6 | {
7 | public static string[] _Alphabetic = new string[26] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
8 |
9 | ///
10 | /// Assembles a continuous alphabetic unique string from index i: A (i = 0), ...., AB (i = 27), ....., BC (i = 54), ... AAB etc
11 | ///
12 | public static string _AlphabetAssembler(int i)
13 | {
14 | string s = "";
15 | int wh = -1;
16 |
17 | for (int j = 0; j <= i; j += _Alphabetic.Length)
18 | {
19 | wh += 1;
20 | }
21 |
22 | for (int j = 0; j <= wh; j++)
23 | {
24 | if (j > 0)
25 | {
26 | j = wh + 1;
27 | s += _Alphabetic[i % _Alphabetic.Length];
28 | }
29 | else
30 | {
31 | s += wh >= 1 ? _Alphabetic[wh - 1] : _Alphabetic[i % _Alphabetic.Length];
32 | }
33 | }
34 |
35 | return s;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/Assets/OTIUtilities.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 33649b6b61241b3449e6dfc5325e699f
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/Octree.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ff6c142fc87f9b34fa30da29f2b3a8d7
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Octree/Octree.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 | using System.Threading;
4 |
5 | namespace oti.AI
6 | {
7 | ///
8 | /// OTI AI access point for tracked objects calculations run on auxilliary thread.
9 | ///
10 | public class Octree : OTIJob
11 | {
12 | /*
13 | Using Nition Octree https://github.com/Nition/UnityOctree
14 | See license in Assets/License/UnityOctree
15 | */
16 |
17 | ///
18 | /// The octree. Access should be restricted to this class. Using int to ID GameObjects outside main thread.
19 | ///
20 | public PointOctree PointOctree;
21 |
22 | ///
23 | /// True entire time Octree thread is running
24 | ///
25 | public bool ThreadRunning;
26 |
27 | ///
28 | /// Do not access this cache of object states as it is volatile, instead reference WorldMonitor's copy
29 | ///
30 | public TrackedObjectStates TrackedObjectStates;
31 |
32 | ///
33 | /// Record of every tracked object's current state of conflict and which categories it's in conflict with
34 | ///
35 | public Dictionary> MasterList = new Dictionary>();
36 |
37 | ///
38 | /// Positions of tracked objects.
39 | ///
40 | private Vector3[] updatePositions;
41 |
42 | ///
43 | /// Generate Nition PointOctree
44 | ///
45 | public void Initialize(int initialWorldSize, Vector3 initialPosition, int smallestObjectSize)
46 | {
47 | PointOctree = new PointOctree(initialWorldSize, initialPosition, smallestObjectSize);
48 | }
49 |
50 | ///
51 | /// Call this method to begin the threaded Octree operations.
52 | ///
53 | ///
54 | public void ThreadOctreeInit(OctreeThreadParameters otp, bool restrictToMainThread)
55 | {
56 | if(restrictToMainThread)
57 | {
58 | TrackedObjectStates = evaluateOctree(otp);
59 | return;
60 | }
61 |
62 | ThreadRunning = true;
63 |
64 | IsDone = false;
65 | base.StartOctree(otp);
66 | }
67 |
68 | protected override void ThreadOctree(OctreeThreadParameters otp)
69 | {
70 | TrackedObjectStates = evaluateOctree(otp);
71 | IsDone = true; // TrackedObjectStates are defined - - eliminating race conditions
72 | }
73 |
74 | ///
75 | /// Non essential method used to monitor threading
76 | ///
77 | protected override void OctreeThreadFinished()
78 | {
79 | ThreadRunning = false;
80 | }
81 |
82 | ///
83 | /// Runs current tracked object data through Octree.
84 | ///
85 | private TrackedObjectStates evaluateOctree(OctreeThreadParameters otp)
86 | {
87 | int alloc = WorldMonitor.Instance.AllocationSpace;
88 | updatePositions = new Vector3[alloc]; // otp.ObjectIDs.Count
89 | float[] thresholds = new float[alloc]; // otp.ObjectIDs.Count
90 |
91 | //for (int i = 0; i < otp.ObjectIDs.Count; i++)
92 | foreach (int id in otp.ObjectIDs)
93 | {
94 | KeyValuePair pos;
95 |
96 | if (!otp.Coordinates.TryGetValue(id, out pos))
97 | Debug.LogError("unknown object position request in octree eval");
98 |
99 | thresholds[id] = pos.Key;
100 | updatePositions[id] = pos.Value;
101 |
102 | PointOctree.Remove(id);
103 | PointOctree.Add(id, pos.Value);
104 | }
105 |
106 | List enteringIDs = new List();
107 | List leavingIDs = new List();
108 |
109 | List parentIDLeavers = new List();
110 | List parentIDEnterers = new List();
111 |
112 | int ind = 0;
113 | foreach(int id in otp.ObjectIDs)
114 | {
115 | List validConflicts = new List();
116 | List stayers = new List();
117 |
118 | int[] areaObjects = PointOctree.GetNearby(updatePositions[id], thresholds[id]);
119 |
120 | for (int j = 0; j < areaObjects.Length; j++)
121 | {
122 | string affiliateObj = WorldMonitor.Instance.TrackedObjectAffiliations[id];
123 | string affiliateCompare = WorldMonitor.Instance.TrackedObjectAffiliations[areaObjects[j]];
124 |
125 | /*
126 | * run conflict validity checks: if not the same object && not an object of the same class type && is a new conflict
127 | */
128 |
129 | if (areaObjects[j] != id && !MasterList[id].Contains(areaObjects[j]) && string.Compare(affiliateObj, affiliateCompare) != 0)
130 | {
131 | if (!parentIDEnterers.Contains(id))
132 | parentIDEnterers.Add(id);
133 |
134 | MasterList[id].Add(areaObjects[j]); // add conflicting object to master list of current conflicts
135 | validConflicts.Add(areaObjects[j]); // *new* conflicts
136 | stayers.Add(areaObjects[j]); // use to look for conflicts that have ended
137 | }
138 | else if (MasterList[id].Contains(areaObjects[j]))
139 | {
140 | stayers.Add(areaObjects[j]); // this is an object staying in conflict
141 | }
142 | }
143 |
144 | bool leaverDetected = false;
145 | List leavers = new List();
146 |
147 | foreach (int _id in MasterList[id]) // look at master list's record of conflicts for this parent ID - if it isn't in stayers, it has left the conflict area or been destroyed
148 | {
149 | if (!stayers.Contains(_id))
150 | {
151 | leaverDetected = true;
152 | leavers.Add(_id);
153 | }
154 |
155 | switch (WorldMonitor.Instance.ConflictEndMode)
156 | {
157 | case ConflictEndMode.OnAllConflictsEnded:
158 | if (leavers.Count == MasterList[id].Count)
159 | parentIDLeavers.Add(id);
160 | break;
161 | case ConflictEndMode.OnIndividualConflictEnded:
162 | if (leaverDetected && !parentIDEnterers.Contains(id) && !parentIDLeavers.Contains(id))
163 | parentIDLeavers.Add(id);
164 | break;
165 | }
166 | }
167 |
168 | foreach (int leaver in leavers)
169 | MasterList[id].Remove(leaver);
170 |
171 | int numValid = leavers.ToArray().Length;
172 |
173 | if (numValid > 0)
174 | leavingIDs.Add(leavers.ToArray());
175 |
176 | numValid = validConflicts.ToArray().Length;
177 |
178 | if (numValid > 0)
179 | enteringIDs.Add(validConflicts.ToArray());
180 |
181 | ind++;
182 | }
183 |
184 | return new TrackedObjectStates
185 | {
186 | ParentIDEnterers = parentIDEnterers.ToArray(), // parent IDs of new or increased conflict states
187 | ParentIDLeavers = parentIDLeavers.ToArray(), // parent IDs of expired or reduced conflict states
188 | LeavingIDs = leavingIDs, // child IDs - ended conflict(s)
189 | EnteringIDs = enteringIDs, // child IDs - the conflict(s)
190 | PriorConflictingIDs = parentIDLeavers // parent IDs that need informed all conflicts have ceased
191 | };
192 | }
193 | }
194 |
195 | ///
196 | /// A reference of states for tracked objects
197 | ///
198 | public class TrackedObjectStates
199 | {
200 | public int[] ParentIDEnterers;
201 | public int[] ParentIDLeavers;
202 | public List EnteringIDs;
203 | public List LeavingIDs;
204 | public List PriorConflictingIDs;
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/Assets/Octree/Octree.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: cf02a59650f4b0c48934a4837c10d202
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/Scenes.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4f704ae4b4f98ae41a0bce26658850c1
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Scenes/Example Scenes.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b2f565eb0b69fff49bf7e5753a256c95
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Scenes/Example Scenes/ExampleNavigator.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace oti.AI
4 | {
5 | ///
6 | /// Moves tracked objects in Dynamic Objects Tracking example scene
7 | ///
8 | public class ExampleNavigator : MonoBehaviour
9 | {
10 | ///
11 | /// Setting false will allow user to investigate collision reporting on their own accord
12 | ///
13 | public bool MoveAuto;
14 |
15 | ///
16 | /// Speed of translation
17 | ///
18 | public float Speed = 5;
19 |
20 | ///
21 | /// Max speed an object can reach after collision.
22 | ///
23 | public float MaxSpeed = 20;
24 |
25 | ///
26 | /// represents length of size of box used for navigation
27 | ///
28 | private float boundingBoxScale = 50;
29 |
30 | ///
31 | /// direction of travel
32 | ///
33 | private Vector3 direction = Vector3.forward;
34 |
35 | ///
36 | /// Corrals objects that can leave bounds in Update
37 | ///
38 | private bool escapedBounds;
39 |
40 | void Start()
41 | {
42 | if (!MoveAuto)
43 | {
44 | Speed = 0;
45 | return;
46 | }
47 |
48 | direction = new Vector3(Random.Range(-1, 1), 0, Random.Range(-1, 1));
49 |
50 | // ensure all objects move with some velocity >> 0
51 | float xMin = Mathf.Max(Mathf.Abs(direction.x), 0.5f) * Mathf.Sign(direction.x);
52 | float zMin = Mathf.Max(Mathf.Abs(direction.z), 0.5f) * Mathf.Sign(direction.z);
53 |
54 | direction = new Vector3(xMin, 0, zMin);
55 | }
56 |
57 | ///
58 | /// Limit gizmos to one component
59 | ///
60 | public static bool _GizmosDrawn;
61 |
62 | ///
63 | /// Method called from subscriber in Tracker
64 | ///
65 | public void ObjectConflict(Vector3 positionOfInitiator)
66 | {
67 | float fr = Random.Range(-0.01f, 0.01f);
68 | //do something with the information -- note that object affiliation and all conflicting objects and types are available in the event
69 | direction = Vector3.Cross(direction + new Vector3(fr,fr,fr), positionOfInitiator - transform.position).normalized; // jump into 3 dimensions
70 | }
71 |
72 | void Update()
73 | {
74 | if (!MoveAuto)
75 | return;
76 |
77 | bool xCrossed = Mathf.Abs(transform.position.x) > boundingBoxScale;
78 | bool zCrossed = Mathf.Abs(transform.position.z) > boundingBoxScale;
79 | bool yCrossed = Mathf.Abs(transform.position.y) > boundingBoxScale;
80 |
81 | if (escapedBounds && (xCrossed || zCrossed || yCrossed)) //object has been outside of bounds for more than one frame so force it back
82 | {
83 | float signX = Mathf.Sign(transform.position.x);
84 | float signY = Mathf.Sign(transform.position.z);
85 | float signZ = Mathf.Sign(transform.position.z);
86 |
87 | transform.position = xCrossed ? new Vector3(signX * boundingBoxScale * 0.9975f, transform.position.y, transform.position.z) : transform.position;
88 | transform.position = yCrossed ? new Vector3(transform.position.x, signY * boundingBoxScale * 0.9975f, transform.position.z) : transform.position;
89 | transform.position = zCrossed ? new Vector3(transform.position.x, transform.position.y, signZ * boundingBoxScale * 0.9975f) : transform.position;
90 |
91 | escapedBounds = false;
92 | }
93 | else
94 | {
95 | escapedBounds = xCrossed || zCrossed || yCrossed;
96 | }
97 |
98 | direction = xCrossed ? new Vector3(-direction.x, direction.y, direction.z) : direction;
99 | direction = zCrossed ? new Vector3(direction.x, direction.y, -direction.z) : direction;
100 | direction = yCrossed ? new Vector3(direction.x, -direction.y, direction.z) : direction;
101 |
102 |
103 | transform.Translate(Speed * direction * Time.deltaTime, Space.World);
104 |
105 | if (Speed == MaxSpeed)
106 | Speed = 5/2;
107 | }
108 | }
109 | }
--------------------------------------------------------------------------------
/Assets/Scenes/Example Scenes/ExampleNavigator.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3bb0f3934e618a24aad8bc1951a07beb
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/Scenes/Example Scenes/SmallTrackingExample.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b69eed32be95be74aa55bd3f574bc6c4
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Assets/Scenes/Example Scenes/Tracker.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | namespace oti.AI
4 | {
5 | ///
6 | /// Class developed to show example usage of Dynamic Object Tracking
7 | ///
8 | public class Tracker : WorldMonitors
9 | {
10 | /*
11 | The purpose of Tracker.cs is to demonstrate usage of WorldMonitors and Worldmonitor classes.
12 | Your tracking agent will need to subscribe to the ObjectConflictHandler delegate in WorldMonitors
13 | like this:
14 | GetComponent().ConflictEnterers += yourFunction;
15 |
16 |
17 | Events in the ObjectConflictHandler:
18 | *** the optional arguments must be included by every method subscribing to this delegate
19 |
20 | ConflictEnterers: emitted every time a new tracked object enters a parent object's tracked area
21 | Arguments(GameObject TrackedObject, GameObject[] ConflictingObjects, string[] ConflictingTypes)
22 | TrackedObject: the object who's threshold has been penetrated
23 | ConflictingObjects: an array of objects that have entered the tracked object's space
24 | ConflictingTypes: an array of the object types ("A", "B", "C" etc) at matching index locations to ConflictingObjects[]
25 |
26 | ConflictLeavers:
27 | Arguments(GameObject TrackedObject, GameObject[] ConflictingObjects, string[] ConflictingTypes)
28 | TrackedObject: the object who's threshold has been partially or entirely vacated
29 | ConflictingObjects: an array of objects that have vacated the tracked object's space
30 | ConflictingTypes: an array of the object types ("A", "B", "C" etc) at matching index locations to ConflictingObjects[]
31 |
32 | ConflictEnd:
33 | Arguments(GameObject TrackedObject, GameObject[] ConflictingObjects, string[] ConflictingTypes)
34 | TrackedObject: the object who's threshold has been entirely vacated
35 | ConflictingObjects & ConflictingTypes are not passed into this method, but are still required by all subscribers.
36 | */
37 |
38 | // Demonstration of event subscription
39 | void Start()
40 | {
41 | sColor = Color.blue;
42 | eColor = Color.red;
43 |
44 | if (GetComponent())
45 | {
46 | WorldMonitors = GetComponent();
47 |
48 | //subscribe to delegate for tracked object information
49 | WorldMonitors.ConflictEnterers += entererListener;
50 | WorldMonitors.ConflictLeavers += leaverListener;
51 | WorldMonitors.ConflictEnd += endListener;
52 |
53 | if (Demo)
54 | StartCoroutine(demo());
55 |
56 | return;
57 | }
58 |
59 | Debug.LogWarning("Make sure the agent has a WorldMonitors component attached to it.");
60 | }
61 |
62 | ///
63 | /// Unsubscribe all Trackers that are destroyed
64 | ///
65 | private void OnDestroy()
66 | {
67 | WorldMonitors.ConflictEnterers -= entererListener;
68 | WorldMonitors.ConflictLeavers -= leaverListener;
69 | WorldMonitors.ConflictEnd -= endListener;
70 | }
71 |
72 | ///
73 | /// Cached ref to WorldMonitors class
74 | ///
75 | [HideInInspector]
76 | public WorldMonitors WorldMonitors;
77 |
78 | ///
79 | /// Prints conflicting object(s) and type
80 | ///
81 | [Tooltip("Shows tracking system interactions.")]
82 | public bool PrintConflictsToConsole;
83 |
84 | ///
85 | /// Can demonstrate how to add tracked objects at runtime
86 | ///
87 | [Tooltip("Uses a tracking system event to demonstrate how to add objects into tracking system.")]
88 | public bool InsertNewObjectOnEnter;
89 |
90 | ///
91 | /// This object will be inserted into tracking system if InsertNewObjectOnEnter is selected
92 | ///
93 | [Tooltip("If Insert New Object On Enter is true, this will be inserted at the origin on object entrance")]
94 | public GameObject ExampleInsertionObject;
95 |
96 | ///
97 | /// Will destroy objects that enter another's threshold
98 | ///
99 | [Tooltip("Uses a tracking system event to demonstrate how to remove objects from tracking system.")]
100 | public bool DestroyConflictingObjects;
101 |
102 | ///
103 | /// Runs an example method in example navigator class.
104 | ///
105 | [Tooltip("Uses a tracking system event to run a method for pure demo purposes You cannot destroy objects if using this method.")]
106 | public bool CrossProductCollisions;
107 |
108 | ///
109 | /// Triggers a coroutine to wait and change parameters for visual effects
110 | ///
111 | public bool Demo;
112 |
113 | ///
114 | /// Starting interpolation color value for added objects
115 | ///
116 | static Color sColor;
117 |
118 | ///
119 | /// Ending interpolation color value for added objects
120 | ///
121 | static Color eColor;
122 |
123 | ///
124 | /// This method shows how to handle objects raising a conflict with a TrackedObject
125 | ///
126 | private void entererListener(GameObject TrackedObject, GameObject[] ConflictingObjects, string[] ConflictingTypes)
127 | {
128 | if (PrintConflictsToConsole)
129 | Debug.Log("Conflict has STARTED for (" + gameObject.name + ") " + TrackedObject + " with:");
130 |
131 | for (int i = 0; i < ConflictingObjects.Length; i++)
132 | {
133 | if (PrintConflictsToConsole)
134 | Debug.Log(" -- (" + gameObject.name + ") " + ConflictingObjects[i] + " of type: " + ConflictingTypes[i]);
135 |
136 | if (InsertNewObjectOnEnter && WorldMonitor.Instance.FreeSpace)
137 | {
138 | GameObject go = Instantiate(ExampleInsertionObject, Vector3.zero, Quaternion.identity);
139 | go.name = "NewGameObject_" + WorldMonitor.Instance.AllocationSpace;
140 | go.AddComponent();
141 | go.SetActive(true);
142 | go.GetComponent().material.color = Color.Lerp(sColor, eColor, Mathf.Sin(0.5f * Time.time));
143 | go.transform.position = new Vector3(Random.Range(-6, 6), Random.Range(-6, 6), Random.Range(-6, 6)); // [-6,6] ensures eventual collision with center object.
144 | WorldMonitor.Instance.InsertNewTrackedObject(go, WorldMonitors, "YouCanMakeThisAnything", 2);
145 | }
146 |
147 | if (DestroyConflictingObjects)
148 | {
149 | WorldMonitor.Instance.RemoveTrackedObject(ConflictingObjects[i]);
150 | Destroy(ConflictingObjects[i]);
151 | }
152 |
153 | if (CrossProductCollisions && !DestroyConflictingObjects)
154 | {
155 | if(ConflictingObjects[i])
156 | ConflictingObjects[i].GetComponent().ObjectConflict(TrackedObject.transform.position);
157 | }
158 | }
159 | }
160 |
161 | ///
162 | /// This method shows how to handle objects leaving the conflict area of a Tracked Object
163 | ///
164 | /// The user can choose to only subscribe to events raised when all conflicts have ended, or none at all.
165 | private void leaverListener(GameObject TrackedObject, GameObject[] ConflictingObjects, string[] ConflictingTypes)
166 | {
167 | if (PrintConflictsToConsole)
168 | Debug.Log("Conflict has ENDED for (" + gameObject.name + ") " + TrackedObject + " with:");
169 |
170 | for (int i = 0; i < ConflictingObjects.Length; i++)
171 | {
172 | if (PrintConflictsToConsole)
173 | Debug.Log(" -- (" + gameObject.name + ") " + ConflictingObjects[i] + " of type: " + ConflictingTypes[i]);
174 | }
175 | }
176 |
177 | ///
178 | /// This method shows how to handle events when a conflict ceases entirely.
179 | ///
180 | /// The user can choose to only subscribe to events raised when any oject leaves a Tracked Object's conflict area, or none at all.
181 | private void endListener(GameObject TrackedObject, GameObject[] ConflictingObjects, string[] ConflictingTypes)
182 | {
183 | if (PrintConflictsToConsole)
184 | Debug.Log("GameObject " + TrackedObject + "'s conflict(s) have ended and logged for " + gameObject.name);
185 | }
186 |
187 | ///
188 | /// Solely to look interesting :)
189 | ///
190 | private IEnumerator demo()
191 | {
192 | float t = Time.time;
193 | yield return new WaitWhile(() => Time.time - t < 10);
194 |
195 | sColor = Color.red;
196 | eColor = Color.yellow;
197 |
198 | CrossProductCollisions = true;
199 | }
200 | }
201 | }
--------------------------------------------------------------------------------
/Assets/Scenes/Example Scenes/Tracker.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 83bed73bc2468f7419add006d59d22e4
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/Scenes/Example Scenes/TrackingExample.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 99c9720ab356a0642a771bea13969a05
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Assets/TrackedObjectTriggers.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | namespace oti.AI
6 | {
7 | public class TrackedObjectTriggers : MonoBehaviour
8 | {
9 | ///
10 | /// How many agents are tracking this object
11 | ///
12 | public int Owners;
13 |
14 | ///
15 | /// The uID for this tracked object.
16 | ///
17 | public int TrackedObjectID;
18 |
19 | ///
20 | /// The agents following this tracked object
21 | ///
22 | public List wms = new List();
23 |
24 | ///
25 | /// Record of how many conflicts occurring
26 | ///
27 | private int insiders = 0;
28 |
29 | ///
30 | /// Agents who find this object in a field will add themselves as owners here
31 | ///
32 | public void AcceptOwner(WorldMonitors wm)
33 | {
34 | Owners++; // quicker than wms.Count
35 | wms.Add(wm);
36 | }
37 |
38 | ///
39 | /// Agents notify objects when they are destroyed
40 | ///
41 | public void LoseOwner(WorldMonitors wm)
42 | {
43 | Owners--;
44 | wms.Remove(wm);
45 | }
46 |
47 | ///
48 | /// Set up unity components to user config
49 | ///
50 | public void Initialize()
51 | {
52 | SphereCollider collider;
53 |
54 | if (!GetComponent())
55 | gameObject.AddComponent();
56 |
57 | collider = GetComponent();
58 | collider.isTrigger = true;
59 | collider.enabled = true;
60 |
61 | if(!GetComponent())
62 | gameObject.AddComponent();
63 |
64 | GetComponent().useGravity = WorldMonitor.Instance.TrackedObjectsUseGravity;
65 |
66 | TrackedObjectID = WorldMonitor.Instance.GameObjectIDReference[gameObject];
67 |
68 | TrackedObjectData todata;
69 | WorldMonitor.Instance.TrackedObjectDataRef.TryGetValue(TrackedObjectID, out todata);
70 |
71 | collider.radius = WorldMonitor.Instance.TriggersMimicOctree ? 0.75f * todata.Threshold : todata.Threshold; // allow triggers to mimic point octree
72 | }
73 |
74 | // MonoBehaviour method
75 | private void OnTriggerEnter(Collider other)
76 | {
77 | if (other.gameObject)
78 | {
79 | GameObject[] goPass = new GameObject[1];
80 | goPass[0] = other.gameObject;
81 |
82 | int childID;
83 | int parentID;
84 |
85 | if (WorldMonitor.Instance.GameObjectIDReference.TryGetValue(goPass[0], out childID)) // not all gameObjects may be in tracking system
86 | {
87 | if (!WorldMonitor.Instance.GameObjectIDReference.TryGetValue(gameObject, out parentID))
88 | Debug.LogError("TrackedObjectTriggers cannot be used on objects not located in a field of a WorldMonitors instance");
89 |
90 | insiders++;
91 |
92 | string[] sPass = new string[1];
93 | sPass[0] = WorldMonitor.Instance.TrackedObjectAffiliations[childID];
94 |
95 | if (string.Compare(WorldMonitor.Instance.TrackedObjectAffiliations[TrackedObjectID], sPass[0]) != 0)
96 | {
97 | foreach (WorldMonitors wm in wms)
98 | wm.RaiseConflictEnterers(gameObject, goPass, sPass);
99 | }
100 | }
101 | }
102 | }
103 |
104 | // MonoBehaviour method
105 | private void OnTriggerExit(Collider other)
106 | {
107 | ConflictEndMode cem = WorldMonitor.Instance.ConflictEndMode;
108 |
109 | if (cem == ConflictEndMode.NoConflictEndEvents)
110 | return;
111 |
112 | if (other.gameObject)
113 | {
114 | GameObject[] goPass = new GameObject[1];
115 | goPass[0] = other.gameObject;
116 |
117 | int childID;
118 | int parentID;
119 |
120 | if (WorldMonitor.Instance.GameObjectIDReference.TryGetValue(goPass[0], out childID)) // not all gameObjects may be in tracking system
121 | {
122 | if (!WorldMonitor.Instance.GameObjectIDReference.TryGetValue(gameObject, out parentID))
123 | Debug.LogError("TrackedObjectTriggers cannot be used on objects not located in a field of a WorldMonitors instance");
124 |
125 | insiders--;
126 |
127 | string[] sPass = new string[1];
128 | sPass[0] = WorldMonitor.Instance.TrackedObjectAffiliations[childID];
129 |
130 | if (string.Compare(WorldMonitor.Instance.TrackedObjectAffiliations[TrackedObjectID], sPass[0]) != 0)
131 | {
132 | if (cem == ConflictEndMode.OnAllConflictsEnded && insiders > 0)
133 | return;
134 | // else: both OnAll and OnIndividual modes will be handled the same from here out
135 |
136 | foreach (WorldMonitors wm in wms)
137 | wm.RaiseConflictLeavers(gameObject, goPass, sPass);
138 | }
139 | }
140 | }
141 | }
142 | }
143 | }
--------------------------------------------------------------------------------
/Assets/TrackedObjectTriggers.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 27bec2c7144b9f443b81cab3adbf7308
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/UnityOctree.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5c417392861d01d40b9df69477b9d75a
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/UnityOctree/BoundsOctree.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | // A Dynamic, Loose Octree for storing any objects that can be described with AABB bounds
5 | // See also: PointOctree, where objects are stored as single points and some code can be simplified
6 | // Octree: An octree is a tree data structure which divides 3D space into smaller partitions (nodes)
7 | // and places objects into the appropriate nodes. This allows fast access to objects
8 | // in an area of interest without having to check every object.
9 | // Dynamic: The octree grows or shrinks as required when objects as added or removed
10 | // It also splits and merges nodes as appropriate. There is no maximum depth.
11 | // Nodes have a constant - numObjectsAllowed - which sets the amount of items allowed in a node before it splits.
12 | // Loose: The octree's nodes can be larger than 1/2 their parent's length and width, so they overlap to some extent.
13 | // This can alleviate the problem of even tiny objects ending up in large nodes if they're near boundaries.
14 | // A looseness value of 1.0 will make it a "normal" octree.
15 | // T: The content of the octree can be anything, since the bounds data is supplied separately.
16 |
17 | // Originally written for my game Scraps (http://www.scrapsgame.com) but intended to be general-purpose.
18 | // Copyright 2014 Nition, BSD licence (see LICENCE file). www.momentstudio.co.nz
19 | // Unity-based, but could be adapted to work in pure C#
20 |
21 | // Note: For loops are often used here since in some cases (e.g. the IsColliding method)
22 | // they actually give much better performance than using Foreach, even in the compiled build.
23 | // Using a LINQ expression is worse again than Foreach.
24 | public class BoundsOctree {
25 | // The total amount of objects currently in the tree
26 | public int Count { get; private set; }
27 |
28 | // Root node of the octree
29 | BoundsOctreeNode rootNode;
30 |
31 | // Should be a value between 1 and 2. A multiplier for the base size of a node.
32 | // 1.0 is a "normal" octree, while values > 1 have overlap
33 | readonly float looseness;
34 |
35 | // Size that the octree was on creation
36 | readonly float initialSize;
37 |
38 | // Minimum side length that a node can be - essentially an alternative to having a max depth
39 | readonly float minSize;
40 | // For collision visualisation. Automatically removed in builds.
41 | #if UNITY_EDITOR
42 | const int numCollisionsToSave = 4;
43 | readonly Queue lastBoundsCollisionChecks = new Queue();
44 | readonly Queue lastRayCollisionChecks = new Queue();
45 | #endif
46 |
47 | ///
48 | /// Constructor for the bounds octree.
49 | ///
50 | /// Size of the sides of the initial node, in metres. The octree will never shrink smaller than this.
51 | /// Position of the centre of the initial node.
52 | /// Nodes will stop splitting if the new nodes would be smaller than this (metres).
53 | /// Clamped between 1 and 2. Values > 1 let nodes overlap.
54 | public BoundsOctree(float initialWorldSize, Vector3 initialWorldPos, float minNodeSize, float loosenessVal) {
55 | if (minNodeSize > initialWorldSize) {
56 | Debug.LogWarning("Minimum node size must be at least as big as the initial world size. Was: " + minNodeSize + " Adjusted to: " + initialWorldSize);
57 | minNodeSize = initialWorldSize;
58 | }
59 | Count = 0;
60 | initialSize = initialWorldSize;
61 | minSize = minNodeSize;
62 | looseness = Mathf.Clamp(loosenessVal, 1.0f, 2.0f);
63 | rootNode = new BoundsOctreeNode(initialSize, minSize, looseness, initialWorldPos);
64 | }
65 |
66 | // #### PUBLIC METHODS ####
67 |
68 | ///
69 | /// Add an object.
70 | ///
71 | /// Object to add.
72 | /// 3D bounding box around the object.
73 | public void Add(T obj, Bounds objBounds) {
74 | // Add object or expand the octree until it can be added
75 | int count = 0; // Safety check against infinite/excessive growth
76 | while (!rootNode.Add(obj, objBounds)) {
77 | Grow(objBounds.center - rootNode.Center);
78 | if (++count > 20) {
79 | Debug.LogError("Aborted Add operation as it seemed to be going on forever (" + (count - 1) + ") attempts at growing the octree.");
80 | return;
81 | }
82 | }
83 | Count++;
84 | }
85 |
86 | ///
87 | /// Remove an object. Makes the assumption that the object only exists once in the tree.
88 | ///
89 | /// Object to remove.
90 | /// True if the object was removed successfully.
91 | public bool Remove(T obj) {
92 | bool removed = rootNode.Remove(obj);
93 |
94 | // See if we can shrink the octree down now that we've removed the item
95 | if (removed) {
96 | Count--;
97 | Shrink();
98 | }
99 |
100 | return removed;
101 | }
102 |
103 | ///
104 | /// Removes the specified object at the given position. Makes the assumption that the object only exists once in the tree.
105 | ///
106 | /// Object to remove.
107 | /// 3D bounding box around the object.
108 | /// True if the object was removed successfully.
109 | public bool Remove(T obj, Bounds objBounds) {
110 | bool removed = rootNode.Remove(obj, objBounds);
111 |
112 | // See if we can shrink the octree down now that we've removed the item
113 | if (removed) {
114 | Count--;
115 | Shrink();
116 | }
117 |
118 | return removed;
119 | }
120 |
121 | ///
122 | /// Check if the specified bounds intersect with anything in the tree. See also: GetColliding.
123 | ///
124 | /// bounds to check.
125 | /// True if there was a collision.
126 | public bool IsColliding(Bounds checkBounds) {
127 | //#if UNITY_EDITOR
128 | // For debugging
129 | //AddCollisionCheck(checkBounds);
130 | //#endif
131 | return rootNode.IsColliding(ref checkBounds);
132 | }
133 |
134 | ///
135 | /// Check if the specified ray intersects with anything in the tree. See also: GetColliding.
136 | ///
137 | /// ray to check.
138 | /// distance to check.
139 | /// True if there was a collision.
140 | public bool IsColliding(Ray checkRay, float maxDistance) {
141 | //#if UNITY_EDITOR
142 | // For debugging
143 | //AddCollisionCheck(checkRay);
144 | //#endif
145 | return rootNode.IsColliding(ref checkRay, maxDistance);
146 | }
147 |
148 | ///
149 | /// Returns an array of objects that intersect with the specified bounds, if any. Otherwise returns an empty array. See also: IsColliding.
150 | ///
151 | /// list to store intersections.
152 | /// bounds to check.
153 | /// Objects that intersect with the specified bounds.
154 | public void GetColliding(List collidingWith, Bounds checkBounds) {
155 | //#if UNITY_EDITOR
156 | // For debugging
157 | //AddCollisionCheck(checkBounds);
158 | //#endif
159 | rootNode.GetColliding(ref checkBounds, collidingWith);
160 | }
161 |
162 | ///
163 | /// Returns an array of objects that intersect with the specified ray, if any. Otherwise returns an empty array. See also: IsColliding.
164 | ///
165 | /// list to store intersections.
166 | /// ray to check.
167 | /// distance to check.
168 | /// Objects that intersect with the specified ray.
169 | public void GetColliding(List collidingWith, Ray checkRay, float maxDistance = float.PositiveInfinity) {
170 | //#if UNITY_EDITOR
171 | // For debugging
172 | //AddCollisionCheck(checkRay);
173 | //#endif
174 | rootNode.GetColliding(ref checkRay, collidingWith, maxDistance);
175 | }
176 |
177 | public List GetWithinFrustum(Camera cam) {
178 | var planes = GeometryUtility.CalculateFrustumPlanes(cam);
179 |
180 | var list = new List();
181 | rootNode.GetWithinFrustum(planes, list);
182 | return list;
183 | }
184 |
185 | public Bounds GetMaxBounds() {
186 | return rootNode.GetBounds();
187 | }
188 |
189 | ///
190 | /// Draws node boundaries visually for debugging.
191 | /// Must be called from OnDrawGizmos externally. See also: DrawAllObjects.
192 | ///
193 | public void DrawAllBounds() {
194 | rootNode.DrawAllBounds();
195 | }
196 |
197 | ///
198 | /// Draws the bounds of all objects in the tree visually for debugging.
199 | /// Must be called from OnDrawGizmos externally. See also: DrawAllBounds.
200 | ///
201 | public void DrawAllObjects() {
202 | rootNode.DrawAllObjects();
203 | }
204 |
205 | // Intended for debugging. Must be called from OnDrawGizmos externally
206 | // See also DrawAllBounds and DrawAllObjects
207 | ///
208 | /// Visualises collision checks from IsColliding and GetColliding.
209 | /// Collision visualisation code is automatically removed from builds so that collision checks aren't slowed down.
210 | ///
211 | #if UNITY_EDITOR
212 | public void DrawCollisionChecks() {
213 | int count = 0;
214 | foreach (Bounds collisionCheck in lastBoundsCollisionChecks) {
215 | Gizmos.color = new Color(1.0f, 1.0f - ((float)count / numCollisionsToSave), 1.0f);
216 | Gizmos.DrawCube(collisionCheck.center, collisionCheck.size);
217 | count++;
218 | }
219 |
220 | foreach (Ray collisionCheck in lastRayCollisionChecks) {
221 | Gizmos.color = new Color(1.0f, 1.0f - ((float)count / numCollisionsToSave), 1.0f);
222 | Gizmos.DrawRay(collisionCheck.origin, collisionCheck.direction);
223 | count++;
224 | }
225 | Gizmos.color = Color.white;
226 | }
227 | #endif
228 |
229 | // #### PRIVATE METHODS ####
230 |
231 | ///
232 | /// Used for visualising collision checks with DrawCollisionChecks.
233 | /// Automatically removed from builds so that collision checks aren't slowed down.
234 | ///
235 | /// bounds that were passed in to check for collisions.
236 | #if UNITY_EDITOR
237 | void AddCollisionCheck(Bounds checkBounds) {
238 | lastBoundsCollisionChecks.Enqueue(checkBounds);
239 | if (lastBoundsCollisionChecks.Count > numCollisionsToSave) {
240 | lastBoundsCollisionChecks.Dequeue();
241 | }
242 | }
243 | #endif
244 |
245 | ///
246 | /// Used for visualising collision checks with DrawCollisionChecks.
247 | /// Automatically removed from builds so that collision checks aren't slowed down.
248 | ///
249 | /// ray that was passed in to check for collisions.
250 | #if UNITY_EDITOR
251 | void AddCollisionCheck(Ray checkRay) {
252 | lastRayCollisionChecks.Enqueue(checkRay);
253 | if (lastRayCollisionChecks.Count > numCollisionsToSave) {
254 | lastRayCollisionChecks.Dequeue();
255 | }
256 | }
257 | #endif
258 |
259 | ///
260 | /// Grow the octree to fit in all objects.
261 | ///
262 | /// Direction to grow.
263 | void Grow(Vector3 direction) {
264 | int xDirection = direction.x >= 0 ? 1 : -1;
265 | int yDirection = direction.y >= 0 ? 1 : -1;
266 | int zDirection = direction.z >= 0 ? 1 : -1;
267 | BoundsOctreeNode oldRoot = rootNode;
268 | float half = rootNode.BaseLength / 2;
269 | float newLength = rootNode.BaseLength * 2;
270 | Vector3 newCenter = rootNode.Center + new Vector3(xDirection * half, yDirection * half, zDirection * half);
271 |
272 | // Create a new, bigger octree root node
273 | rootNode = new BoundsOctreeNode(newLength, minSize, looseness, newCenter);
274 |
275 | if (oldRoot.HasAnyObjects()) {
276 | // Create 7 new octree children to go with the old root as children of the new root
277 | int rootPos = rootNode.BestFitChild(oldRoot.Center);
278 | BoundsOctreeNode[] children = new BoundsOctreeNode[8];
279 | for (int i = 0; i < 8; i++) {
280 | if (i == rootPos) {
281 | children[i] = oldRoot;
282 | }
283 | else {
284 | xDirection = i % 2 == 0 ? -1 : 1;
285 | yDirection = i > 3 ? -1 : 1;
286 | zDirection = (i < 2 || (i > 3 && i < 6)) ? -1 : 1;
287 | children[i] = new BoundsOctreeNode(oldRoot.BaseLength, minSize, looseness, newCenter + new Vector3(xDirection * half, yDirection * half, zDirection * half));
288 | }
289 | }
290 |
291 | // Attach the new children to the new root node
292 | rootNode.SetChildren(children);
293 | }
294 | }
295 |
296 | ///
297 | /// Shrink the octree if possible, else leave it the same.
298 | ///
299 | void Shrink() {
300 | rootNode = rootNode.ShrinkIfPossible(initialSize);
301 | }
302 | }
303 |
--------------------------------------------------------------------------------
/Assets/UnityOctree/BoundsOctree.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: acb06913ab8ee284b8b436ed59cce729
3 | timeCreated: 1481513782
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/UnityOctree/BoundsOctreeNode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 098c3a5fece947a4ba701dc1f6723c21
3 | timeCreated: 1481513782
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/UnityOctree/PointOctree.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | // A Dynamic Octree for storing any objects that can be described as a single point
5 | // See also: BoundsOctree, where objects are described by AABB bounds
6 | // Octree: An octree is a tree data structure which divides 3D space into smaller partitions (nodes)
7 | // and places objects into the appropriate nodes. This allows fast access to objects
8 | // in an area of interest without having to check every object.
9 | // Dynamic: The octree grows or shrinks as required when objects as added or removed
10 | // It also splits and merges nodes as appropriate. There is no maximum depth.
11 | // Nodes have a constant - numObjectsAllowed - which sets the amount of items allowed in a node before it splits.
12 | // T: The content of the octree can be anything, since the bounds data is supplied separately.
13 |
14 | // Originally written for my game Scraps (http://www.scrapsgame.com) but intended to be general-purpose.
15 | // Copyright 2014 Nition, BSD licence (see LICENCE file). www.momentstudio.co.nz
16 | // Unity-based, but could be adapted to work in pure C#
17 | public class PointOctree {
18 | // The total amount of objects currently in the tree
19 | public int Count { get; private set; }
20 |
21 | // Root node of the octree
22 | PointOctreeNode rootNode;
23 |
24 | // Size that the octree was on creation
25 | readonly float initialSize;
26 |
27 | // Minimum side length that a node can be - essentially an alternative to having a max depth
28 | readonly float minSize;
29 |
30 | ///
31 | /// Constructor for the point octree.
32 | ///
33 | /// Size of the sides of the initial node. The octree will never shrink smaller than this.
34 | /// Position of the centre of the initial node.
35 | /// Nodes will stop splitting if the new nodes would be smaller than this.
36 | public PointOctree(float initialWorldSize, Vector3 initialWorldPos, float minNodeSize) {
37 | if (minNodeSize > initialWorldSize) {
38 | Debug.LogWarning("Minimum node size must be at least as big as the initial world size. Was: " + minNodeSize + " Adjusted to: " + initialWorldSize);
39 | minNodeSize = initialWorldSize;
40 | }
41 | Count = 0;
42 | initialSize = initialWorldSize;
43 | minSize = minNodeSize;
44 | rootNode = new PointOctreeNode(initialSize, minSize, initialWorldPos);
45 | }
46 |
47 | // #### PUBLIC METHODS ####
48 |
49 | ///
50 | /// Add an object.
51 | ///
52 | /// Object to add.
53 | /// Position of the object.
54 | public void Add(T obj, Vector3 objPos) {
55 | // Add object or expand the octree until it can be added
56 | int count = 0; // Safety check against infinite/excessive growth
57 | while (!rootNode.Add(obj, objPos)) {
58 | Grow(objPos - rootNode.Center);
59 | if (++count > 20) {
60 | Debug.LogError("Aborted Add operation as it seemed to be going on forever (" + (count - 1) + ") attempts at growing the octree.");
61 | return;
62 | }
63 | }
64 | Count++;
65 | }
66 |
67 | ///
68 | /// Remove an object. Makes the assumption that the object only exists once in the tree.
69 | ///
70 | /// Object to remove.
71 | /// True if the object was removed successfully.
72 | public bool Remove(T obj) {
73 | bool removed = rootNode.Remove(obj);
74 |
75 | // See if we can shrink the octree down now that we've removed the item
76 | if (removed) {
77 | Count--;
78 | Shrink();
79 | }
80 |
81 | return removed;
82 | }
83 |
84 | ///
85 | /// Removes the specified object at the given position. Makes the assumption that the object only exists once in the tree.
86 | ///
87 | /// Object to remove.
88 | /// Position of the object.
89 | /// True if the object was removed successfully.
90 | public bool Remove(T obj, Vector3 objPos) {
91 | bool removed = rootNode.Remove(obj, objPos);
92 |
93 | // See if we can shrink the octree down now that we've removed the item
94 | if (removed) {
95 | Count--;
96 | Shrink();
97 | }
98 |
99 | return removed;
100 | }
101 |
102 | ///
103 | /// Returns objects that are within of the specified ray.
104 | /// If none, returns false. Uses supplied list for results.
105 | ///
106 | /// The ray. Passing as ref to improve performance since it won't have to be copied.
107 | /// Maximum distance from the ray to consider
108 | /// Pre-initialized list to populate
109 | /// True if items are found, false if not
110 | public bool GetNearbyNonAlloc(Ray ray, float maxDistance, List nearBy) {
111 | nearBy.Clear();
112 | rootNode.GetNearby(ref ray, maxDistance, nearBy);
113 | if (nearBy.Count > 0)
114 | return true;
115 | return false;
116 | }
117 |
118 | ///
119 | /// Returns objects that are within of the specified ray.
120 | /// If none, returns an empty array (not null).
121 | ///
122 | /// The ray. Passing as ref to improve performance since it won't have to be copied.
123 | /// Maximum distance from the ray to consider.
124 | /// Objects within range.
125 | public T[] GetNearby(Ray ray, float maxDistance) {
126 | List collidingWith = new List();
127 | rootNode.GetNearby(ref ray, maxDistance, collidingWith);
128 | return collidingWith.ToArray();
129 | }
130 |
131 | ///
132 | /// Returns objects that are within of the specified position.
133 | /// If none, returns an empty array (not null).
134 | ///
135 | /// The position. Passing as ref to improve performance since it won't have to be copied.
136 | /// Maximum distance from the position to consider.
137 | /// Objects within range.
138 | public T[] GetNearby(Vector3 position, float maxDistance) {
139 | List collidingWith = new List();
140 | rootNode.GetNearby(ref position, maxDistance, collidingWith);
141 | return collidingWith.ToArray();
142 | }
143 |
144 | ///
145 | /// Returns objects that are within of the specified position.
146 | /// If none, returns false. Uses supplied list for results.
147 | ///
148 | /// Maximum distance from the position to consider
149 | /// Pre-initialized list to populate
150 | /// True if items are found, false if not
151 | public bool GetNearbyNonAlloc(Vector3 position, float maxDistance, List nearBy) {
152 | nearBy.Clear();
153 | rootNode.GetNearby(ref position, maxDistance, nearBy);
154 | if (nearBy.Count > 0)
155 | return true;
156 | return false;
157 | }
158 |
159 | ///
160 | /// Return all objects in the tree.
161 | /// If none, returns an empty array (not null).
162 | ///
163 | /// All objects.
164 | public ICollection GetAll() {
165 | List objects = new List(Count);
166 | rootNode.GetAll(objects);
167 | return objects;
168 | }
169 |
170 | ///
171 | /// Draws node boundaries visually for debugging.
172 | /// Must be called from OnDrawGizmos externally. See also: DrawAllObjects.
173 | ///
174 | public void DrawAllBounds() {
175 | rootNode.DrawAllBounds();
176 | }
177 |
178 | ///
179 | /// Draws the bounds of all objects in the tree visually for debugging.
180 | /// Must be called from OnDrawGizmos externally. See also: DrawAllBounds.
181 | ///
182 | public void DrawAllObjects() {
183 | rootNode.DrawAllObjects();
184 | }
185 |
186 | // #### PRIVATE METHODS ####
187 |
188 | ///
189 | /// Grow the octree to fit in all objects.
190 | ///
191 | /// Direction to grow.
192 | void Grow(Vector3 direction) {
193 | int xDirection = direction.x >= 0 ? 1 : -1;
194 | int yDirection = direction.y >= 0 ? 1 : -1;
195 | int zDirection = direction.z >= 0 ? 1 : -1;
196 | PointOctreeNode oldRoot = rootNode;
197 | float half = rootNode.SideLength / 2;
198 | float newLength = rootNode.SideLength * 2;
199 | Vector3 newCenter = rootNode.Center + new Vector3(xDirection * half, yDirection * half, zDirection * half);
200 |
201 | // Create a new, bigger octree root node
202 | rootNode = new PointOctreeNode(newLength, minSize, newCenter);
203 |
204 | if (oldRoot.HasAnyObjects()) {
205 | // Create 7 new octree children to go with the old root as children of the new root
206 | int rootPos = rootNode.BestFitChild(oldRoot.Center);
207 | PointOctreeNode[] children = new PointOctreeNode[8];
208 | for (int i = 0; i < 8; i++) {
209 | if (i == rootPos) {
210 | children[i] = oldRoot;
211 | }
212 | else {
213 | xDirection = i % 2 == 0 ? -1 : 1;
214 | yDirection = i > 3 ? -1 : 1;
215 | zDirection = (i < 2 || (i > 3 && i < 6)) ? -1 : 1;
216 | children[i] = new PointOctreeNode(oldRoot.SideLength, minSize, newCenter + new Vector3(xDirection * half, yDirection * half, zDirection * half));
217 | }
218 | }
219 |
220 | // Attach the new children to the new root node
221 | rootNode.SetChildren(children);
222 | }
223 | }
224 |
225 | ///
226 | /// Shrink the octree if possible, else leave it the same.
227 | ///
228 | void Shrink() {
229 | rootNode = rootNode.ShrinkIfPossible(initialSize);
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/Assets/UnityOctree/PointOctree.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9db0c90c9ab9af246b08fa68962659ae
3 | timeCreated: 1481513782
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/UnityOctree/PointOctreeNode.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using UnityEngine;
4 |
5 | // A node in a PointOctree
6 | // Copyright 2014 Nition, BSD licence (see LICENCE file). www.momentstudio.co.nz
7 | public class PointOctreeNode {
8 | // Centre of this node
9 | public Vector3 Center { get; private set; }
10 |
11 | // Length of the sides of this node
12 | public float SideLength { get; private set; }
13 |
14 | // Minimum size for a node in this octree
15 | float minSize;
16 |
17 | // Bounding box that represents this node
18 | Bounds bounds = default(Bounds);
19 |
20 | // Objects in this node
21 | readonly List objects = new List();
22 |
23 | // Child nodes, if any
24 | PointOctreeNode[] children = null;
25 |
26 | bool HasChildren { get { return children != null; } }
27 |
28 | // bounds of potential children to this node. These are actual size (with looseness taken into account), not base size
29 | Bounds[] childBounds;
30 |
31 | // If there are already NUM_OBJECTS_ALLOWED in a node, we split it into children
32 | // A generally good number seems to be something around 8-15
33 | const int NUM_OBJECTS_ALLOWED = 8;
34 |
35 | // For reverting the bounds size after temporary changes
36 | Vector3 actualBoundsSize;
37 |
38 | // An object in the octree
39 | class OctreeObject {
40 | public T Obj;
41 | public Vector3 Pos;
42 | }
43 |
44 | ///
45 | /// Constructor.
46 | ///
47 | /// Length of this node, not taking looseness into account.
48 | /// Minimum size of nodes in this octree.
49 | /// Centre position of this node.
50 | public PointOctreeNode(float baseLengthVal, float minSizeVal, Vector3 centerVal) {
51 | SetValues(baseLengthVal, minSizeVal, centerVal);
52 | }
53 |
54 | // #### PUBLIC METHODS ####
55 |
56 | ///
57 | /// Add an object.
58 | ///
59 | /// Object to add.
60 | /// Position of the object.
61 | ///
62 | public bool Add(T obj, Vector3 objPos) {
63 | if (!Encapsulates(bounds, objPos)) {
64 | return false;
65 | }
66 | SubAdd(obj, objPos);
67 | return true;
68 | }
69 |
70 | ///
71 | /// Remove an object. Makes the assumption that the object only exists once in the tree.
72 | ///
73 | /// Object to remove.
74 | /// True if the object was removed successfully.
75 | public bool Remove(T obj) {
76 | bool removed = false;
77 |
78 | for (int i = 0; i < objects.Count; i++) {
79 | if (objects[i].Obj.Equals(obj)) {
80 | removed = objects.Remove(objects[i]);
81 | break;
82 | }
83 | }
84 |
85 | if (!removed && children != null) {
86 | for (int i = 0; i < 8; i++) {
87 | removed = children[i].Remove(obj);
88 | if (removed) break;
89 | }
90 | }
91 |
92 | if (removed && children != null) {
93 | // Check if we should merge nodes now that we've removed an item
94 | if (ShouldMerge()) {
95 | Merge();
96 | }
97 | }
98 |
99 | return removed;
100 | }
101 |
102 | ///
103 | /// Removes the specified object at the given position. Makes the assumption that the object only exists once in the tree.
104 | ///
105 | /// Object to remove.
106 | /// Position of the object.
107 | /// True if the object was removed successfully.
108 | public bool Remove(T obj, Vector3 objPos) {
109 | if (!Encapsulates(bounds, objPos)) {
110 | return false;
111 | }
112 | return SubRemove(obj, objPos);
113 | }
114 |
115 | ///
116 | /// Return objects that are within maxDistance of the specified ray.
117 | ///
118 | /// The ray.
119 | /// Maximum distance from the ray to consider.
120 | /// List result.
121 | /// Objects within range.
122 | public void GetNearby(ref Ray ray, float maxDistance, List result) {
123 | // Does the ray hit this node at all?
124 | // Note: Expanding the bounds is not exactly the same as a real distance check, but it's fast.
125 | // TODO: Does someone have a fast AND accurate formula to do this check?
126 | bounds.Expand(new Vector3(maxDistance * 2, maxDistance * 2, maxDistance * 2));
127 | bool intersected = bounds.IntersectRay(ray);
128 | bounds.size = actualBoundsSize;
129 | if (!intersected) {
130 | return;
131 | }
132 |
133 | // Check against any objects in this node
134 | for (int i = 0; i < objects.Count; i++) {
135 | if (SqrDistanceToRay(ray, objects[i].Pos) <= (maxDistance * maxDistance)) {
136 | result.Add(objects[i].Obj);
137 | }
138 | }
139 |
140 | // Check children
141 | if (children != null) {
142 | for (int i = 0; i < 8; i++) {
143 | children[i].GetNearby(ref ray, maxDistance, result);
144 | }
145 | }
146 | }
147 |
148 | ///
149 | /// Return objects that are within of the specified position.
150 | ///
151 | /// The position.
152 | /// Maximum distance from the position to consider.
153 | /// List result.
154 | /// Objects within range.
155 | public void GetNearby(ref Vector3 position, float maxDistance, List result) {
156 | float sqrMaxDistance = maxDistance * maxDistance;
157 |
158 | #if UNITY_2017_1_OR_NEWER
159 | // Does the node intersect with the sphere of center = position and radius = maxDistance?
160 | if ((bounds.ClosestPoint(position) - position).sqrMagnitude > sqrMaxDistance) {
161 | return;
162 | }
163 | #else
164 | // Does the ray hit this node at all?
165 | // Note: Expanding the bounds is not exactly the same as a real distance check, but it's fast
166 | // TODO: Does someone have a fast AND accurate formula to do this check?
167 | bounds.Expand(new Vector3(maxDistance * 2, maxDistance * 2, maxDistance * 2));
168 | bool contained = bounds.Contains(position);
169 | bounds.size = actualBoundsSize;
170 | if (!contained) {
171 | return;
172 | }
173 | #endif
174 |
175 | // Check against any objects in this node
176 | for (int i = 0; i < objects.Count; i++) {
177 | if ((position - objects[i].Pos).sqrMagnitude <= sqrMaxDistance) {
178 | result.Add(objects[i].Obj);
179 | }
180 | }
181 |
182 | // Check children
183 | if (children != null) {
184 | for (int i = 0; i < 8; i++) {
185 | children[i].GetNearby(ref position, maxDistance, result);
186 | }
187 | }
188 | }
189 |
190 | ///
191 | /// Return all objects in the tree.
192 | ///
193 | /// All objects.
194 | public void GetAll(List result) {
195 | // add directly contained objects
196 | result.AddRange(objects.Select(o => o.Obj));
197 |
198 | // add children objects
199 | if (children != null) {
200 | for (int i = 0; i < 8; i++) {
201 | children[i].GetAll(result);
202 | }
203 | }
204 | }
205 |
206 | ///
207 | /// Set the 8 children of this octree.
208 | ///
209 | /// The 8 new child nodes.
210 | public void SetChildren(PointOctreeNode[] childOctrees) {
211 | if (childOctrees.Length != 8) {
212 | Debug.LogError("Child octree array must be length 8. Was length: " + childOctrees.Length);
213 | return;
214 | }
215 |
216 | children = childOctrees;
217 | }
218 |
219 | ///
220 | /// Draws node boundaries visually for debugging.
221 | /// Must be called from OnDrawGizmos externally. See also: DrawAllObjects.
222 | ///
223 | /// Used for recurcive calls to this method.
224 | public void DrawAllBounds(float depth = 0) {
225 | float tintVal = depth / 7; // Will eventually get values > 1. Color rounds to 1 automatically
226 | Gizmos.color = new Color(tintVal, 0, 1.0f - tintVal);
227 |
228 | Bounds thisBounds = new Bounds(Center, new Vector3(SideLength, SideLength, SideLength));
229 | Gizmos.DrawWireCube(thisBounds.center, thisBounds.size);
230 |
231 | if (children != null) {
232 | depth++;
233 | for (int i = 0; i < 8; i++) {
234 | children[i].DrawAllBounds(depth);
235 | }
236 | }
237 | Gizmos.color = Color.white;
238 | }
239 |
240 | ///
241 | /// Draws the bounds of all objects in the tree visually for debugging.
242 | /// Must be called from OnDrawGizmos externally. See also: DrawAllBounds.
243 | /// NOTE: marker.tif must be placed in your Unity /Assets/Gizmos subfolder for this to work.
244 | ///
245 | public void DrawAllObjects() {
246 | float tintVal = SideLength / 20;
247 | Gizmos.color = new Color(0, 1.0f - tintVal, tintVal, 0.25f);
248 |
249 | foreach (OctreeObject obj in objects) {
250 | Gizmos.DrawIcon(obj.Pos, "marker.tif", true);
251 | }
252 |
253 | if (children != null) {
254 | for (int i = 0; i < 8; i++) {
255 | children[i].DrawAllObjects();
256 | }
257 | }
258 |
259 | Gizmos.color = Color.white;
260 | }
261 |
262 | ///
263 | /// We can shrink the octree if:
264 | /// - This node is >= double minLength in length
265 | /// - All objects in the root node are within one octant
266 | /// - This node doesn't have children, or does but 7/8 children are empty
267 | /// We can also shrink it if there are no objects left at all!
268 | ///
269 | /// Minimum dimensions of a node in this octree.
270 | /// The new root, or the existing one if we didn't shrink.
271 | public PointOctreeNode ShrinkIfPossible(float minLength) {
272 | if (SideLength < (2 * minLength)) {
273 | return this;
274 | }
275 | if (objects.Count == 0 && (children == null || children.Length == 0)) {
276 | return this;
277 | }
278 |
279 | // Check objects in root
280 | int bestFit = -1;
281 | for (int i = 0; i < objects.Count; i++) {
282 | OctreeObject curObj = objects[i];
283 | int newBestFit = BestFitChild(curObj.Pos);
284 | if (i == 0 || newBestFit == bestFit) {
285 | if (bestFit < 0) {
286 | bestFit = newBestFit;
287 | }
288 | }
289 | else {
290 | return this; // Can't reduce - objects fit in different octants
291 | }
292 | }
293 |
294 | // Check objects in children if there are any
295 | if (children != null) {
296 | bool childHadContent = false;
297 | for (int i = 0; i < children.Length; i++) {
298 | if (children[i].HasAnyObjects()) {
299 | if (childHadContent) {
300 | return this; // Can't shrink - another child had content already
301 | }
302 | if (bestFit >= 0 && bestFit != i) {
303 | return this; // Can't reduce - objects in root are in a different octant to objects in child
304 | }
305 | childHadContent = true;
306 | bestFit = i;
307 | }
308 | }
309 | }
310 |
311 | // Can reduce
312 | if (children == null) {
313 | // We don't have any children, so just shrink this node to the new size
314 | // We already know that everything will still fit in it
315 | SetValues(SideLength / 2, minSize, childBounds[bestFit].center);
316 | return this;
317 | }
318 |
319 | // We have children. Use the appropriate child as the new root node
320 | return children[bestFit];
321 | }
322 |
323 | ///
324 | /// Find which child node this object would be most likely to fit in.
325 | ///
326 | /// The object's position.
327 | /// One of the eight child octants.
328 | public int BestFitChild(Vector3 objPos) {
329 | return (objPos.x <= Center.x ? 0 : 1) + (objPos.y >= Center.y ? 0 : 4) + (objPos.z <= Center.z ? 0 : 2);
330 | }
331 |
332 | ///
333 | /// Checks if this node or anything below it has something in it.
334 | ///
335 | /// True if this node or any of its children, grandchildren etc have something in them
336 | public bool HasAnyObjects() {
337 | if (objects.Count > 0) return true;
338 |
339 | if (children != null) {
340 | for (int i = 0; i < 8; i++) {
341 | if (children[i].HasAnyObjects()) return true;
342 | }
343 | }
344 |
345 | return false;
346 | }
347 |
348 | /*
349 | ///
350 | /// Get the total amount of objects in this node and all its children, grandchildren etc. Useful for debugging.
351 | ///
352 | /// Used by recursive calls to add to the previous total.
353 | /// Total objects in this node and its children, grandchildren etc.
354 | public int GetTotalObjects(int startingNum = 0) {
355 | int totalObjects = startingNum + objects.Count;
356 | if (children != null) {
357 | for (int i = 0; i < 8; i++) {
358 | totalObjects += children[i].GetTotalObjects();
359 | }
360 | }
361 | return totalObjects;
362 | }
363 | */
364 |
365 | // #### PRIVATE METHODS ####
366 |
367 | ///
368 | /// Set values for this node.
369 | ///
370 | /// Length of this node, not taking looseness into account.
371 | /// Minimum size of nodes in this octree.
372 | /// Centre position of this node.
373 | void SetValues(float baseLengthVal, float minSizeVal, Vector3 centerVal) {
374 | SideLength = baseLengthVal;
375 | minSize = minSizeVal;
376 | Center = centerVal;
377 |
378 | // Create the bounding box.
379 | actualBoundsSize = new Vector3(SideLength, SideLength, SideLength);
380 | bounds = new Bounds(Center, actualBoundsSize);
381 |
382 | float quarter = SideLength / 4f;
383 | float childActualLength = SideLength / 2;
384 | Vector3 childActualSize = new Vector3(childActualLength, childActualLength, childActualLength);
385 | childBounds = new Bounds[8];
386 | childBounds[0] = new Bounds(Center + new Vector3(-quarter, quarter, -quarter), childActualSize);
387 | childBounds[1] = new Bounds(Center + new Vector3(quarter, quarter, -quarter), childActualSize);
388 | childBounds[2] = new Bounds(Center + new Vector3(-quarter, quarter, quarter), childActualSize);
389 | childBounds[3] = new Bounds(Center + new Vector3(quarter, quarter, quarter), childActualSize);
390 | childBounds[4] = new Bounds(Center + new Vector3(-quarter, -quarter, -quarter), childActualSize);
391 | childBounds[5] = new Bounds(Center + new Vector3(quarter, -quarter, -quarter), childActualSize);
392 | childBounds[6] = new Bounds(Center + new Vector3(-quarter, -quarter, quarter), childActualSize);
393 | childBounds[7] = new Bounds(Center + new Vector3(quarter, -quarter, quarter), childActualSize);
394 | }
395 |
396 | ///
397 | /// Private counterpart to the public Add method.
398 | ///
399 | /// Object to add.
400 | /// Position of the object.
401 | void SubAdd(T obj, Vector3 objPos) {
402 | // We know it fits at this level if we've got this far
403 |
404 | // We always put things in the deepest possible child
405 | // So we can skip checks and simply move down if there are children aleady
406 | if (!HasChildren) {
407 | // Just add if few objects are here, or children would be below min size
408 | if (objects.Count < NUM_OBJECTS_ALLOWED || (SideLength / 2) < minSize) {
409 | OctreeObject newObj = new OctreeObject { Obj = obj, Pos = objPos };
410 | objects.Add(newObj);
411 | return; // We're done. No children yet
412 | }
413 |
414 | // Enough objects in this node already: Create the 8 children
415 | int bestFitChild;
416 | if (children == null) {
417 | Split();
418 | if (children == null) {
419 | Debug.LogError("Child creation failed for an unknown reason. Early exit.");
420 | return;
421 | }
422 |
423 | // Now that we have the new children, move this node's existing objects into them
424 | for (int i = objects.Count - 1; i >= 0; i--) {
425 | OctreeObject existingObj = objects[i];
426 | // Find which child the object is closest to based on where the
427 | // object's center is located in relation to the octree's center
428 | bestFitChild = BestFitChild(existingObj.Pos);
429 | children[bestFitChild].SubAdd(existingObj.Obj, existingObj.Pos); // Go a level deeper
430 | objects.Remove(existingObj); // Remove from here
431 | }
432 | }
433 | }
434 |
435 | // Handle the new object we're adding now
436 | int bestFit = BestFitChild(objPos);
437 | children[bestFit].SubAdd(obj, objPos);
438 | }
439 |
440 | ///
441 | /// Private counterpart to the public method.
442 | ///
443 | /// Object to remove.
444 | /// Position of the object.
445 | /// True if the object was removed successfully.
446 | bool SubRemove(T obj, Vector3 objPos) {
447 | bool removed = false;
448 |
449 | for (int i = 0; i < objects.Count; i++) {
450 | if (objects[i].Obj.Equals(obj)) {
451 | removed = objects.Remove(objects[i]);
452 | break;
453 | }
454 | }
455 |
456 | if (!removed && children != null) {
457 | int bestFitChild = BestFitChild(objPos);
458 | removed = children[bestFitChild].SubRemove(obj, objPos);
459 | }
460 |
461 | if (removed && children != null) {
462 | // Check if we should merge nodes now that we've removed an item
463 | if (ShouldMerge()) {
464 | Merge();
465 | }
466 | }
467 |
468 | return removed;
469 | }
470 |
471 | ///
472 | /// Splits the octree into eight children.
473 | ///
474 | void Split() {
475 | float quarter = SideLength / 4f;
476 | float newLength = SideLength / 2;
477 | children = new PointOctreeNode[8];
478 | children[0] = new PointOctreeNode(newLength, minSize, Center + new Vector3(-quarter, quarter, -quarter));
479 | children[1] = new PointOctreeNode(newLength, minSize, Center + new Vector3(quarter, quarter, -quarter));
480 | children[2] = new PointOctreeNode(newLength, minSize, Center + new Vector3(-quarter, quarter, quarter));
481 | children[3] = new PointOctreeNode(newLength, minSize, Center + new Vector3(quarter, quarter, quarter));
482 | children[4] = new PointOctreeNode(newLength, minSize, Center + new Vector3(-quarter, -quarter, -quarter));
483 | children[5] = new PointOctreeNode(newLength, minSize, Center + new Vector3(quarter, -quarter, -quarter));
484 | children[6] = new PointOctreeNode(newLength, minSize, Center + new Vector3(-quarter, -quarter, quarter));
485 | children[7] = new PointOctreeNode(newLength, minSize, Center + new Vector3(quarter, -quarter, quarter));
486 | }
487 |
488 | ///
489 | /// Merge all children into this node - the opposite of Split.
490 | /// Note: We only have to check one level down since a merge will never happen if the children already have children,
491 | /// since THAT won't happen unless there are already too many objects to merge.
492 | ///
493 | void Merge() {
494 | // Note: We know children != null or we wouldn't be merging
495 | for (int i = 0; i < 8; i++) {
496 | PointOctreeNode curChild = children[i];
497 | int numObjects = curChild.objects.Count;
498 | for (int j = numObjects - 1; j >= 0; j--) {
499 | OctreeObject curObj = curChild.objects[j];
500 | objects.Add(curObj);
501 | }
502 | }
503 | // Remove the child nodes (and the objects in them - they've been added elsewhere now)
504 | children = null;
505 | }
506 |
507 | ///
508 | /// Checks if outerBounds encapsulates the given point.
509 | ///
510 | /// Outer bounds.
511 | /// Point.
512 | /// True if innerBounds is fully encapsulated by outerBounds.
513 | static bool Encapsulates(Bounds outerBounds, Vector3 point) {
514 | return outerBounds.Contains(point);
515 | }
516 |
517 | ///
518 | /// Checks if there are few enough objects in this node and its children that the children should all be merged into this.
519 | ///
520 | /// True there are less or the same abount of objects in this and its children than numObjectsAllowed.
521 | bool ShouldMerge() {
522 | int totalObjects = objects.Count;
523 | if (children != null) {
524 | foreach (PointOctreeNode child in children) {
525 | if (child.children != null) {
526 | // If any of the *children* have children, there are definitely too many to merge,
527 | // or the child woudl have been merged already
528 | return false;
529 | }
530 | totalObjects += child.objects.Count;
531 | }
532 | }
533 | return totalObjects <= NUM_OBJECTS_ALLOWED;
534 | }
535 |
536 | ///
537 | /// Returns the closest distance to the given ray from a point.
538 | ///
539 | /// The ray.
540 | /// The point to check distance from the ray.
541 | /// Squared distance from the point to the closest point of the ray.
542 | public static float SqrDistanceToRay(Ray ray, Vector3 point) {
543 | return Vector3.Cross(ray.direction, point - ray.origin).sqrMagnitude;
544 | }
545 | }
546 |
--------------------------------------------------------------------------------
/Assets/UnityOctree/PointOctreeNode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7a3117d130f3f2b46b4761386f25c3b8
3 | timeCreated: 1481513782
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/WorldMonitor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 877efc7026ea890479a88c338061bb10
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/WorldMonitors.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | namespace oti.AI
6 | {
7 | public class WorldMonitors : MonoBehaviour
8 | {
9 | ///
10 | /// User defined list of GameObject to track
11 | ///
12 | [HideInInspector] // hides in child classes only
13 | public List TrackedObjects = new List();
14 |
15 | ///
16 | /// User defined area for defining close objects
17 | ///
18 | [HideInInspector] // hides in child classes only
19 | public List ThresholdSet = new List();
20 |
21 | ///
22 | /// Delegate for tracked object conflicts.
23 | ///
24 | /// The types of objects as defined in WorldMonitors
25 | /// The positions of the objects causing the conflict
26 | public delegate void ObjectConflictHandler(GameObject objectWithConflict, GameObject[] conflictingObjects, string[] conflictingTypes);
27 |
28 | ///
29 | /// Event to raise awareness to listeners of the increase tracked object conflict
30 | ///
31 | public event ObjectConflictHandler ConflictEnterers;
32 |
33 | ///
34 | /// Event to raise awareness to listeners of the reduced tracked object conflict
35 | ///
36 | public event ObjectConflictHandler ConflictLeavers;
37 |
38 | ///
39 | /// Event to inform listeners all conflicting objects have ended
40 | ///
41 | public event ObjectConflictHandler ConflictEnd;
42 |
43 | //Provide WorldMonitor a method to raise event from
44 | public void RaiseConflictEnterers(GameObject objectWithConflict, GameObject[] conflictingObjects, string[] conflictingTypes)
45 | {
46 | ConflictEnterers?.Invoke(objectWithConflict, conflictingObjects, conflictingTypes);
47 | }
48 |
49 | //Provide WorldMonitor a method to raise event from
50 | public void RaiseConflictLeavers(GameObject objectWithConflict, GameObject[] conflictingObjects, string[] conflictingTypes)
51 | {
52 | ConflictLeavers?.Invoke(objectWithConflict, conflictingObjects, conflictingTypes);
53 | }
54 |
55 | //Provide WorldMonitor a method to raise event from
56 | public void EndConflicts(GameObject objectWithEndedConflict)
57 | {
58 | ConflictEnd?.Invoke(objectWithEndedConflict, default(GameObject[]), default(string[]));
59 | }
60 |
61 | private void Start()
62 | {
63 | //if user hasn't created a GameObject with WorldMonitor singleton
64 | if (!WorldMonitor.Instance)
65 | {
66 | new GameObject(gameObject.name + "_WMContainer", typeof(WorldMonitor));
67 | }
68 |
69 | if(WorldMonitor.Instance.TrackingMode == TrackingMode.UnityTriggers)
70 | {
71 | foreach (TrackedObjectContainer toc in TrackedObjects)
72 | {
73 | foreach (GameObject go in toc.TrackedObjects)
74 | {
75 | if (!go.GetComponent())
76 | go.AddComponent();
77 |
78 | go.GetComponent().AcceptOwner(this);
79 | }
80 | }
81 | }
82 | }
83 | }
84 |
85 | [System.Serializable]
86 | public class TrackedObjectContainer
87 | {
88 | public List TrackedObjects = new List();
89 | }
90 | }
--------------------------------------------------------------------------------
/Assets/WorldMonitors.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 56a76824d65be454581186658dd2b4c0
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Images/20k.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Images/20k.PNG
--------------------------------------------------------------------------------
/Images/exampleTrack.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Images/exampleTrack.PNG
--------------------------------------------------------------------------------
/Images/inspInitial.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Images/inspInitial.PNG
--------------------------------------------------------------------------------
/Images/inspSymmetricObjects.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Images/inspSymmetricObjects.PNG
--------------------------------------------------------------------------------
/Images/smallScene.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Images/smallScene.PNG
--------------------------------------------------------------------------------
/Images/trackingScene.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Images/trackingScene.PNG
--------------------------------------------------------------------------------
/Images/triggerVsOctreeConflict.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Images/triggerVsOctreeConflict.PNG
--------------------------------------------------------------------------------
/Images/worldMonitor.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phatboysh/DynamicObjectTracking/0eca5e19ac230e4a71bca647deebcd2de25b71a4/Images/worldMonitor.PNG
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Joey Mansfield
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Packages/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | }
4 | }
5 |
--------------------------------------------------------------------------------
/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!11 &1
4 | AudioManager:
5 | m_ObjectHideFlags: 0
6 | m_Volume: 1
7 | Rolloff Scale: 1
8 | Doppler Factor: 1
9 | Default Speaker Mode: 2
10 | m_SampleRate: 0
11 | m_DSPBufferSize: 1024
12 | m_VirtualVoiceCount: 512
13 | m_RealVoiceCount: 32
14 | m_SpatializerPlugin:
15 | m_AmbisonicDecoderPlugin:
16 | m_DisableAudio: 0
17 | m_VirtualizeEffects: 1
18 |
--------------------------------------------------------------------------------
/ProjectSettings/ClusterInputManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!236 &1
4 | ClusterInputManager:
5 | m_ObjectHideFlags: 0
6 | m_Inputs: []
7 |
--------------------------------------------------------------------------------
/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!55 &1
4 | PhysicsManager:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 7
7 | m_Gravity: {x: 0, y: -9.81, z: 0}
8 | m_DefaultMaterial: {fileID: 0}
9 | m_BounceThreshold: 2
10 | m_SleepThreshold: 0.005
11 | m_DefaultContactOffset: 0.01
12 | m_DefaultSolverIterations: 6
13 | m_DefaultSolverVelocityIterations: 1
14 | m_QueriesHitBackfaces: 0
15 | m_QueriesHitTriggers: 1
16 | m_EnableAdaptiveForce: 0
17 | m_ClothInterCollisionDistance: 0
18 | m_ClothInterCollisionStiffness: 0
19 | m_ContactsGeneration: 1
20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
21 | m_AutoSimulation: 1
22 | m_AutoSyncTransforms: 1
23 | m_ClothInterCollisionSettingsToggle: 0
24 | m_ContactPairsMode: 0
25 | m_BroadphaseType: 0
26 | m_WorldBounds:
27 | m_Center: {x: 0, y: 0, z: 0}
28 | m_Extent: {x: 250, y: 250, z: 250}
29 | m_WorldSubdivisions: 8
30 |
--------------------------------------------------------------------------------
/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1045 &1
4 | EditorBuildSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Scenes:
8 | - enabled: 1
9 | path: Assets/Scenes/SampleScene.unity
10 | guid: 99c9720ab356a0642a771bea13969a05
11 | m_configObjects: {}
12 |
--------------------------------------------------------------------------------
/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!159 &1
4 | EditorSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 7
7 | m_ExternalVersionControlSupport: Visible Meta Files
8 | m_SerializationMode: 2
9 | m_LineEndingsForNewScripts: 2
10 | m_DefaultBehaviorMode: 0
11 | m_SpritePackerMode: 0
12 | m_SpritePackerPaddingPower: 1
13 | m_EtcTextureCompressorBehavior: 1
14 | m_EtcTextureFastCompressor: 1
15 | m_EtcTextureNormalCompressor: 2
16 | m_EtcTextureBestCompressor: 4
17 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd
18 | m_ProjectGenerationRootNamespace:
19 | m_UserGeneratedProjectSuffix:
20 | m_CollabEditorSettings:
21 | inProgressEnabled: 1
22 |
--------------------------------------------------------------------------------
/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!30 &1
4 | GraphicsSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 12
7 | m_Deferred:
8 | m_Mode: 1
9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
10 | m_DeferredReflections:
11 | m_Mode: 1
12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
13 | m_ScreenSpaceShadows:
14 | m_Mode: 1
15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
16 | m_LegacyDeferred:
17 | m_Mode: 1
18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
19 | m_DepthNormals:
20 | m_Mode: 1
21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
22 | m_MotionVectors:
23 | m_Mode: 1
24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
25 | m_LightHalo:
26 | m_Mode: 1
27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
28 | m_LensFlare:
29 | m_Mode: 1
30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
31 | m_AlwaysIncludedShaders:
32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
38 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
39 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
40 | m_PreloadedShaders: []
41 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
42 | type: 0}
43 | m_CustomRenderPipeline: {fileID: 0}
44 | m_TransparencySortMode: 0
45 | m_TransparencySortAxis: {x: 0, y: 0, z: 1}
46 | m_DefaultRenderingPath: 1
47 | m_DefaultMobileRenderingPath: 1
48 | m_TierSettings: []
49 | m_LightmapStripping: 0
50 | m_FogStripping: 0
51 | m_InstancingStripping: 0
52 | m_LightmapKeepPlain: 1
53 | m_LightmapKeepDirCombined: 1
54 | m_LightmapKeepDynamicPlain: 1
55 | m_LightmapKeepDynamicDirCombined: 1
56 | m_LightmapKeepShadowMask: 1
57 | m_LightmapKeepSubtractive: 1
58 | m_FogKeepLinear: 1
59 | m_FogKeepExp: 1
60 | m_FogKeepExp2: 1
61 | m_AlbedoSwatchInfos: []
62 | m_LightsUseLinearIntensity: 0
63 | m_LightsUseColorTemperature: 0
64 |
--------------------------------------------------------------------------------
/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!13 &1
4 | InputManager:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Axes:
8 | - serializedVersion: 3
9 | m_Name: Horizontal
10 | descriptiveName:
11 | descriptiveNegativeName:
12 | negativeButton: left
13 | positiveButton: right
14 | altNegativeButton: a
15 | altPositiveButton: d
16 | gravity: 3
17 | dead: 0.001
18 | sensitivity: 3
19 | snap: 1
20 | invert: 0
21 | type: 0
22 | axis: 0
23 | joyNum: 0
24 | - serializedVersion: 3
25 | m_Name: Vertical
26 | descriptiveName:
27 | descriptiveNegativeName:
28 | negativeButton: down
29 | positiveButton: up
30 | altNegativeButton: s
31 | altPositiveButton: w
32 | gravity: 3
33 | dead: 0.001
34 | sensitivity: 3
35 | snap: 1
36 | invert: 0
37 | type: 0
38 | axis: 0
39 | joyNum: 0
40 | - serializedVersion: 3
41 | m_Name: Fire1
42 | descriptiveName:
43 | descriptiveNegativeName:
44 | negativeButton:
45 | positiveButton: left ctrl
46 | altNegativeButton:
47 | altPositiveButton: mouse 0
48 | gravity: 1000
49 | dead: 0.001
50 | sensitivity: 1000
51 | snap: 0
52 | invert: 0
53 | type: 0
54 | axis: 0
55 | joyNum: 0
56 | - serializedVersion: 3
57 | m_Name: Fire2
58 | descriptiveName:
59 | descriptiveNegativeName:
60 | negativeButton:
61 | positiveButton: left alt
62 | altNegativeButton:
63 | altPositiveButton: mouse 1
64 | gravity: 1000
65 | dead: 0.001
66 | sensitivity: 1000
67 | snap: 0
68 | invert: 0
69 | type: 0
70 | axis: 0
71 | joyNum: 0
72 | - serializedVersion: 3
73 | m_Name: Fire3
74 | descriptiveName:
75 | descriptiveNegativeName:
76 | negativeButton:
77 | positiveButton: left shift
78 | altNegativeButton:
79 | altPositiveButton: mouse 2
80 | gravity: 1000
81 | dead: 0.001
82 | sensitivity: 1000
83 | snap: 0
84 | invert: 0
85 | type: 0
86 | axis: 0
87 | joyNum: 0
88 | - serializedVersion: 3
89 | m_Name: Jump
90 | descriptiveName:
91 | descriptiveNegativeName:
92 | negativeButton:
93 | positiveButton: space
94 | altNegativeButton:
95 | altPositiveButton:
96 | gravity: 1000
97 | dead: 0.001
98 | sensitivity: 1000
99 | snap: 0
100 | invert: 0
101 | type: 0
102 | axis: 0
103 | joyNum: 0
104 | - serializedVersion: 3
105 | m_Name: Mouse X
106 | descriptiveName:
107 | descriptiveNegativeName:
108 | negativeButton:
109 | positiveButton:
110 | altNegativeButton:
111 | altPositiveButton:
112 | gravity: 0
113 | dead: 0
114 | sensitivity: 0.1
115 | snap: 0
116 | invert: 0
117 | type: 1
118 | axis: 0
119 | joyNum: 0
120 | - serializedVersion: 3
121 | m_Name: Mouse Y
122 | descriptiveName:
123 | descriptiveNegativeName:
124 | negativeButton:
125 | positiveButton:
126 | altNegativeButton:
127 | altPositiveButton:
128 | gravity: 0
129 | dead: 0
130 | sensitivity: 0.1
131 | snap: 0
132 | invert: 0
133 | type: 1
134 | axis: 1
135 | joyNum: 0
136 | - serializedVersion: 3
137 | m_Name: Mouse ScrollWheel
138 | descriptiveName:
139 | descriptiveNegativeName:
140 | negativeButton:
141 | positiveButton:
142 | altNegativeButton:
143 | altPositiveButton:
144 | gravity: 0
145 | dead: 0
146 | sensitivity: 0.1
147 | snap: 0
148 | invert: 0
149 | type: 1
150 | axis: 2
151 | joyNum: 0
152 | - serializedVersion: 3
153 | m_Name: Horizontal
154 | descriptiveName:
155 | descriptiveNegativeName:
156 | negativeButton:
157 | positiveButton:
158 | altNegativeButton:
159 | altPositiveButton:
160 | gravity: 0
161 | dead: 0.19
162 | sensitivity: 1
163 | snap: 0
164 | invert: 0
165 | type: 2
166 | axis: 0
167 | joyNum: 0
168 | - serializedVersion: 3
169 | m_Name: Vertical
170 | descriptiveName:
171 | descriptiveNegativeName:
172 | negativeButton:
173 | positiveButton:
174 | altNegativeButton:
175 | altPositiveButton:
176 | gravity: 0
177 | dead: 0.19
178 | sensitivity: 1
179 | snap: 0
180 | invert: 1
181 | type: 2
182 | axis: 1
183 | joyNum: 0
184 | - serializedVersion: 3
185 | m_Name: Fire1
186 | descriptiveName:
187 | descriptiveNegativeName:
188 | negativeButton:
189 | positiveButton: joystick button 0
190 | altNegativeButton:
191 | altPositiveButton:
192 | gravity: 1000
193 | dead: 0.001
194 | sensitivity: 1000
195 | snap: 0
196 | invert: 0
197 | type: 0
198 | axis: 0
199 | joyNum: 0
200 | - serializedVersion: 3
201 | m_Name: Fire2
202 | descriptiveName:
203 | descriptiveNegativeName:
204 | negativeButton:
205 | positiveButton: joystick button 1
206 | altNegativeButton:
207 | altPositiveButton:
208 | gravity: 1000
209 | dead: 0.001
210 | sensitivity: 1000
211 | snap: 0
212 | invert: 0
213 | type: 0
214 | axis: 0
215 | joyNum: 0
216 | - serializedVersion: 3
217 | m_Name: Fire3
218 | descriptiveName:
219 | descriptiveNegativeName:
220 | negativeButton:
221 | positiveButton: joystick button 2
222 | altNegativeButton:
223 | altPositiveButton:
224 | gravity: 1000
225 | dead: 0.001
226 | sensitivity: 1000
227 | snap: 0
228 | invert: 0
229 | type: 0
230 | axis: 0
231 | joyNum: 0
232 | - serializedVersion: 3
233 | m_Name: Jump
234 | descriptiveName:
235 | descriptiveNegativeName:
236 | negativeButton:
237 | positiveButton: joystick button 3
238 | altNegativeButton:
239 | altPositiveButton:
240 | gravity: 1000
241 | dead: 0.001
242 | sensitivity: 1000
243 | snap: 0
244 | invert: 0
245 | type: 0
246 | axis: 0
247 | joyNum: 0
248 | - serializedVersion: 3
249 | m_Name: Submit
250 | descriptiveName:
251 | descriptiveNegativeName:
252 | negativeButton:
253 | positiveButton: return
254 | altNegativeButton:
255 | altPositiveButton: joystick button 0
256 | gravity: 1000
257 | dead: 0.001
258 | sensitivity: 1000
259 | snap: 0
260 | invert: 0
261 | type: 0
262 | axis: 0
263 | joyNum: 0
264 | - serializedVersion: 3
265 | m_Name: Submit
266 | descriptiveName:
267 | descriptiveNegativeName:
268 | negativeButton:
269 | positiveButton: enter
270 | altNegativeButton:
271 | altPositiveButton: space
272 | gravity: 1000
273 | dead: 0.001
274 | sensitivity: 1000
275 | snap: 0
276 | invert: 0
277 | type: 0
278 | axis: 0
279 | joyNum: 0
280 | - serializedVersion: 3
281 | m_Name: Cancel
282 | descriptiveName:
283 | descriptiveNegativeName:
284 | negativeButton:
285 | positiveButton: escape
286 | altNegativeButton:
287 | altPositiveButton: joystick button 1
288 | gravity: 1000
289 | dead: 0.001
290 | sensitivity: 1000
291 | snap: 0
292 | invert: 0
293 | type: 0
294 | axis: 0
295 | joyNum: 0
296 |
--------------------------------------------------------------------------------
/ProjectSettings/NavMeshAreas.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!126 &1
4 | NavMeshProjectSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | areas:
8 | - name: Walkable
9 | cost: 1
10 | - name: Not Walkable
11 | cost: 1
12 | - name: Jump
13 | cost: 2
14 | - name:
15 | cost: 1
16 | - name:
17 | cost: 1
18 | - name:
19 | cost: 1
20 | - name:
21 | cost: 1
22 | - name:
23 | cost: 1
24 | - name:
25 | cost: 1
26 | - name:
27 | cost: 1
28 | - name:
29 | cost: 1
30 | - name:
31 | cost: 1
32 | - name:
33 | cost: 1
34 | - name:
35 | cost: 1
36 | - name:
37 | cost: 1
38 | - name:
39 | cost: 1
40 | - name:
41 | cost: 1
42 | - name:
43 | cost: 1
44 | - name:
45 | cost: 1
46 | - name:
47 | cost: 1
48 | - name:
49 | cost: 1
50 | - name:
51 | cost: 1
52 | - name:
53 | cost: 1
54 | - name:
55 | cost: 1
56 | - name:
57 | cost: 1
58 | - name:
59 | cost: 1
60 | - name:
61 | cost: 1
62 | - name:
63 | cost: 1
64 | - name:
65 | cost: 1
66 | - name:
67 | cost: 1
68 | - name:
69 | cost: 1
70 | - name:
71 | cost: 1
72 | m_LastAgentTypeID: -1372625422
73 | m_Settings:
74 | - serializedVersion: 2
75 | agentTypeID: 0
76 | agentRadius: 0.5
77 | agentHeight: 2
78 | agentSlope: 45
79 | agentClimb: 0.75
80 | ledgeDropHeight: 0
81 | maxJumpAcrossDistance: 0
82 | minRegionArea: 2
83 | manualCellSize: 0
84 | cellSize: 0.16666667
85 | manualTileSize: 0
86 | tileSize: 256
87 | accuratePlacement: 0
88 | debug:
89 | m_Flags: 0
90 | m_SettingNames:
91 | - Humanoid
92 |
--------------------------------------------------------------------------------
/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!149 &1
4 | NetworkManager:
5 | m_ObjectHideFlags: 0
6 | m_DebugLevel: 0
7 | m_Sendrate: 15
8 | m_AssetToPrefab: {}
9 |
--------------------------------------------------------------------------------
/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!19 &1
4 | Physics2DSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 3
7 | m_Gravity: {x: 0, y: -9.81}
8 | m_DefaultMaterial: {fileID: 0}
9 | m_VelocityIterations: 8
10 | m_PositionIterations: 3
11 | m_VelocityThreshold: 1
12 | m_MaxLinearCorrection: 0.2
13 | m_MaxAngularCorrection: 8
14 | m_MaxTranslationSpeed: 100
15 | m_MaxRotationSpeed: 360
16 | m_BaumgarteScale: 0.2
17 | m_BaumgarteTimeOfImpactScale: 0.75
18 | m_TimeToSleep: 0.5
19 | m_LinearSleepTolerance: 0.01
20 | m_AngularSleepTolerance: 2
21 | m_DefaultContactOffset: 0.01
22 | m_AutoSimulation: 1
23 | m_QueriesHitTriggers: 1
24 | m_QueriesStartInColliders: 1
25 | m_ChangeStopsCallbacks: 0
26 | m_CallbacksOnDisable: 1
27 | m_AutoSyncTransforms: 1
28 | m_AlwaysShowColliders: 0
29 | m_ShowColliderSleep: 1
30 | m_ShowColliderContacts: 0
31 | m_ShowColliderAABB: 0
32 | m_ContactArrowScale: 0.2
33 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
34 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
35 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
36 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
37 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
38 |
--------------------------------------------------------------------------------
/ProjectSettings/PresetManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1386491679 &1
4 | PresetManager:
5 | m_ObjectHideFlags: 0
6 | m_DefaultList:
7 | - type:
8 | m_NativeTypeID: 108
9 | m_ManagedTypePPtr: {fileID: 0}
10 | m_ManagedTypeFallback:
11 | defaultPresets:
12 | - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea,
13 | type: 2}
14 | - type:
15 | m_NativeTypeID: 1020
16 | m_ManagedTypePPtr: {fileID: 0}
17 | m_ManagedTypeFallback:
18 | defaultPresets:
19 | - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6,
20 | type: 2}
21 | - type:
22 | m_NativeTypeID: 1006
23 | m_ManagedTypePPtr: {fileID: 0}
24 | m_ManagedTypeFallback:
25 | defaultPresets:
26 | - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9,
27 | type: 2}
28 |
--------------------------------------------------------------------------------
/ProjectSettings/ProjectSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!129 &1
4 | PlayerSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 15
7 | productGUID: 7ae494ae49d7a0b44bb40661eca326e1
8 | AndroidProfiler: 0
9 | AndroidFilterTouchesWhenObscured: 0
10 | AndroidEnableSustainedPerformanceMode: 0
11 | defaultScreenOrientation: 4
12 | targetDevice: 2
13 | useOnDemandResources: 0
14 | accelerometerFrequency: 60
15 | companyName: DefaultCompany
16 | productName: Buckets AI
17 | defaultCursor: {fileID: 0}
18 | cursorHotspot: {x: 0, y: 0}
19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
20 | m_ShowUnitySplashScreen: 1
21 | m_ShowUnitySplashLogo: 1
22 | m_SplashScreenOverlayOpacity: 1
23 | m_SplashScreenAnimation: 1
24 | m_SplashScreenLogoStyle: 1
25 | m_SplashScreenDrawMode: 0
26 | m_SplashScreenBackgroundAnimationZoom: 1
27 | m_SplashScreenLogoAnimationZoom: 1
28 | m_SplashScreenBackgroundLandscapeAspect: 1
29 | m_SplashScreenBackgroundPortraitAspect: 1
30 | m_SplashScreenBackgroundLandscapeUvs:
31 | serializedVersion: 2
32 | x: 0
33 | y: 0
34 | width: 1
35 | height: 1
36 | m_SplashScreenBackgroundPortraitUvs:
37 | serializedVersion: 2
38 | x: 0
39 | y: 0
40 | width: 1
41 | height: 1
42 | m_SplashScreenLogos: []
43 | m_VirtualRealitySplashScreen: {fileID: 0}
44 | m_HolographicTrackingLossScreen: {fileID: 0}
45 | defaultScreenWidth: 1024
46 | defaultScreenHeight: 768
47 | defaultScreenWidthWeb: 960
48 | defaultScreenHeightWeb: 600
49 | m_StereoRenderingPath: 0
50 | m_ActiveColorSpace: 0
51 | m_MTRendering: 1
52 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000
53 | iosShowActivityIndicatorOnLoading: -1
54 | androidShowActivityIndicatorOnLoading: -1
55 | tizenShowActivityIndicatorOnLoading: -1
56 | iosAppInBackgroundBehavior: 0
57 | displayResolutionDialog: 1
58 | iosAllowHTTPDownload: 1
59 | allowedAutorotateToPortrait: 1
60 | allowedAutorotateToPortraitUpsideDown: 1
61 | allowedAutorotateToLandscapeRight: 1
62 | allowedAutorotateToLandscapeLeft: 1
63 | useOSAutorotation: 1
64 | use32BitDisplayBuffer: 1
65 | preserveFramebufferAlpha: 0
66 | disableDepthAndStencilBuffers: 0
67 | androidBlitType: 0
68 | defaultIsNativeResolution: 1
69 | macRetinaSupport: 1
70 | runInBackground: 1
71 | captureSingleScreen: 0
72 | muteOtherAudioSources: 0
73 | Prepare IOS For Recording: 0
74 | Force IOS Speakers When Recording: 0
75 | deferSystemGesturesMode: 0
76 | hideHomeButton: 0
77 | submitAnalytics: 1
78 | usePlayerLog: 1
79 | bakeCollisionMeshes: 0
80 | forceSingleInstance: 0
81 | resizableWindow: 0
82 | useMacAppStoreValidation: 0
83 | macAppStoreCategory: public.app-category.games
84 | gpuSkinning: 1
85 | graphicsJobs: 0
86 | xboxPIXTextureCapture: 0
87 | xboxEnableAvatar: 0
88 | xboxEnableKinect: 0
89 | xboxEnableKinectAutoTracking: 0
90 | xboxEnableFitness: 0
91 | visibleInBackground: 1
92 | allowFullscreenSwitch: 1
93 | graphicsJobMode: 0
94 | fullscreenMode: 1
95 | xboxSpeechDB: 0
96 | xboxEnableHeadOrientation: 0
97 | xboxEnableGuest: 0
98 | xboxEnablePIXSampling: 0
99 | metalFramebufferOnly: 0
100 | n3dsDisableStereoscopicView: 0
101 | n3dsEnableSharedListOpt: 1
102 | n3dsEnableVSync: 0
103 | xboxOneResolution: 0
104 | xboxOneSResolution: 0
105 | xboxOneXResolution: 3
106 | xboxOneMonoLoggingLevel: 0
107 | xboxOneLoggingLevel: 1
108 | xboxOneDisableEsram: 0
109 | xboxOnePresentImmediateThreshold: 0
110 | switchQueueCommandMemory: 0
111 | videoMemoryForVertexBuffers: 0
112 | psp2PowerMode: 0
113 | psp2AcquireBGM: 1
114 | m_SupportedAspectRatios:
115 | 4:3: 1
116 | 5:4: 1
117 | 16:10: 1
118 | 16:9: 1
119 | Others: 1
120 | bundleVersion: 0.1
121 | preloadedAssets: []
122 | metroInputSource: 0
123 | wsaTransparentSwapchain: 0
124 | m_HolographicPauseOnTrackingLoss: 1
125 | xboxOneDisableKinectGpuReservation: 0
126 | xboxOneEnable7thCore: 0
127 | vrSettings:
128 | cardboard:
129 | depthFormat: 0
130 | enableTransitionView: 0
131 | daydream:
132 | depthFormat: 0
133 | useSustainedPerformanceMode: 0
134 | enableVideoLayer: 0
135 | useProtectedVideoMemory: 0
136 | minimumSupportedHeadTracking: 0
137 | maximumSupportedHeadTracking: 1
138 | hololens:
139 | depthFormat: 1
140 | depthBufferSharingEnabled: 0
141 | enable360StereoCapture: 0
142 | oculus:
143 | sharedDepthBuffer: 0
144 | dashSupport: 0
145 | protectGraphicsMemory: 0
146 | useHDRDisplay: 0
147 | m_ColorGamuts: 00000000
148 | targetPixelDensity: 30
149 | resolutionScalingMode: 0
150 | androidSupportedAspectRatio: 1
151 | androidMaxAspectRatio: 2.1
152 | applicationIdentifier: {}
153 | buildNumber: {}
154 | AndroidBundleVersionCode: 1
155 | AndroidMinSdkVersion: 16
156 | AndroidTargetSdkVersion: 0
157 | AndroidPreferredInstallLocation: 1
158 | aotOptions:
159 | stripEngineCode: 1
160 | iPhoneStrippingLevel: 0
161 | iPhoneScriptCallOptimization: 0
162 | ForceInternetPermission: 0
163 | ForceSDCardPermission: 0
164 | CreateWallpaper: 0
165 | APKExpansionFiles: 0
166 | keepLoadedShadersAlive: 0
167 | StripUnusedMeshComponents: 1
168 | VertexChannelCompressionMask: 4054
169 | iPhoneSdkVersion: 988
170 | iOSTargetOSVersionString: 8.0
171 | tvOSSdkVersion: 0
172 | tvOSRequireExtendedGameController: 0
173 | tvOSTargetOSVersionString: 9.0
174 | uIPrerenderedIcon: 0
175 | uIRequiresPersistentWiFi: 0
176 | uIRequiresFullScreen: 1
177 | uIStatusBarHidden: 1
178 | uIExitOnSuspend: 0
179 | uIStatusBarStyle: 0
180 | iPhoneSplashScreen: {fileID: 0}
181 | iPhoneHighResSplashScreen: {fileID: 0}
182 | iPhoneTallHighResSplashScreen: {fileID: 0}
183 | iPhone47inSplashScreen: {fileID: 0}
184 | iPhone55inPortraitSplashScreen: {fileID: 0}
185 | iPhone55inLandscapeSplashScreen: {fileID: 0}
186 | iPhone58inPortraitSplashScreen: {fileID: 0}
187 | iPhone58inLandscapeSplashScreen: {fileID: 0}
188 | iPadPortraitSplashScreen: {fileID: 0}
189 | iPadHighResPortraitSplashScreen: {fileID: 0}
190 | iPadLandscapeSplashScreen: {fileID: 0}
191 | iPadHighResLandscapeSplashScreen: {fileID: 0}
192 | appleTVSplashScreen: {fileID: 0}
193 | appleTVSplashScreen2x: {fileID: 0}
194 | tvOSSmallIconLayers: []
195 | tvOSSmallIconLayers2x: []
196 | tvOSLargeIconLayers: []
197 | tvOSLargeIconLayers2x: []
198 | tvOSTopShelfImageLayers: []
199 | tvOSTopShelfImageLayers2x: []
200 | tvOSTopShelfImageWideLayers: []
201 | tvOSTopShelfImageWideLayers2x: []
202 | iOSLaunchScreenType: 0
203 | iOSLaunchScreenPortrait: {fileID: 0}
204 | iOSLaunchScreenLandscape: {fileID: 0}
205 | iOSLaunchScreenBackgroundColor:
206 | serializedVersion: 2
207 | rgba: 0
208 | iOSLaunchScreenFillPct: 100
209 | iOSLaunchScreenSize: 100
210 | iOSLaunchScreenCustomXibPath:
211 | iOSLaunchScreeniPadType: 0
212 | iOSLaunchScreeniPadImage: {fileID: 0}
213 | iOSLaunchScreeniPadBackgroundColor:
214 | serializedVersion: 2
215 | rgba: 0
216 | iOSLaunchScreeniPadFillPct: 100
217 | iOSLaunchScreeniPadSize: 100
218 | iOSLaunchScreeniPadCustomXibPath:
219 | iOSUseLaunchScreenStoryboard: 0
220 | iOSLaunchScreenCustomStoryboardPath:
221 | iOSDeviceRequirements: []
222 | iOSURLSchemes: []
223 | iOSBackgroundModes: 0
224 | iOSMetalForceHardShadows: 0
225 | metalEditorSupport: 1
226 | metalAPIValidation: 1
227 | iOSRenderExtraFrameOnPause: 0
228 | appleDeveloperTeamID:
229 | iOSManualSigningProvisioningProfileID:
230 | tvOSManualSigningProvisioningProfileID:
231 | iOSManualSigningProvisioningProfileType: 0
232 | tvOSManualSigningProvisioningProfileType: 0
233 | appleEnableAutomaticSigning: 0
234 | iOSRequireARKit: 0
235 | appleEnableProMotion: 0
236 | clonedFromGUID: 56e7a2d3a00f33d44bdd161b773c35b5
237 | templatePackageId: com.unity.template.3d@1.0.0
238 | templateDefaultScene: Assets/Scenes/SampleScene.unity
239 | AndroidTargetArchitectures: 5
240 | AndroidSplashScreenScale: 0
241 | androidSplashScreen: {fileID: 0}
242 | AndroidKeystoreName:
243 | AndroidKeyaliasName:
244 | AndroidTVCompatibility: 1
245 | AndroidIsGame: 1
246 | AndroidEnableTango: 0
247 | androidEnableBanner: 1
248 | androidUseLowAccuracyLocation: 0
249 | m_AndroidBanners:
250 | - width: 320
251 | height: 180
252 | banner: {fileID: 0}
253 | androidGamepadSupportLevel: 0
254 | resolutionDialogBanner: {fileID: 0}
255 | m_BuildTargetIcons: []
256 | m_BuildTargetPlatformIcons: []
257 | m_BuildTargetBatching:
258 | - m_BuildTarget: Standalone
259 | m_StaticBatching: 1
260 | m_DynamicBatching: 0
261 | - m_BuildTarget: tvOS
262 | m_StaticBatching: 1
263 | m_DynamicBatching: 0
264 | - m_BuildTarget: Android
265 | m_StaticBatching: 1
266 | m_DynamicBatching: 0
267 | - m_BuildTarget: iPhone
268 | m_StaticBatching: 1
269 | m_DynamicBatching: 0
270 | - m_BuildTarget: WebGL
271 | m_StaticBatching: 0
272 | m_DynamicBatching: 0
273 | m_BuildTargetGraphicsAPIs:
274 | - m_BuildTarget: AndroidPlayer
275 | m_APIs: 0b00000015000000
276 | m_Automatic: 1
277 | - m_BuildTarget: iOSSupport
278 | m_APIs: 10000000
279 | m_Automatic: 1
280 | - m_BuildTarget: AppleTVSupport
281 | m_APIs: 10000000
282 | m_Automatic: 0
283 | - m_BuildTarget: WebGLSupport
284 | m_APIs: 0b000000
285 | m_Automatic: 1
286 | m_BuildTargetVRSettings:
287 | - m_BuildTarget: Standalone
288 | m_Enabled: 0
289 | m_Devices:
290 | - Oculus
291 | - OpenVR
292 | m_BuildTargetEnableVuforiaSettings: []
293 | openGLRequireES31: 0
294 | openGLRequireES31AEP: 0
295 | m_TemplateCustomTags: {}
296 | mobileMTRendering:
297 | Android: 1
298 | iPhone: 1
299 | tvOS: 1
300 | m_BuildTargetGroupLightmapEncodingQuality: []
301 | playModeTestRunnerEnabled: 0
302 | runPlayModeTestAsEditModeTest: 0
303 | actionOnDotNetUnhandledException: 1
304 | enableInternalProfiler: 0
305 | logObjCUncaughtExceptions: 1
306 | enableCrashReportAPI: 0
307 | cameraUsageDescription:
308 | locationUsageDescription:
309 | microphoneUsageDescription:
310 | switchNetLibKey:
311 | switchSocketMemoryPoolSize: 6144
312 | switchSocketAllocatorPoolSize: 128
313 | switchSocketConcurrencyLimit: 14
314 | switchScreenResolutionBehavior: 2
315 | switchUseCPUProfiler: 0
316 | switchApplicationID: 0x01004b9000490000
317 | switchNSODependencies:
318 | switchTitleNames_0:
319 | switchTitleNames_1:
320 | switchTitleNames_2:
321 | switchTitleNames_3:
322 | switchTitleNames_4:
323 | switchTitleNames_5:
324 | switchTitleNames_6:
325 | switchTitleNames_7:
326 | switchTitleNames_8:
327 | switchTitleNames_9:
328 | switchTitleNames_10:
329 | switchTitleNames_11:
330 | switchTitleNames_12:
331 | switchTitleNames_13:
332 | switchTitleNames_14:
333 | switchPublisherNames_0:
334 | switchPublisherNames_1:
335 | switchPublisherNames_2:
336 | switchPublisherNames_3:
337 | switchPublisherNames_4:
338 | switchPublisherNames_5:
339 | switchPublisherNames_6:
340 | switchPublisherNames_7:
341 | switchPublisherNames_8:
342 | switchPublisherNames_9:
343 | switchPublisherNames_10:
344 | switchPublisherNames_11:
345 | switchPublisherNames_12:
346 | switchPublisherNames_13:
347 | switchPublisherNames_14:
348 | switchIcons_0: {fileID: 0}
349 | switchIcons_1: {fileID: 0}
350 | switchIcons_2: {fileID: 0}
351 | switchIcons_3: {fileID: 0}
352 | switchIcons_4: {fileID: 0}
353 | switchIcons_5: {fileID: 0}
354 | switchIcons_6: {fileID: 0}
355 | switchIcons_7: {fileID: 0}
356 | switchIcons_8: {fileID: 0}
357 | switchIcons_9: {fileID: 0}
358 | switchIcons_10: {fileID: 0}
359 | switchIcons_11: {fileID: 0}
360 | switchIcons_12: {fileID: 0}
361 | switchIcons_13: {fileID: 0}
362 | switchIcons_14: {fileID: 0}
363 | switchSmallIcons_0: {fileID: 0}
364 | switchSmallIcons_1: {fileID: 0}
365 | switchSmallIcons_2: {fileID: 0}
366 | switchSmallIcons_3: {fileID: 0}
367 | switchSmallIcons_4: {fileID: 0}
368 | switchSmallIcons_5: {fileID: 0}
369 | switchSmallIcons_6: {fileID: 0}
370 | switchSmallIcons_7: {fileID: 0}
371 | switchSmallIcons_8: {fileID: 0}
372 | switchSmallIcons_9: {fileID: 0}
373 | switchSmallIcons_10: {fileID: 0}
374 | switchSmallIcons_11: {fileID: 0}
375 | switchSmallIcons_12: {fileID: 0}
376 | switchSmallIcons_13: {fileID: 0}
377 | switchSmallIcons_14: {fileID: 0}
378 | switchManualHTML:
379 | switchAccessibleURLs:
380 | switchLegalInformation:
381 | switchMainThreadStackSize: 1048576
382 | switchPresenceGroupId:
383 | switchLogoHandling: 0
384 | switchReleaseVersion: 0
385 | switchDisplayVersion: 1.0.0
386 | switchStartupUserAccount: 0
387 | switchTouchScreenUsage: 0
388 | switchSupportedLanguagesMask: 0
389 | switchLogoType: 0
390 | switchApplicationErrorCodeCategory:
391 | switchUserAccountSaveDataSize: 0
392 | switchUserAccountSaveDataJournalSize: 0
393 | switchApplicationAttribute: 0
394 | switchCardSpecSize: -1
395 | switchCardSpecClock: -1
396 | switchRatingsMask: 0
397 | switchRatingsInt_0: 0
398 | switchRatingsInt_1: 0
399 | switchRatingsInt_2: 0
400 | switchRatingsInt_3: 0
401 | switchRatingsInt_4: 0
402 | switchRatingsInt_5: 0
403 | switchRatingsInt_6: 0
404 | switchRatingsInt_7: 0
405 | switchRatingsInt_8: 0
406 | switchRatingsInt_9: 0
407 | switchRatingsInt_10: 0
408 | switchRatingsInt_11: 0
409 | switchLocalCommunicationIds_0:
410 | switchLocalCommunicationIds_1:
411 | switchLocalCommunicationIds_2:
412 | switchLocalCommunicationIds_3:
413 | switchLocalCommunicationIds_4:
414 | switchLocalCommunicationIds_5:
415 | switchLocalCommunicationIds_6:
416 | switchLocalCommunicationIds_7:
417 | switchParentalControl: 0
418 | switchAllowsScreenshot: 1
419 | switchAllowsVideoCapturing: 1
420 | switchAllowsRuntimeAddOnContentInstall: 0
421 | switchDataLossConfirmation: 0
422 | switchSupportedNpadStyles: 3
423 | switchSocketConfigEnabled: 0
424 | switchTcpInitialSendBufferSize: 32
425 | switchTcpInitialReceiveBufferSize: 64
426 | switchTcpAutoSendBufferSizeMax: 256
427 | switchTcpAutoReceiveBufferSizeMax: 256
428 | switchUdpSendBufferSize: 9
429 | switchUdpReceiveBufferSize: 42
430 | switchSocketBufferEfficiency: 4
431 | switchSocketInitializeEnabled: 1
432 | switchNetworkInterfaceManagerInitializeEnabled: 1
433 | switchPlayerConnectionEnabled: 1
434 | ps4NPAgeRating: 12
435 | ps4NPTitleSecret:
436 | ps4NPTrophyPackPath:
437 | ps4ParentalLevel: 11
438 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000
439 | ps4Category: 0
440 | ps4MasterVersion: 01.00
441 | ps4AppVersion: 01.00
442 | ps4AppType: 0
443 | ps4ParamSfxPath:
444 | ps4VideoOutPixelFormat: 0
445 | ps4VideoOutInitialWidth: 1920
446 | ps4VideoOutBaseModeInitialWidth: 1920
447 | ps4VideoOutReprojectionRate: 60
448 | ps4PronunciationXMLPath:
449 | ps4PronunciationSIGPath:
450 | ps4BackgroundImagePath:
451 | ps4StartupImagePath:
452 | ps4StartupImagesFolder:
453 | ps4IconImagesFolder:
454 | ps4SaveDataImagePath:
455 | ps4SdkOverride:
456 | ps4BGMPath:
457 | ps4ShareFilePath:
458 | ps4ShareOverlayImagePath:
459 | ps4PrivacyGuardImagePath:
460 | ps4NPtitleDatPath:
461 | ps4RemotePlayKeyAssignment: -1
462 | ps4RemotePlayKeyMappingDir:
463 | ps4PlayTogetherPlayerCount: 0
464 | ps4EnterButtonAssignment: 1
465 | ps4ApplicationParam1: 0
466 | ps4ApplicationParam2: 0
467 | ps4ApplicationParam3: 0
468 | ps4ApplicationParam4: 0
469 | ps4DownloadDataSize: 0
470 | ps4GarlicHeapSize: 2048
471 | ps4ProGarlicHeapSize: 2560
472 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ
473 | ps4pnSessions: 1
474 | ps4pnPresence: 1
475 | ps4pnFriends: 1
476 | ps4pnGameCustomData: 1
477 | playerPrefsSupport: 0
478 | enableApplicationExit: 0
479 | restrictedAudioUsageRights: 0
480 | ps4UseResolutionFallback: 0
481 | ps4ReprojectionSupport: 0
482 | ps4UseAudio3dBackend: 0
483 | ps4SocialScreenEnabled: 0
484 | ps4ScriptOptimizationLevel: 0
485 | ps4Audio3dVirtualSpeakerCount: 14
486 | ps4attribCpuUsage: 0
487 | ps4PatchPkgPath:
488 | ps4PatchLatestPkgPath:
489 | ps4PatchChangeinfoPath:
490 | ps4PatchDayOne: 0
491 | ps4attribUserManagement: 0
492 | ps4attribMoveSupport: 0
493 | ps4attrib3DSupport: 0
494 | ps4attribShareSupport: 0
495 | ps4attribExclusiveVR: 0
496 | ps4disableAutoHideSplash: 0
497 | ps4videoRecordingFeaturesUsed: 0
498 | ps4contentSearchFeaturesUsed: 0
499 | ps4attribEyeToEyeDistanceSettingVR: 0
500 | ps4IncludedModules: []
501 | monoEnv:
502 | psp2Splashimage: {fileID: 0}
503 | psp2NPTrophyPackPath:
504 | psp2NPSupportGBMorGJP: 0
505 | psp2NPAgeRating: 12
506 | psp2NPTitleDatPath:
507 | psp2NPCommsID:
508 | psp2NPCommunicationsID:
509 | psp2NPCommsPassphrase:
510 | psp2NPCommsSig:
511 | psp2ParamSfxPath:
512 | psp2ManualPath:
513 | psp2LiveAreaGatePath:
514 | psp2LiveAreaBackroundPath:
515 | psp2LiveAreaPath:
516 | psp2LiveAreaTrialPath:
517 | psp2PatchChangeInfoPath:
518 | psp2PatchOriginalPackage:
519 | psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui
520 | psp2KeystoneFile:
521 | psp2MemoryExpansionMode: 0
522 | psp2DRMType: 0
523 | psp2StorageType: 0
524 | psp2MediaCapacity: 0
525 | psp2DLCConfigPath:
526 | psp2ThumbnailPath:
527 | psp2BackgroundPath:
528 | psp2SoundPath:
529 | psp2TrophyCommId:
530 | psp2TrophyPackagePath:
531 | psp2PackagedResourcesPath:
532 | psp2SaveDataQuota: 10240
533 | psp2ParentalLevel: 1
534 | psp2ShortTitle: Not Set
535 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF
536 | psp2Category: 0
537 | psp2MasterVersion: 01.00
538 | psp2AppVersion: 01.00
539 | psp2TVBootMode: 0
540 | psp2EnterButtonAssignment: 2
541 | psp2TVDisableEmu: 0
542 | psp2AllowTwitterDialog: 1
543 | psp2Upgradable: 0
544 | psp2HealthWarning: 0
545 | psp2UseLibLocation: 0
546 | psp2InfoBarOnStartup: 0
547 | psp2InfoBarColor: 0
548 | psp2ScriptOptimizationLevel: 0
549 | splashScreenBackgroundSourceLandscape: {fileID: 0}
550 | splashScreenBackgroundSourcePortrait: {fileID: 0}
551 | spritePackerPolicy:
552 | webGLMemorySize: 256
553 | webGLExceptionSupport: 1
554 | webGLNameFilesAsHashes: 0
555 | webGLDataCaching: 0
556 | webGLDebugSymbols: 0
557 | webGLEmscriptenArgs:
558 | webGLModulesDirectory:
559 | webGLTemplate: APPLICATION:Default
560 | webGLAnalyzeBuildSize: 0
561 | webGLUseEmbeddedResources: 0
562 | webGLCompressionFormat: 1
563 | webGLLinkerTarget: 0
564 | scriptingDefineSymbols:
565 | 1: UNITY_POST_PROCESSING_STACK_V2
566 | 4: UNITY_POST_PROCESSING_STACK_V2
567 | 7: UNITY_POST_PROCESSING_STACK_V2
568 | 13: UNITY_POST_PROCESSING_STACK_V2
569 | 17: UNITY_POST_PROCESSING_STACK_V2
570 | 18: UNITY_POST_PROCESSING_STACK_V2
571 | 19: UNITY_POST_PROCESSING_STACK_V2
572 | 21: UNITY_POST_PROCESSING_STACK_V2
573 | 23: UNITY_POST_PROCESSING_STACK_V2
574 | 24: UNITY_POST_PROCESSING_STACK_V2
575 | 25: UNITY_POST_PROCESSING_STACK_V2
576 | 26: UNITY_POST_PROCESSING_STACK_V2
577 | 27: UNITY_POST_PROCESSING_STACK_V2
578 | platformArchitecture: {}
579 | scriptingBackend: {}
580 | il2cppCompilerConfiguration: {}
581 | incrementalIl2cppBuild: {}
582 | allowUnsafeCode: 1
583 | additionalIl2CppArgs:
584 | scriptingRuntimeVersion: 1
585 | apiCompatibilityLevelPerPlatform:
586 | Standalone: 1
587 | m_RenderingPath: 1
588 | m_MobileRenderingPath: 1
589 | metroPackageName: Template_3D
590 | metroPackageVersion:
591 | metroCertificatePath:
592 | metroCertificatePassword:
593 | metroCertificateSubject:
594 | metroCertificateIssuer:
595 | metroCertificateNotAfter: 0000000000000000
596 | metroApplicationDescription: Template_3D
597 | wsaImages: {}
598 | metroTileShortName:
599 | metroCommandLineArgsFile:
600 | metroTileShowName: 0
601 | metroMediumTileShowName: 0
602 | metroLargeTileShowName: 0
603 | metroWideTileShowName: 0
604 | metroDefaultTileSize: 1
605 | metroTileForegroundText: 2
606 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
607 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628,
608 | a: 1}
609 | metroSplashScreenUseBackgroundColor: 0
610 | platformCapabilities: {}
611 | metroFTAName:
612 | metroFTAFileTypes: []
613 | metroProtocolName:
614 | metroCompilationOverrides: 1
615 | tizenProductDescription:
616 | tizenProductURL:
617 | tizenSigningProfileName:
618 | tizenGPSPermissions: 0
619 | tizenMicrophonePermissions: 0
620 | tizenDeploymentTarget:
621 | tizenDeploymentTargetType: -1
622 | tizenMinOSVersion: 1
623 | n3dsUseExtSaveData: 0
624 | n3dsCompressStaticMem: 1
625 | n3dsExtSaveDataNumber: 0x12345
626 | n3dsStackSize: 131072
627 | n3dsTargetPlatform: 2
628 | n3dsRegion: 7
629 | n3dsMediaSize: 0
630 | n3dsLogoStyle: 3
631 | n3dsTitle: GameName
632 | n3dsProductCode:
633 | n3dsApplicationId: 0xFF3FF
634 | XboxOneProductId:
635 | XboxOneUpdateKey:
636 | XboxOneSandboxId:
637 | XboxOneContentId:
638 | XboxOneTitleId:
639 | XboxOneSCId:
640 | XboxOneGameOsOverridePath:
641 | XboxOnePackagingOverridePath:
642 | XboxOneAppManifestOverridePath:
643 | XboxOnePackageEncryption: 0
644 | XboxOnePackageUpdateGranularity: 2
645 | XboxOneDescription:
646 | XboxOneLanguage:
647 | - enus
648 | XboxOneCapability: []
649 | XboxOneGameRating: {}
650 | XboxOneIsContentPackage: 0
651 | XboxOneEnableGPUVariability: 0
652 | XboxOneSockets: {}
653 | XboxOneSplashScreen: {fileID: 0}
654 | XboxOneAllowedProductIds: []
655 | XboxOnePersistentLocalStorageSize: 0
656 | XboxOneXTitleMemory: 8
657 | xboxOneScriptCompiler: 0
658 | vrEditorSettings:
659 | daydream:
660 | daydreamIconForeground: {fileID: 0}
661 | daydreamIconBackground: {fileID: 0}
662 | cloudServicesEnabled:
663 | Collab: 1
664 | UNet: 1
665 | facebookSdkVersion: 7.9.4
666 | apiCompatibilityLevel: 2
667 | cloudProjectId: db2e33cc-849c-4d1a-95ce-77620e527424
668 | projectName: Buckets AI
669 | organizationId: ot-interactive
670 | cloudEnabled: 0
671 | enableNativePlatformBackendsForNewInputSystem: 0
672 | disableOldInputManagerSupport: 0
673 |
--------------------------------------------------------------------------------
/ProjectSettings/ProjectVersion.txt:
--------------------------------------------------------------------------------
1 | m_EditorVersion: 2018.1.0f2
2 |
--------------------------------------------------------------------------------
/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!47 &1
4 | QualitySettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 5
7 | m_CurrentQuality: 4
8 | m_QualitySettings:
9 | - serializedVersion: 2
10 | name: Very Low
11 | pixelLightCount: 0
12 | shadows: 0
13 | shadowResolution: 0
14 | shadowProjection: 1
15 | shadowCascades: 1
16 | shadowDistance: 15
17 | shadowNearPlaneOffset: 3
18 | shadowCascade2Split: 0.33333334
19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
20 | shadowmaskMode: 0
21 | blendWeights: 1
22 | textureQuality: 1
23 | anisotropicTextures: 0
24 | antiAliasing: 0
25 | softParticles: 0
26 | softVegetation: 0
27 | realtimeReflectionProbes: 0
28 | billboardsFaceCameraPosition: 0
29 | vSyncCount: 0
30 | lodBias: 0.3
31 | maximumLODLevel: 0
32 | particleRaycastBudget: 4
33 | asyncUploadTimeSlice: 2
34 | asyncUploadBufferSize: 4
35 | resolutionScalingFixedDPIFactor: 1
36 | excludedTargetPlatforms: []
37 | - serializedVersion: 2
38 | name: Low
39 | pixelLightCount: 0
40 | shadows: 0
41 | shadowResolution: 0
42 | shadowProjection: 1
43 | shadowCascades: 1
44 | shadowDistance: 20
45 | shadowNearPlaneOffset: 3
46 | shadowCascade2Split: 0.33333334
47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
48 | shadowmaskMode: 0
49 | blendWeights: 2
50 | textureQuality: 0
51 | anisotropicTextures: 0
52 | antiAliasing: 0
53 | softParticles: 0
54 | softVegetation: 0
55 | realtimeReflectionProbes: 0
56 | billboardsFaceCameraPosition: 0
57 | vSyncCount: 0
58 | lodBias: 0.4
59 | maximumLODLevel: 0
60 | particleRaycastBudget: 16
61 | asyncUploadTimeSlice: 2
62 | asyncUploadBufferSize: 4
63 | resolutionScalingFixedDPIFactor: 1
64 | excludedTargetPlatforms: []
65 | - serializedVersion: 2
66 | name: Medium
67 | pixelLightCount: 1
68 | shadows: 1
69 | shadowResolution: 0
70 | shadowProjection: 1
71 | shadowCascades: 1
72 | shadowDistance: 20
73 | shadowNearPlaneOffset: 3
74 | shadowCascade2Split: 0.33333334
75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
76 | shadowmaskMode: 0
77 | blendWeights: 2
78 | textureQuality: 0
79 | anisotropicTextures: 1
80 | antiAliasing: 0
81 | softParticles: 0
82 | softVegetation: 0
83 | realtimeReflectionProbes: 0
84 | billboardsFaceCameraPosition: 0
85 | vSyncCount: 1
86 | lodBias: 0.7
87 | maximumLODLevel: 0
88 | particleRaycastBudget: 64
89 | asyncUploadTimeSlice: 2
90 | asyncUploadBufferSize: 4
91 | resolutionScalingFixedDPIFactor: 1
92 | excludedTargetPlatforms: []
93 | - serializedVersion: 2
94 | name: High
95 | pixelLightCount: 2
96 | shadows: 2
97 | shadowResolution: 1
98 | shadowProjection: 1
99 | shadowCascades: 2
100 | shadowDistance: 40
101 | shadowNearPlaneOffset: 3
102 | shadowCascade2Split: 0.33333334
103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
104 | shadowmaskMode: 1
105 | blendWeights: 2
106 | textureQuality: 0
107 | anisotropicTextures: 1
108 | antiAliasing: 2
109 | softParticles: 0
110 | softVegetation: 1
111 | realtimeReflectionProbes: 1
112 | billboardsFaceCameraPosition: 1
113 | vSyncCount: 1
114 | lodBias: 1
115 | maximumLODLevel: 0
116 | particleRaycastBudget: 256
117 | asyncUploadTimeSlice: 2
118 | asyncUploadBufferSize: 4
119 | resolutionScalingFixedDPIFactor: 1
120 | excludedTargetPlatforms: []
121 | - serializedVersion: 2
122 | name: Very High
123 | pixelLightCount: 3
124 | shadows: 2
125 | shadowResolution: 2
126 | shadowProjection: 1
127 | shadowCascades: 2
128 | shadowDistance: 40
129 | shadowNearPlaneOffset: 3
130 | shadowCascade2Split: 0.33333334
131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
132 | shadowmaskMode: 1
133 | blendWeights: 4
134 | textureQuality: 0
135 | anisotropicTextures: 1
136 | antiAliasing: 4
137 | softParticles: 1
138 | softVegetation: 1
139 | realtimeReflectionProbes: 1
140 | billboardsFaceCameraPosition: 1
141 | vSyncCount: 0
142 | lodBias: 1.5
143 | maximumLODLevel: 0
144 | particleRaycastBudget: 1024
145 | asyncUploadTimeSlice: 2
146 | asyncUploadBufferSize: 4
147 | resolutionScalingFixedDPIFactor: 1
148 | excludedTargetPlatforms: []
149 | - serializedVersion: 2
150 | name: Ultra
151 | pixelLightCount: 4
152 | shadows: 2
153 | shadowResolution: 2
154 | shadowProjection: 1
155 | shadowCascades: 4
156 | shadowDistance: 150
157 | shadowNearPlaneOffset: 3
158 | shadowCascade2Split: 0.33333334
159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
160 | shadowmaskMode: 1
161 | blendWeights: 4
162 | textureQuality: 0
163 | anisotropicTextures: 1
164 | antiAliasing: 4
165 | softParticles: 1
166 | softVegetation: 1
167 | realtimeReflectionProbes: 1
168 | billboardsFaceCameraPosition: 1
169 | vSyncCount: 1
170 | lodBias: 2
171 | maximumLODLevel: 0
172 | particleRaycastBudget: 4096
173 | asyncUploadTimeSlice: 2
174 | asyncUploadBufferSize: 4
175 | resolutionScalingFixedDPIFactor: 1
176 | excludedTargetPlatforms: []
177 | m_PerPlatformDefaultQuality:
178 | Android: 2
179 | Nintendo 3DS: 5
180 | Nintendo Switch: 5
181 | PS4: 5
182 | PSP2: 2
183 | Standalone: 5
184 | Tizen: 2
185 | WebGL: 3
186 | WiiU: 5
187 | Windows Store Apps: 5
188 | XboxOne: 5
189 | iPhone: 2
190 | tvOS: 2
191 |
--------------------------------------------------------------------------------
/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!78 &1
4 | TagManager:
5 | serializedVersion: 2
6 | tags: []
7 | layers:
8 | - Default
9 | - TransparentFX
10 | - Ignore Raycast
11 | -
12 | - Water
13 | - UI
14 | -
15 | -
16 | - PostProcessing
17 | -
18 | -
19 | -
20 | -
21 | -
22 | -
23 | -
24 | -
25 | -
26 | -
27 | -
28 | -
29 | -
30 | -
31 | -
32 | -
33 | -
34 | -
35 | -
36 | -
37 | -
38 | -
39 | -
40 | m_SortingLayers:
41 | - name: Default
42 | uniqueID: 0
43 | locked: 0
44 |
--------------------------------------------------------------------------------
/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!5 &1
4 | TimeManager:
5 | m_ObjectHideFlags: 0
6 | Fixed Timestep: 0.0167
7 | Maximum Allowed Timestep: 0.1
8 | m_TimeScale: 1
9 | Maximum Particle Timestep: 0.03
10 |
--------------------------------------------------------------------------------
/ProjectSettings/UnityConnectSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!310 &1
4 | UnityConnectSettings:
5 | m_ObjectHideFlags: 0
6 | m_Enabled: 0
7 | m_TestMode: 0
8 | m_TestEventUrl:
9 | m_TestConfigUrl:
10 | m_TestInitMode: 0
11 | CrashReportingSettings:
12 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes
13 | m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate
14 | m_Enabled: 0
15 | m_CaptureEditorExceptions: 1
16 | UnityPurchasingSettings:
17 | m_Enabled: 0
18 | m_TestMode: 0
19 | UnityAnalyticsSettings:
20 | m_Enabled: 1
21 | m_InitializeOnStartup: 1
22 | m_TestMode: 0
23 | m_TestEventUrl:
24 | m_TestConfigUrl:
25 | UnityAdsSettings:
26 | m_Enabled: 0
27 | m_InitializeOnStartup: 1
28 | m_TestMode: 0
29 | m_IosGameId:
30 | m_AndroidGameId:
31 | m_GameIds: {}
32 | m_GameId:
33 | PerformanceReportingSettings:
34 | m_Enabled: 0
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DynamicObjectTracking
2 |
3 | A multithreaded implementation of [Nition's Octree for Unity](https://github.com/Nition/UnityOctree) allowing for discriminatory
4 | object tracking with large numbers of moving GameObjects.
5 |
6 | Use of the point Octree system is comparable to using trigger colliders with hard coded switch or if else statements, however the objects tracked and
7 | the information receivers are easily selected at your discretion (no more sifting through enormous amounts of collider data). This
8 | is also a viable option for collision detection if you wish to escape PhysX (and spherical colliders can meet your needs). The primary benefit
9 | is getting optimized spatial calculations without interfering with anything you (or perhaps your users) are doing with trigger colliders.
10 |
11 | Any number of agents can track up to 701 classes / fields of objects (a thru zz), and *each field may contain any number of tracked objects*.
12 | Although 701 different fields of tracked objects is likely beyond any need - additional fields can be added at runtime (see public methods).
13 |
14 | Every field has its own distance threshold value defining when it registers other tracked objects. Once another tracked object registers,
15 | an event is published to the subscribers (typically an agent or a game manager) monitoring that object. The event publishes the registered
16 | GameObjects inside the threshold (GameObject[]) and their associated object field types (string[] "a","b","c"...).
17 |
18 | Additionally, this package can be configured to forego Octree implementation and simply automate Unity's Collider trigger configuration across your
19 | selected fields of tracked objects. Both the Octree and Trigger configurations produce the same discriminatory data - reported the same way - to
20 | monitoring agents. You can easily benchmark the two against each other. Choosing to have this system automate trigger configurations for you will
21 | obviously negate any benefits afforded by using the Octree implementation.
22 |
23 | 20k Tracked Objects - colliding *only* with objects with that are different in color - using *no colliders or rigidbodies.*
24 |
25 |
26 |
27 | The above scene uses a collision method that simply sets object direction to it's position minus the colliding objects position. Object scales are set to
28 | match their *threshold* size. This scene averaged 20 fps on a 15" Surfacebook. When scene sizes get this large, collision detection loses accuracy,
29 | but crucially - the main thread remains unblocked (unless you choose the Unity Trigger implementation).
30 |
31 | # Getting Started
32 |
33 | **The Empty WorldMonitors Component**
34 |
35 |
36 |
37 |
38 | To start tracking, add a WorldMonitors component as shown above. This component is added to every "tracker" - i.e. a GameObject that will track
39 | the movement of a selected group of GameObjects. The + button will open up the *Tracked Field*, where you can add tracked objects. Add at least
40 | one more *Tracked Field* (in any instance of WorldMonitors) where the tracked objects will raise conflict with objects in other *Tracked Fields*.
41 |
42 | Any number of WorldMonitors can be used. If multiple instances of WorldMonitors will be tracking the same object, that object must appear under
43 | the same field for every instance of WorldMonitors tracking it. See how PinkSphere (1) appears in the following (separate) instances of
44 | WorldMonitors - it is under "Set B" for each instance. The order of objects in Set B can be different for each WorldMonitors instance. Also note
45 | that the threshold sizes are the same for each field; this is enforced by the custom inspector code every time a value is changed so you won't
46 | need to check across all instances of WorldMonitors for continuity.
47 |
48 | **Multiple WorldMonitors Instances - Use Symmetrical Fields**
49 |
50 |
51 |
52 |
53 |
54 | **The WorldMonitor Component - Singleton**
55 |
56 |
57 |
58 |
59 | If you do not add this component it will be created for you, however you should make a sincere effort to set the parameters beforehand.
60 | Failing to do so can result in an unnecessarily large Octree which can consume resources. Place it on any GameObject you'd like.
61 |
62 | This system will *never* use more than one auxilliary thread. If you wish, you may restrict the object tracking to the main thread
63 | at the expense of performance.
64 |
65 | The exhaustive calculation is intended for benchmarking - however if you are using a very small number of tracked objects, exhaustive calculations
66 | may be faster for your use case. This method raises the conflict event every frame, as such it's functionality is similar to OnTriggerStay(). It
67 | is of no value if you choose to implement the system's automated Unity Trigger configuration.
68 |
69 | # Events
70 |
71 | *All events use the ObjectConflictHandler delegate*
72 | > delegate void ObjectConflictHandler(GameObject objectWithConflict, GameObject[] conflictingObjects, string[] conflictingTypes);
73 |
74 | * **GameObject objectWithConflict:** this is the object who's threshold has been crossed
75 | * **GameObject[] conflictingObjects:** an array of the objects who've crossed into the threshold
76 | * **string[] conflictingTypes:** an array of the object field names (e.g. "A", "B", "C" etc)
77 |
78 | It is possible for more than one object to cross thresholds during an Update cycle, as such the latter two arguments are arrays.
79 |
80 | > ConflictEnterers(GameObject objectWithConflict, GameObject[] conflictingObjects, string[] conflictingTypes)
81 |
82 | Subscribe to this event for notification every time a tracked object enters another's threshold.
83 |
84 | > ConflictLeavers(GameObject objectWithConflict, GameObject[] conflictingObjects, string[] conflictingTypes)
85 | > ConflictEnd(GameObject objectWithConflict, GameObject[] conflictingObjects, string[] conflictingTypes)
86 |
87 | These two events are mutually exclusive; subcribe to ConflictLeavers if you need an update every time an object leaves another's threshold area.
88 | ConflictEnd is only emitted when *all* tracked objects have vacated a threshold area.
89 |
90 | # Public Methods
91 | > void ChangeThresholdSize(float threshold, GameObject trackedObject, string objectType)
92 |
93 | * **float threshold** the new threshold size you wish to set.
94 | * **GameObject trackedObject** *(Optional)* the particular tracked object whos threshold you wish to change.
95 | * **string objectType** *(Optional)* the field name of the threshold you'd like to change
96 |
97 | *Remarks: you must include at least one of the optional arguments - - both options change the threshold size for an entire field, not individual objects.
98 | If you are using the trigger implementation, use the public ChangeTriggerSize() method instead.*
99 |
100 | > void InsertNewTrackedObject(GameObject trackedObject, WorldMonitors owner, string objectAffiliation, float threshold)
101 |
102 | * **GameObject trackedObject:** the object to be tracked.
103 | * **WorldMonitors owner:** the WorldMonitors component for the tracker tracking this object.
104 | * **string objectAffiliation** the type (field name) for this object. This can be anything -- here is where you can expand on the 701 field limit.
105 | * **float threshold:** the new threshold size you wish to set.
106 |
107 | *Remarks: see the example scenes for demonstration of usage.*
108 |
109 | > void RemoveTrackedObject(GameObject trackedObject, WorldMonitors whoToRemove, bool retainOtherTrackers)
110 |
111 | * **GameObject trackedObject:** the tracked object to be removed.
112 | * **WorldMonitors whoToRemove:** *(Optional)* you can remove individual trackers from tracked objects as they can be tracked by any number of agents
113 | * **bool retainOtherTrackers:** *(Optional)* set this argument true if you wish to remove only aspecified tracking agent.
114 |
115 | *Remarks: you should always remove the WorldMonitors owner when an agent is destroyed, or at the minimum unsubscribe from the events. see the example scenes for demonstration of usage.*
116 |
117 | **Tracker - an Example Object Tracker**
118 |
119 |
120 |
121 |
122 | You will find the Tracker class in the example scenes, which demonstrates how to use all of the public methods except for ChangeThresholdSize().
123 | The last Tracking Agent in the heirarchy (in both scenes) is preconfigured to use some of the options.
124 |
125 | ## ** Scenes **
126 | # TrackingExample
127 |
128 |
129 | TrackingExample demonstrates the system's large scale dynamic object tracking ability, and an example method is used to change the tracked object's
130 | trajectories when conflicts are incurred by one enabled object (you can enable this behavior in the Tracker inspector). This scene includes
131 | 500 initial tracked objects and inflates to 5,000 at runtime. All of these object's are configured to interact with thresholds beyond their size (like a trigger).
132 | On a SurfaceBook (i7, GTX 1060), this scene runs at 45 fps with the tracking system updating once 1-2 times per 10 frames (note the tracking refresh
133 | rate on smaller scenes is about once/ frame).
134 |
135 | # SmallTrackingExample
136 |
137 |
138 | This scene is preconfigured to log events to the console so you can quickly understand how and what data is published.
139 |
140 | # Important Points
141 |
142 | If you may be switching between the Octree and Trigger tracking methods, you should be aware of how the threshold and trigger radius differ.
143 | They are both a measure of the same thing (a spherical radius) however triggers emit collisions when the triggers cross each other's boundaries,
144 | not when the parent object crosses the boundary. **You can configure the WorldMonitor component to have triggers immitate the Octree behavior
145 | or visa-versa.** The difference between the two methods without configuring the WorldMonitor to immitate behaviors is shown below.
146 |
147 |
148 |
--------------------------------------------------------------------------------
/THIRD_PARTY_NOTICES.md:
--------------------------------------------------------------------------------
1 | OTI (Overtime Interactive) Dynamic Object Tracking uses third-party libraries or other resources that may
2 | be distributed under licenses different than the OTI software.
3 | The original copyright notice and the license at the time of incorporation of
4 | such third party material are set forth below.
5 |
6 | In the event that we accidentally failed to list a required notice, please
7 | bring it to our attention through opening a new issue on the GitHub repo here:
8 |
9 | https://github.com/phatboysh/DynamicObjectTracking/issues
10 |
11 | -------------------------------------------------------------------------------
12 |
13 | UnityOctree
14 | https://github.com/Nition/UnityOctree
15 |
16 | This work is included in DynamicObjectTracking/Assets/UnityOctree
17 |
18 | and accessed from OTI files:
19 | DynamicObjectTracking/Assets/Octree/Octree.cs
20 |
21 | ---
22 | Copyright (c) 2014, Nition
23 |
24 | All rights reserved.
25 |
26 |
27 |
28 | Redistribution and use in source and binary forms, with or without
29 | modification,
30 | are permitted provided that the following conditions are met:
31 |
32 |
33 |
34 | * Redistributions of source code must retain the above copyright notice, this
35 | list of conditions and the following disclaimer.
36 |
37 |
38 |
39 | * Redistributions in binary form must reproduce the above copyright notice,
40 | this list of conditions and the following disclaimer
41 | in the documentation
42 | and/or other materials provided with the distribution.
43 |
44 |
45 |
46 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
47 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
48 | BUT NOT LIMITED TO, THE
49 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50 | DISCLAIMED. IN NO EVENT
51 | SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
52 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 |
54 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
55 | SERVICES; LOSS OF USE, DATA, OR PROFITS;
56 | OR BUSINESS INTERRUPTION) HOWEVER
57 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
58 |
59 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 | OF THIS SOFTWARE, EVEN IF ADVISED OF
61 | THE POSSIBILITY OF SUCH DAMAGE.
62 |
63 | -------------------------------------------------------------------------------
64 |
--------------------------------------------------------------------------------