├── .gitignore ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── CONTRIBUTING.md ├── CONTRIBUTING.md.meta ├── Documentation~ └── Inspector.png ├── Editor.meta ├── Editor ├── Unity.ZombieObjectDetector.Editor.asmdef ├── Unity.ZombieObjectDetector.Editor.asmdef.meta ├── ZombieObjectDetectorEditor.cs └── ZombieObjectDetectorEditor.cs.meta ├── LICENSE.md ├── LICENSE.md.meta ├── OldExample~ ├── MultipleSceneCycleLoader.cs ├── MultipleSceneCycleLoader.cs.meta ├── SceneLoader.cs ├── SceneLoader.cs.meta ├── Scenes.meta ├── Scenes │ ├── Boot.unity │ ├── Boot.unity.meta │ ├── Empty.unity │ ├── Empty.unity.meta │ ├── Reset.unity │ ├── Reset.unity.meta │ ├── Test.unity │ └── Test.unity.meta ├── TestScripts.meta ├── TestScripts │ ├── Arrays.meta │ ├── Arrays │ │ ├── BasicStaticObjectStack.cs │ │ ├── BasicStaticObjectStack.cs.meta │ │ ├── ObjectAttachedToArray.cs │ │ ├── ObjectAttachedToArray.cs.meta │ │ ├── ObjectAttachedToDictionary.cs │ │ ├── ObjectAttachedToDictionary.cs.meta │ │ ├── ObjectAttachedToList.cs │ │ ├── ObjectAttachedToList.cs.meta │ │ ├── ObjectAttachedToStack.cs │ │ ├── ObjectAttachedToStack.cs.meta │ │ ├── StaticArray.cs │ │ ├── StaticArray.cs.meta │ │ ├── StaticObjectList.cs │ │ ├── StaticObjectList.cs.meta │ │ ├── StaticObjectStack.cs │ │ ├── StaticObjectStack.cs.meta │ │ ├── StaticStringObjectDictionary.cs │ │ └── StaticStringObjectDictionary.cs.meta │ ├── BasedOnIgnoredTypeParam.cs │ ├── BasedOnIgnoredTypeParam.cs.meta │ ├── ClearKnownZombies.cs │ ├── ClearKnownZombies.cs.meta │ ├── EdgeCases.meta │ ├── EdgeCases │ │ ├── BadEqualsImplementation.cs │ │ ├── BadEqualsImplementation.cs.meta │ │ ├── FalsePositive.cs │ │ ├── FalsePositive.cs.meta │ │ ├── IgnoredTypeParam.cs │ │ ├── IgnoredTypeParam.cs.meta │ │ ├── UnsafePointer.cs │ │ └── UnsafePointer.cs.meta │ ├── Events.meta │ ├── Events │ │ ├── EventListener.cs │ │ ├── EventListener.cs.meta │ │ ├── LambdaEventListener.cs │ │ ├── LambdaEventListener.cs.meta │ │ ├── StaticEvents.cs │ │ └── StaticEvents.cs.meta │ ├── References.meta │ ├── References │ │ ├── ObjectAttachedToReference.cs │ │ ├── ObjectAttachedToReference.cs.meta │ │ ├── ReferenceHolder.cs │ │ ├── ReferenceHolder.cs.meta │ │ ├── ReferenceHolderHolder.cs │ │ └── ReferenceHolderHolder.cs.meta │ ├── SerializedClass.meta │ └── SerializedClass │ │ ├── SerializedClass.cs │ │ ├── SerializedClass.cs.meta │ │ ├── SerializedClassAddToHolder.cs │ │ ├── SerializedClassAddToHolder.cs.meta │ │ ├── SerializedClassHolder.cs │ │ └── SerializedClassHolder.cs.meta ├── ZombieSceneLoader.cs └── ZombieSceneLoader.cs.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── TypeHelper.cs ├── TypeHelper.cs.meta ├── Unity.ZombieObjectDetector.Runtime.asmdef ├── Unity.ZombieObjectDetector.Runtime.asmdef.meta ├── ZombieObjectDetector.cs ├── ZombieObjectDetector.cs.meta ├── ZombieObjectDetector_Report_TTY.cs └── ZombieObjectDetector_Report_TTY.cs.meta ├── package.json └── package.json.meta /.gitignore: -------------------------------------------------------------------------------- 1 | # Unity generated 2 | /[Ll]ibrary/ 3 | /[Tt]emp/ 4 | /[Oo]bj/ 5 | /[Bb]uild/ 6 | /[Bb]uilds/ 7 | /[Pp]ackages/ 8 | /.[Vv][Ss][Cc]ode/ 9 | /.[Vv][Ss]/ 10 | /UnityPackageManager 11 | /Assets/.ZombieLogs/ 12 | 13 | # Autogenerated VS/MD solution and project files 14 | ExportedObj/ 15 | .consulo/ 16 | *.csproj 17 | *.unityproj 18 | *.sln 19 | *.suo 20 | *.tmp 21 | *.user 22 | *.userprefs 23 | *.pidb 24 | *.booproj 25 | *.svd 26 | 27 | # Unity3D generated meta files 28 | *.pidb.meta 29 | 30 | # Unity3D Generated File On Crash Reports 31 | sysinfo.txt 32 | 33 | # Builds 34 | *.apk 35 | *.unitypackage 36 | 37 | # Mac stuff 38 | .DS_Store 39 | .bak 40 | .BAK 41 | \.leu 42 | 43 | RegisterIcalls\.cpp 44 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## 0.4.2 - 2022-02-22 3 | ### Changed 4 | - Improved documentation (README.md) 5 | 6 | ## 0.4.1 - 2021-08-19 7 | ### Fixed 8 | - Empty (or otherwise invalid) regexes in the inspector no longer cause exceptions. 9 | 10 | ### Added 11 | - Checkboxes for ZombieObjectDetector_Report_TTY, to say what to report. 12 | 13 | ## 0.4.0 - 2021-08-17 14 | ### Added 15 | - More callbacks to the `SearchContext` type. 16 | - A checkbox to specify that the detector should run on its `Start` call. 17 | - User can specify types (using regexes) that will be ignored if encountered during the search. This is in addition to the existing fields which specified the types from which to *start* the search. 18 | - This changelog. 19 | 20 | 21 | -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa2fb4f2761c82843a8b321182cc81f3 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributions 2 | 3 | ## If you are interested in contributing, here are some ground rules: 4 | * Let us know about it before committing effort. We may have relevant ideas and opinions, or there might be work-in-progress already that you can help with. 5 | * Follow naming & style conventions in the project 6 | 7 | ## All contributions are subject to the [Unity Contribution Agreement(UCA)](https://unity3d.com/legal/licenses/Unity_Contribution_Agreement) 8 | By making a pull request, you are confirming agreement to the terms and conditions of the UCA, including that your Contributions are your original creation and that you have complete right and authority to make your Contributions. 9 | 10 | ## Once you have a change ready following these ground rules. Simply make a pull request in Github 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b24d50d11bcad247ba2e61a9c99e549 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Documentation~/Inspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Unity-Technologies/ZombieObjectDetector/d7abe96f989375af2400e6058db0ff6bab9ec608/Documentation~/Inspector.png -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fdb36f8687e7a1447a42bf7629a8b8f3 3 | folderAsset: yes 4 | timeCreated: 1506949416 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/Unity.ZombieObjectDetector.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Unity.ZombieObjectDetector.Editor", 3 | "references": [ 4 | "GUID:5adcca6eb4c13094e98ff197186a0ca6" 5 | ], 6 | "includePlatforms": [ 7 | "Editor" 8 | ], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": false, 12 | "precompiledReferences": [], 13 | "autoReferenced": true, 14 | "defineConstraints": [], 15 | "versionDefines": [], 16 | "noEngineReferences": false 17 | } -------------------------------------------------------------------------------- /Editor/Unity.ZombieObjectDetector.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0e46b9c68638014abba2adc671112b1 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/ZombieObjectDetectorEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text.RegularExpressions; 7 | 8 | namespace CSharpZombieDetector 9 | { 10 | 11 | [CustomEditor(typeof(ZombieObjectDetector))] 12 | public class ZombieObjectDetectorEditor : Editor 13 | { 14 | 15 | // Repeated code of a list of regexes. 16 | class RegexListEditor 17 | { 18 | private bool m_show; 19 | 20 | private string m_title; 21 | private string m_propName; 22 | private string[] m_defaults; 23 | 24 | private string m_doodle; 25 | private string m_testResult = ""; 26 | 27 | public RegexListEditor(string propName, string title, IEnumerable defaults) 28 | { 29 | m_propName = propName; 30 | m_title = title; 31 | m_defaults = defaults.ToArray(); 32 | } 33 | 34 | public void Draw(SerializedObject serializedObject) 35 | { 36 | serializedObject.ApplyModifiedProperties(); // So that we can detect OUR OWN changes later on. 37 | SerializedProperty prop = serializedObject.FindProperty(m_propName); 38 | bool reset = false; 39 | using (new GUILayout.HorizontalScope()) 40 | { 41 | m_show = EditorGUILayout.Foldout(m_show, m_title); 42 | reset |= GUILayout.Button("Reset", GUILayout.ExpandWidth(false)); 43 | } 44 | 45 | // Reset logic. 46 | if (reset) 47 | { 48 | prop.arraySize = m_defaults.Length; 49 | for (int i = 0; i < m_defaults.Length; ++i) 50 | prop.GetArrayElementAtIndex(i).stringValue = m_defaults[i]; 51 | } 52 | 53 | // Show values when folded-out. 54 | if (m_show) 55 | { 56 | using (new EditorGUI.IndentLevelScope()) 57 | { 58 | EditorGUILayout.PropertyField(prop, new GUIContent("Values")); 59 | DrawTestField(prop); 60 | } 61 | } 62 | 63 | serializedObject.ApplyModifiedProperties(); 64 | } 65 | 66 | private void DrawTestField(SerializedProperty prop) 67 | { 68 | var thin = GUILayout.ExpandWidth(false); 69 | var fat = GUILayout.ExpandWidth(true); 70 | using (new EditorGUILayout.HorizontalScope(fat)) 71 | { 72 | string prev = m_doodle; 73 | m_doodle = EditorGUILayout.TextField("Test:", m_doodle, fat); 74 | 75 | bool change = (m_doodle != prev) || prop.serializedObject.hasModifiedProperties; 76 | if (change) 77 | RecalculateTestResult(prop); 78 | 79 | EditorGUILayout.LabelField(m_testResult, thin); 80 | } 81 | } 82 | 83 | private void RecalculateTestResult(SerializedProperty prop) 84 | { 85 | IEnumerable regexes = 86 | Enumerable.Range(0, prop.arraySize) 87 | .Select(i => prop.GetArrayElementAtIndex(i).stringValue) 88 | .Select(s => new Regex(s)) 89 | .Where(r => r != null); 90 | bool match = regexes.Any(r => r.IsMatch(m_doodle)); 91 | m_testResult = match ? "Match" : "Not a match"; 92 | } 93 | } 94 | 95 | 96 | 97 | 98 | private RegexListEditor m_ignoreAssemblies, m_ignoreTypes, m_ignoreTypesDuringSearch; 99 | 100 | private void Awake() 101 | { 102 | m_ignoreAssemblies = new RegexListEditor( 103 | "m_ignoreAssemblyPatterns", 104 | "Do not start from these Assemblies (Regex)", 105 | ZombieObjectDetector.DefaultAssemblyIgnorePatterns); 106 | 107 | m_ignoreTypes = new RegexListEditor( 108 | "m_ignoreTypePatterns", 109 | "Do not start from these Types (Regex)", 110 | ZombieObjectDetector.DefaultIgnoreTypePatterns); 111 | 112 | m_ignoreTypesDuringSearch = new RegexListEditor( 113 | "m_ignoreTypePatternsDuringSearch", 114 | "Do not recurse into these Types during search (Regex)", 115 | new string[] { }); // Default is empty string[] 116 | } 117 | 118 | 119 | 120 | 121 | public override void OnInspectorGUI() 122 | { 123 | EditorGUILayout.PropertyField(serializedObject.FindProperty("m_runOnStart")); 124 | 125 | m_ignoreAssemblies.Draw(serializedObject); 126 | m_ignoreTypes.Draw(serializedObject); 127 | m_ignoreTypesDuringSearch.Draw(serializedObject); 128 | DrawDetectionButton(); 129 | } 130 | 131 | 132 | 133 | private bool m_showSearchTypeIgnores = false; 134 | 135 | private void DrawIgnoredTypesDuringSearch() 136 | { 137 | DrawRegexList( 138 | "m_ignoreTypePatternsDuringSearch", 139 | "Do not recurse into these Types during search (Regex)", 140 | ref m_showSearchTypeIgnores, 141 | new string[] { }); // Default is empty string[] 142 | } 143 | 144 | private void DrawRegexList( 145 | string propName, 146 | string name, 147 | ref bool show, 148 | string[] defaults) 149 | { 150 | 151 | SerializedProperty prop = serializedObject.FindProperty(propName); 152 | bool reset = false; 153 | using (new GUILayout.HorizontalScope()) 154 | { 155 | show = EditorGUILayout.Foldout(show, name); 156 | reset |= GUILayout.Button("Reset", GUILayout.ExpandWidth(false)); 157 | } 158 | if (show) 159 | { 160 | using (new EditorGUI.IndentLevelScope()) 161 | { 162 | EditorGUILayout.PropertyField(prop, new GUIContent("Values")); 163 | } 164 | } 165 | if (reset) 166 | { 167 | prop.arraySize = defaults.Length; 168 | for (int i = 0; i < defaults.Length; ++i) 169 | prop.GetArrayElementAtIndex(i).stringValue = defaults[i]; 170 | } 171 | } 172 | 173 | 174 | // Allows the user to trigger detection straight from the inspector. 175 | private void DrawDetectionButton() 176 | { 177 | var zod = target as ZombieObjectDetector; 178 | bool enabled = Application.isPlaying; 179 | using (new EditorGUI.DisabledGroupScope(!enabled)) 180 | { 181 | if (enabled) 182 | { 183 | if (GUILayout.Button("Log Zombies")) 184 | { 185 | zod.RunZombieObjectDetection(); 186 | } 187 | } 188 | else 189 | { 190 | GUILayout.Button("Log Zombies (Available during Play)"); 191 | } 192 | } 193 | } 194 | } 195 | 196 | 197 | 198 | } 199 | -------------------------------------------------------------------------------- /Editor/ZombieObjectDetectorEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f808a17436845494c96bc7fe49ce6939 3 | timeCreated: 1507649157 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2018 Unity Technologies ApS 2 | 3 | Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](https://unity3d.com/legal/licenses/Unity_Companion_License). 4 | 5 | Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions. 6 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1c3e63707858a3c44b6aef28a30108f9 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /OldExample~/MultipleSceneCycleLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.SceneManagement; 5 | using UnityEngine.UI; 6 | 7 | public class MultipleSceneCycleLoader : MonoBehaviour 8 | { 9 | 10 | [SerializeField] 11 | string m_SceneToLoadAndUnload = ""; 12 | 13 | [SerializeField] 14 | int m_NumberOfTimesToLoadAndUnload = 100000; 15 | [SerializeField] 16 | Button m_Button; 17 | [SerializeField] 18 | Text m_ButtonText; 19 | 20 | private bool m_IsCycling = false; 21 | 22 | private void Start() 23 | { 24 | m_ButtonText.text = string.Format("Load and Unload {0} {1} times", m_SceneToLoadAndUnload, m_NumberOfTimesToLoadAndUnload); 25 | m_Button.onClick.AddListener(StartSceneCycling); 26 | } 27 | 28 | private void OnDestroy() 29 | { 30 | m_Button.onClick.RemoveAllListeners(); 31 | } 32 | 33 | private void OnGUI() 34 | { 35 | if (m_IsCycling) 36 | { 37 | GUI.Box(new Rect(0, 0, Screen.width, Screen.height), "Logging Zombie Objects!"); 38 | } 39 | } 40 | 41 | private void StartSceneCycling() 42 | { 43 | StartCoroutine(LoadUnloadScenes()); 44 | } 45 | 46 | private IEnumerator LoadUnloadScenes() 47 | { 48 | m_IsCycling = true; 49 | m_Button.interactable = false; 50 | 51 | for (int i = m_NumberOfTimesToLoadAndUnload; i > 0; i--) 52 | { 53 | m_ButtonText.text = string.Format("{0} Loads Remaining", i); 54 | 55 | yield return SceneManager.LoadSceneAsync(m_SceneToLoadAndUnload, LoadSceneMode.Additive); 56 | 57 | yield return SceneManager.UnloadSceneAsync(m_SceneToLoadAndUnload); 58 | 59 | } 60 | 61 | yield return Resources.UnloadUnusedAssets(); 62 | 63 | m_ButtonText.text = string.Format("Load and Unload {0} {1} times", m_SceneToLoadAndUnload, m_NumberOfTimesToLoadAndUnload); 64 | m_Button.interactable = true; 65 | m_IsCycling = false; 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /OldExample~/MultipleSceneCycleLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0155af832a8ec4fa497dfefd7d4a3257 3 | timeCreated: 1515785098 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/SceneLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.SceneManagement; 5 | using UnityEngine.UI; 6 | 7 | public class SceneLoader : MonoBehaviour { 8 | 9 | [SerializeField] 10 | string m_resetScene = "Reset"; 11 | 12 | [SerializeField] 13 | Button m_Button; 14 | 15 | private void Start() 16 | { 17 | m_Button.onClick.AddListener(LoadScene); 18 | } 19 | 20 | private void OnDestroy() 21 | { 22 | m_Button.onClick.RemoveAllListeners(); 23 | } 24 | 25 | private void LoadScene() 26 | { 27 | SceneManager.LoadScene(m_resetScene); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /OldExample~/SceneLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5bd415b5e94aed429567b10cdbe58a3 3 | timeCreated: 1510933653 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc04457b0466d7d43ae7d7ccb162e0f6 3 | folderAsset: yes 4 | timeCreated: 1507813038 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /OldExample~/Scenes/Boot.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 8 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.4465934, g: 0.49642956, b: 0.5748249, a: 1} 42 | --- !u!157 &3 43 | LightmapSettings: 44 | m_ObjectHideFlags: 0 45 | serializedVersion: 11 46 | m_GIWorkflowMode: 0 47 | m_GISettings: 48 | serializedVersion: 2 49 | m_BounceScale: 1 50 | m_IndirectOutputScale: 1 51 | m_AlbedoBoost: 1 52 | m_TemporalCoherenceThreshold: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 1 56 | m_LightmapEditorSettings: 57 | serializedVersion: 9 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_TextureWidth: 1024 61 | m_TextureHeight: 1024 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 1 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 0 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_LightingDataAsset: {fileID: 0} 92 | m_UseShadowmask: 0 93 | --- !u!196 &4 94 | NavMeshSettings: 95 | serializedVersion: 2 96 | m_ObjectHideFlags: 0 97 | m_BuildSettings: 98 | serializedVersion: 2 99 | agentTypeID: 0 100 | agentRadius: 0.5 101 | agentHeight: 2 102 | agentSlope: 45 103 | agentClimb: 0.4 104 | ledgeDropHeight: 0 105 | maxJumpAcrossDistance: 0 106 | minRegionArea: 2 107 | manualCellSize: 0 108 | cellSize: 0.16666667 109 | manualTileSize: 0 110 | tileSize: 256 111 | accuratePlacement: 0 112 | m_NavMeshData: {fileID: 0} 113 | --- !u!1 &247881377 114 | GameObject: 115 | m_ObjectHideFlags: 0 116 | m_PrefabParentObject: {fileID: 0} 117 | m_PrefabInternal: {fileID: 0} 118 | serializedVersion: 5 119 | m_Component: 120 | - component: {fileID: 247881378} 121 | - component: {fileID: 247881381} 122 | - component: {fileID: 247881380} 123 | - component: {fileID: 247881379} 124 | - component: {fileID: 247881382} 125 | m_Layer: 5 126 | m_Name: ResetButton 127 | m_TagString: Untagged 128 | m_Icon: {fileID: 0} 129 | m_NavMeshLayer: 0 130 | m_StaticEditorFlags: 0 131 | m_IsActive: 1 132 | --- !u!224 &247881378 133 | RectTransform: 134 | m_ObjectHideFlags: 0 135 | m_PrefabParentObject: {fileID: 0} 136 | m_PrefabInternal: {fileID: 0} 137 | m_GameObject: {fileID: 247881377} 138 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 139 | m_LocalPosition: {x: 0, y: 0, z: 0} 140 | m_LocalScale: {x: 1, y: 1, z: 1} 141 | m_Children: 142 | - {fileID: 667558426} 143 | m_Father: {fileID: 564230929} 144 | m_RootOrder: 2 145 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 146 | m_AnchorMin: {x: 1, y: 0} 147 | m_AnchorMax: {x: 1, y: 0} 148 | m_AnchoredPosition: {x: -140, y: 48} 149 | m_SizeDelta: {x: 240, y: 60} 150 | m_Pivot: {x: 0.5, y: 0.5} 151 | --- !u!114 &247881379 152 | MonoBehaviour: 153 | m_ObjectHideFlags: 0 154 | m_PrefabParentObject: {fileID: 0} 155 | m_PrefabInternal: {fileID: 0} 156 | m_GameObject: {fileID: 247881377} 157 | m_Enabled: 1 158 | m_EditorHideFlags: 0 159 | m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 160 | m_Name: 161 | m_EditorClassIdentifier: 162 | m_Navigation: 163 | m_Mode: 3 164 | m_SelectOnUp: {fileID: 0} 165 | m_SelectOnDown: {fileID: 0} 166 | m_SelectOnLeft: {fileID: 0} 167 | m_SelectOnRight: {fileID: 0} 168 | m_Transition: 1 169 | m_Colors: 170 | m_NormalColor: {r: 1, g: 1, b: 1, a: 1} 171 | m_HighlightedColor: {r: 0.85294116, g: 0.85294116, b: 0.85294116, a: 1} 172 | m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} 173 | m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} 174 | m_ColorMultiplier: 1 175 | m_FadeDuration: 0.1 176 | m_SpriteState: 177 | m_HighlightedSprite: {fileID: 0} 178 | m_PressedSprite: {fileID: 0} 179 | m_DisabledSprite: {fileID: 0} 180 | m_AnimationTriggers: 181 | m_NormalTrigger: Normal 182 | m_HighlightedTrigger: Highlighted 183 | m_PressedTrigger: Pressed 184 | m_DisabledTrigger: Disabled 185 | m_Interactable: 1 186 | m_TargetGraphic: {fileID: 247881380} 187 | m_OnClick: 188 | m_PersistentCalls: 189 | m_Calls: [] 190 | m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, 191 | Culture=neutral, PublicKeyToken=null 192 | --- !u!114 &247881380 193 | MonoBehaviour: 194 | m_ObjectHideFlags: 0 195 | m_PrefabParentObject: {fileID: 0} 196 | m_PrefabInternal: {fileID: 0} 197 | m_GameObject: {fileID: 247881377} 198 | m_Enabled: 1 199 | m_EditorHideFlags: 0 200 | m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 201 | m_Name: 202 | m_EditorClassIdentifier: 203 | m_Material: {fileID: 0} 204 | m_Color: {r: 1, g: 1, b: 1, a: 1} 205 | m_RaycastTarget: 1 206 | m_OnCullStateChanged: 207 | m_PersistentCalls: 208 | m_Calls: [] 209 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, 210 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 211 | m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} 212 | m_Type: 1 213 | m_PreserveAspect: 0 214 | m_FillCenter: 1 215 | m_FillMethod: 4 216 | m_FillAmount: 1 217 | m_FillClockwise: 1 218 | m_FillOrigin: 0 219 | --- !u!222 &247881381 220 | CanvasRenderer: 221 | m_ObjectHideFlags: 0 222 | m_PrefabParentObject: {fileID: 0} 223 | m_PrefabInternal: {fileID: 0} 224 | m_GameObject: {fileID: 247881377} 225 | --- !u!114 &247881382 226 | MonoBehaviour: 227 | m_ObjectHideFlags: 0 228 | m_PrefabParentObject: {fileID: 0} 229 | m_PrefabInternal: {fileID: 0} 230 | m_GameObject: {fileID: 247881377} 231 | m_Enabled: 1 232 | m_EditorHideFlags: 0 233 | m_Script: {fileID: 11500000, guid: d5bd415b5e94aed429567b10cdbe58a3, type: 3} 234 | m_Name: 235 | m_EditorClassIdentifier: 236 | m_resetScene: Reset 237 | m_Button: {fileID: 247881379} 238 | --- !u!1 &543137978 239 | GameObject: 240 | m_ObjectHideFlags: 0 241 | m_PrefabParentObject: {fileID: 0} 242 | m_PrefabInternal: {fileID: 0} 243 | serializedVersion: 5 244 | m_Component: 245 | - component: {fileID: 543137983} 246 | - component: {fileID: 543137982} 247 | m_Layer: 0 248 | m_Name: Main Camera 249 | m_TagString: MainCamera 250 | m_Icon: {fileID: 0} 251 | m_NavMeshLayer: 0 252 | m_StaticEditorFlags: 0 253 | m_IsActive: 1 254 | --- !u!20 &543137982 255 | Camera: 256 | m_ObjectHideFlags: 0 257 | m_PrefabParentObject: {fileID: 0} 258 | m_PrefabInternal: {fileID: 0} 259 | m_GameObject: {fileID: 543137978} 260 | m_Enabled: 1 261 | serializedVersion: 2 262 | m_ClearFlags: 2 263 | m_BackGroundColor: {r: 0.21960786, g: 0.21960786, b: 0.21960786, a: 0} 264 | m_NormalizedViewPortRect: 265 | serializedVersion: 2 266 | x: 0 267 | y: 0 268 | width: 1 269 | height: 1 270 | near clip plane: 0.3 271 | far clip plane: 1000 272 | field of view: 60 273 | orthographic: 0 274 | orthographic size: 5 275 | m_Depth: -1 276 | m_CullingMask: 277 | serializedVersion: 2 278 | m_Bits: 4294967295 279 | m_RenderingPath: -1 280 | m_TargetTexture: {fileID: 0} 281 | m_TargetDisplay: 0 282 | m_TargetEye: 3 283 | m_HDR: 0 284 | m_AllowMSAA: 1 285 | m_ForceIntoRT: 0 286 | m_OcclusionCulling: 1 287 | m_StereoConvergence: 10 288 | m_StereoSeparation: 0.022 289 | m_StereoMirrorMode: 0 290 | --- !u!4 &543137983 291 | Transform: 292 | m_ObjectHideFlags: 0 293 | m_PrefabParentObject: {fileID: 0} 294 | m_PrefabInternal: {fileID: 0} 295 | m_GameObject: {fileID: 543137978} 296 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 297 | m_LocalPosition: {x: 0, y: 1, z: -10} 298 | m_LocalScale: {x: 1, y: 1, z: 1} 299 | m_Children: [] 300 | m_Father: {fileID: 0} 301 | m_RootOrder: 0 302 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 303 | --- !u!1 &564230925 304 | GameObject: 305 | m_ObjectHideFlags: 0 306 | m_PrefabParentObject: {fileID: 0} 307 | m_PrefabInternal: {fileID: 0} 308 | serializedVersion: 5 309 | m_Component: 310 | - component: {fileID: 564230929} 311 | - component: {fileID: 564230928} 312 | - component: {fileID: 564230927} 313 | - component: {fileID: 564230926} 314 | - component: {fileID: 564230930} 315 | m_Layer: 5 316 | m_Name: Canvas 317 | m_TagString: Untagged 318 | m_Icon: {fileID: 0} 319 | m_NavMeshLayer: 0 320 | m_StaticEditorFlags: 0 321 | m_IsActive: 1 322 | --- !u!114 &564230926 323 | MonoBehaviour: 324 | m_ObjectHideFlags: 0 325 | m_PrefabParentObject: {fileID: 0} 326 | m_PrefabInternal: {fileID: 0} 327 | m_GameObject: {fileID: 564230925} 328 | m_Enabled: 1 329 | m_EditorHideFlags: 0 330 | m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 331 | m_Name: 332 | m_EditorClassIdentifier: 333 | m_IgnoreReversedGraphics: 1 334 | m_BlockingObjects: 0 335 | m_BlockingMask: 336 | serializedVersion: 2 337 | m_Bits: 4294967295 338 | --- !u!114 &564230927 339 | MonoBehaviour: 340 | m_ObjectHideFlags: 0 341 | m_PrefabParentObject: {fileID: 0} 342 | m_PrefabInternal: {fileID: 0} 343 | m_GameObject: {fileID: 564230925} 344 | m_Enabled: 1 345 | m_EditorHideFlags: 0 346 | m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 347 | m_Name: 348 | m_EditorClassIdentifier: 349 | m_UiScaleMode: 0 350 | m_ReferencePixelsPerUnit: 100 351 | m_ScaleFactor: 1 352 | m_ReferenceResolution: {x: 800, y: 600} 353 | m_ScreenMatchMode: 0 354 | m_MatchWidthOrHeight: 0 355 | m_PhysicalUnit: 3 356 | m_FallbackScreenDPI: 96 357 | m_DefaultSpriteDPI: 96 358 | m_DynamicPixelsPerUnit: 1 359 | --- !u!223 &564230928 360 | Canvas: 361 | m_ObjectHideFlags: 0 362 | m_PrefabParentObject: {fileID: 0} 363 | m_PrefabInternal: {fileID: 0} 364 | m_GameObject: {fileID: 564230925} 365 | m_Enabled: 1 366 | serializedVersion: 3 367 | m_RenderMode: 0 368 | m_Camera: {fileID: 0} 369 | m_PlaneDistance: 100 370 | m_PixelPerfect: 0 371 | m_ReceivesEvents: 1 372 | m_OverrideSorting: 0 373 | m_OverridePixelPerfect: 0 374 | m_SortingBucketNormalizedSize: 0 375 | m_AdditionalShaderChannelsFlag: 25 376 | m_SortingLayerID: 0 377 | m_SortingOrder: 0 378 | m_TargetDisplay: 0 379 | --- !u!224 &564230929 380 | RectTransform: 381 | m_ObjectHideFlags: 0 382 | m_PrefabParentObject: {fileID: 0} 383 | m_PrefabInternal: {fileID: 0} 384 | m_GameObject: {fileID: 564230925} 385 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 386 | m_LocalPosition: {x: 0, y: 0, z: 0} 387 | m_LocalScale: {x: 0, y: 0, z: 0} 388 | m_Children: 389 | - {fileID: 663405136} 390 | - {fileID: 1043399804} 391 | - {fileID: 247881378} 392 | m_Father: {fileID: 0} 393 | m_RootOrder: 2 394 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 395 | m_AnchorMin: {x: 0, y: 0} 396 | m_AnchorMax: {x: 0, y: 0} 397 | m_AnchoredPosition: {x: 0, y: 0} 398 | m_SizeDelta: {x: 0, y: 0} 399 | m_Pivot: {x: 0, y: 0} 400 | --- !u!225 &564230930 401 | CanvasGroup: 402 | m_ObjectHideFlags: 0 403 | m_PrefabParentObject: {fileID: 0} 404 | m_PrefabInternal: {fileID: 0} 405 | m_GameObject: {fileID: 564230925} 406 | m_Enabled: 1 407 | m_Alpha: 1 408 | m_Interactable: 1 409 | m_BlocksRaycasts: 1 410 | m_IgnoreParentGroups: 0 411 | --- !u!1 &663405135 412 | GameObject: 413 | m_ObjectHideFlags: 0 414 | m_PrefabParentObject: {fileID: 0} 415 | m_PrefabInternal: {fileID: 0} 416 | serializedVersion: 5 417 | m_Component: 418 | - component: {fileID: 663405136} 419 | - component: {fileID: 663405140} 420 | - component: {fileID: 663405139} 421 | - component: {fileID: 663405138} 422 | - component: {fileID: 663405137} 423 | m_Layer: 5 424 | m_Name: LoadButton 425 | m_TagString: Untagged 426 | m_Icon: {fileID: 0} 427 | m_NavMeshLayer: 0 428 | m_StaticEditorFlags: 0 429 | m_IsActive: 1 430 | --- !u!224 &663405136 431 | RectTransform: 432 | m_ObjectHideFlags: 0 433 | m_PrefabParentObject: {fileID: 0} 434 | m_PrefabInternal: {fileID: 0} 435 | m_GameObject: {fileID: 663405135} 436 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 437 | m_LocalPosition: {x: 0, y: 0, z: 0} 438 | m_LocalScale: {x: 1, y: 1, z: 1} 439 | m_Children: 440 | - {fileID: 1910380763} 441 | m_Father: {fileID: 564230929} 442 | m_RootOrder: 0 443 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 444 | m_AnchorMin: {x: 0.5, y: 0.5} 445 | m_AnchorMax: {x: 0.5, y: 0.5} 446 | m_AnchoredPosition: {x: 0, y: 0} 447 | m_SizeDelta: {x: 320, y: 80} 448 | m_Pivot: {x: 0.5, y: 0.5} 449 | --- !u!114 &663405137 450 | MonoBehaviour: 451 | m_ObjectHideFlags: 0 452 | m_PrefabParentObject: {fileID: 0} 453 | m_PrefabInternal: {fileID: 0} 454 | m_GameObject: {fileID: 663405135} 455 | m_Enabled: 1 456 | m_EditorHideFlags: 0 457 | m_Script: {fileID: 11500000, guid: 61c26c9030a36d44bb2f33e8181612a7, type: 3} 458 | m_Name: 459 | m_EditorClassIdentifier: 460 | m_SceneToLoadAndUnload: Test 461 | m_Button: {fileID: 663405138} 462 | m_ButtonText: {fileID: 1910380764} 463 | --- !u!114 &663405138 464 | MonoBehaviour: 465 | m_ObjectHideFlags: 0 466 | m_PrefabParentObject: {fileID: 0} 467 | m_PrefabInternal: {fileID: 0} 468 | m_GameObject: {fileID: 663405135} 469 | m_Enabled: 1 470 | m_EditorHideFlags: 0 471 | m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 472 | m_Name: 473 | m_EditorClassIdentifier: 474 | m_Navigation: 475 | m_Mode: 3 476 | m_SelectOnUp: {fileID: 0} 477 | m_SelectOnDown: {fileID: 0} 478 | m_SelectOnLeft: {fileID: 0} 479 | m_SelectOnRight: {fileID: 0} 480 | m_Transition: 1 481 | m_Colors: 482 | m_NormalColor: {r: 1, g: 1, b: 1, a: 1} 483 | m_HighlightedColor: {r: 0.85294116, g: 0.85294116, b: 0.85294116, a: 1} 484 | m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} 485 | m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} 486 | m_ColorMultiplier: 1 487 | m_FadeDuration: 0.1 488 | m_SpriteState: 489 | m_HighlightedSprite: {fileID: 0} 490 | m_PressedSprite: {fileID: 0} 491 | m_DisabledSprite: {fileID: 0} 492 | m_AnimationTriggers: 493 | m_NormalTrigger: Normal 494 | m_HighlightedTrigger: Highlighted 495 | m_PressedTrigger: Pressed 496 | m_DisabledTrigger: Disabled 497 | m_Interactable: 1 498 | m_TargetGraphic: {fileID: 663405139} 499 | m_OnClick: 500 | m_PersistentCalls: 501 | m_Calls: [] 502 | m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, 503 | Culture=neutral, PublicKeyToken=null 504 | --- !u!114 &663405139 505 | MonoBehaviour: 506 | m_ObjectHideFlags: 0 507 | m_PrefabParentObject: {fileID: 0} 508 | m_PrefabInternal: {fileID: 0} 509 | m_GameObject: {fileID: 663405135} 510 | m_Enabled: 1 511 | m_EditorHideFlags: 0 512 | m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 513 | m_Name: 514 | m_EditorClassIdentifier: 515 | m_Material: {fileID: 0} 516 | m_Color: {r: 1, g: 1, b: 1, a: 1} 517 | m_RaycastTarget: 1 518 | m_OnCullStateChanged: 519 | m_PersistentCalls: 520 | m_Calls: [] 521 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, 522 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 523 | m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} 524 | m_Type: 1 525 | m_PreserveAspect: 0 526 | m_FillCenter: 1 527 | m_FillMethod: 4 528 | m_FillAmount: 1 529 | m_FillClockwise: 1 530 | m_FillOrigin: 0 531 | --- !u!222 &663405140 532 | CanvasRenderer: 533 | m_ObjectHideFlags: 0 534 | m_PrefabParentObject: {fileID: 0} 535 | m_PrefabInternal: {fileID: 0} 536 | m_GameObject: {fileID: 663405135} 537 | --- !u!1 &667558425 538 | GameObject: 539 | m_ObjectHideFlags: 0 540 | m_PrefabParentObject: {fileID: 0} 541 | m_PrefabInternal: {fileID: 0} 542 | serializedVersion: 5 543 | m_Component: 544 | - component: {fileID: 667558426} 545 | - component: {fileID: 667558428} 546 | - component: {fileID: 667558427} 547 | m_Layer: 5 548 | m_Name: Text 549 | m_TagString: Untagged 550 | m_Icon: {fileID: 0} 551 | m_NavMeshLayer: 0 552 | m_StaticEditorFlags: 0 553 | m_IsActive: 1 554 | --- !u!224 &667558426 555 | RectTransform: 556 | m_ObjectHideFlags: 0 557 | m_PrefabParentObject: {fileID: 0} 558 | m_PrefabInternal: {fileID: 0} 559 | m_GameObject: {fileID: 667558425} 560 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 561 | m_LocalPosition: {x: 0, y: 0, z: 0} 562 | m_LocalScale: {x: 1, y: 1, z: 1} 563 | m_Children: [] 564 | m_Father: {fileID: 247881378} 565 | m_RootOrder: 0 566 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 567 | m_AnchorMin: {x: 0, y: 0} 568 | m_AnchorMax: {x: 1, y: 1} 569 | m_AnchoredPosition: {x: 0, y: 0} 570 | m_SizeDelta: {x: 0, y: 0} 571 | m_Pivot: {x: 0.5, y: 0.5} 572 | --- !u!114 &667558427 573 | MonoBehaviour: 574 | m_ObjectHideFlags: 0 575 | m_PrefabParentObject: {fileID: 0} 576 | m_PrefabInternal: {fileID: 0} 577 | m_GameObject: {fileID: 667558425} 578 | m_Enabled: 1 579 | m_EditorHideFlags: 0 580 | m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 581 | m_Name: 582 | m_EditorClassIdentifier: 583 | m_Material: {fileID: 0} 584 | m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} 585 | m_RaycastTarget: 1 586 | m_OnCullStateChanged: 587 | m_PersistentCalls: 588 | m_Calls: [] 589 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, 590 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 591 | m_FontData: 592 | m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} 593 | m_FontSize: 14 594 | m_FontStyle: 0 595 | m_BestFit: 0 596 | m_MinSize: 10 597 | m_MaxSize: 40 598 | m_Alignment: 4 599 | m_AlignByGeometry: 0 600 | m_RichText: 1 601 | m_HorizontalOverflow: 0 602 | m_VerticalOverflow: 0 603 | m_LineSpacing: 1 604 | m_Text: Reset 605 | --- !u!222 &667558428 606 | CanvasRenderer: 607 | m_ObjectHideFlags: 0 608 | m_PrefabParentObject: {fileID: 0} 609 | m_PrefabInternal: {fileID: 0} 610 | m_GameObject: {fileID: 667558425} 611 | --- !u!1 &1043399803 612 | GameObject: 613 | m_ObjectHideFlags: 0 614 | m_PrefabParentObject: {fileID: 0} 615 | m_PrefabInternal: {fileID: 0} 616 | serializedVersion: 5 617 | m_Component: 618 | - component: {fileID: 1043399804} 619 | - component: {fileID: 1043399808} 620 | - component: {fileID: 1043399807} 621 | - component: {fileID: 1043399806} 622 | - component: {fileID: 1043399805} 623 | m_Layer: 5 624 | m_Name: SceneCycleButton 625 | m_TagString: Untagged 626 | m_Icon: {fileID: 0} 627 | m_NavMeshLayer: 0 628 | m_StaticEditorFlags: 0 629 | m_IsActive: 1 630 | --- !u!224 &1043399804 631 | RectTransform: 632 | m_ObjectHideFlags: 0 633 | m_PrefabParentObject: {fileID: 0} 634 | m_PrefabInternal: {fileID: 0} 635 | m_GameObject: {fileID: 1043399803} 636 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 637 | m_LocalPosition: {x: 0, y: 0, z: 0} 638 | m_LocalScale: {x: 1, y: 1, z: 1} 639 | m_Children: 640 | - {fileID: 1794204493} 641 | m_Father: {fileID: 564230929} 642 | m_RootOrder: 1 643 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 644 | m_AnchorMin: {x: 0.5, y: 0.5} 645 | m_AnchorMax: {x: 0.5, y: 0.5} 646 | m_AnchoredPosition: {x: 0, y: -100} 647 | m_SizeDelta: {x: 320, y: 80} 648 | m_Pivot: {x: 0.5, y: 0.5} 649 | --- !u!114 &1043399805 650 | MonoBehaviour: 651 | m_ObjectHideFlags: 0 652 | m_PrefabParentObject: {fileID: 0} 653 | m_PrefabInternal: {fileID: 0} 654 | m_GameObject: {fileID: 1043399803} 655 | m_Enabled: 1 656 | m_EditorHideFlags: 0 657 | m_Script: {fileID: 11500000, guid: 0155af832a8ec4fa497dfefd7d4a3257, type: 3} 658 | m_Name: 659 | m_EditorClassIdentifier: 660 | m_SceneToLoadAndUnload: Test 661 | m_NumberOfTimesToLoadAndUnload: 3000 662 | m_Button: {fileID: 1043399806} 663 | m_ButtonText: {fileID: 1794204494} 664 | --- !u!114 &1043399806 665 | MonoBehaviour: 666 | m_ObjectHideFlags: 0 667 | m_PrefabParentObject: {fileID: 0} 668 | m_PrefabInternal: {fileID: 0} 669 | m_GameObject: {fileID: 1043399803} 670 | m_Enabled: 1 671 | m_EditorHideFlags: 0 672 | m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 673 | m_Name: 674 | m_EditorClassIdentifier: 675 | m_Navigation: 676 | m_Mode: 3 677 | m_SelectOnUp: {fileID: 0} 678 | m_SelectOnDown: {fileID: 0} 679 | m_SelectOnLeft: {fileID: 0} 680 | m_SelectOnRight: {fileID: 0} 681 | m_Transition: 1 682 | m_Colors: 683 | m_NormalColor: {r: 1, g: 1, b: 1, a: 1} 684 | m_HighlightedColor: {r: 0.85294116, g: 0.85294116, b: 0.85294116, a: 1} 685 | m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} 686 | m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} 687 | m_ColorMultiplier: 1 688 | m_FadeDuration: 0.1 689 | m_SpriteState: 690 | m_HighlightedSprite: {fileID: 0} 691 | m_PressedSprite: {fileID: 0} 692 | m_DisabledSprite: {fileID: 0} 693 | m_AnimationTriggers: 694 | m_NormalTrigger: Normal 695 | m_HighlightedTrigger: Highlighted 696 | m_PressedTrigger: Pressed 697 | m_DisabledTrigger: Disabled 698 | m_Interactable: 1 699 | m_TargetGraphic: {fileID: 1043399807} 700 | m_OnClick: 701 | m_PersistentCalls: 702 | m_Calls: [] 703 | m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, 704 | Culture=neutral, PublicKeyToken=null 705 | --- !u!114 &1043399807 706 | MonoBehaviour: 707 | m_ObjectHideFlags: 0 708 | m_PrefabParentObject: {fileID: 0} 709 | m_PrefabInternal: {fileID: 0} 710 | m_GameObject: {fileID: 1043399803} 711 | m_Enabled: 1 712 | m_EditorHideFlags: 0 713 | m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 714 | m_Name: 715 | m_EditorClassIdentifier: 716 | m_Material: {fileID: 0} 717 | m_Color: {r: 1, g: 1, b: 1, a: 1} 718 | m_RaycastTarget: 1 719 | m_OnCullStateChanged: 720 | m_PersistentCalls: 721 | m_Calls: [] 722 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, 723 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 724 | m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} 725 | m_Type: 1 726 | m_PreserveAspect: 0 727 | m_FillCenter: 1 728 | m_FillMethod: 4 729 | m_FillAmount: 1 730 | m_FillClockwise: 1 731 | m_FillOrigin: 0 732 | --- !u!222 &1043399808 733 | CanvasRenderer: 734 | m_ObjectHideFlags: 0 735 | m_PrefabParentObject: {fileID: 0} 736 | m_PrefabInternal: {fileID: 0} 737 | m_GameObject: {fileID: 1043399803} 738 | --- !u!1 &1080903274 739 | GameObject: 740 | m_ObjectHideFlags: 0 741 | m_PrefabParentObject: {fileID: 0} 742 | m_PrefabInternal: {fileID: 0} 743 | serializedVersion: 5 744 | m_Component: 745 | - component: {fileID: 1080903277} 746 | - component: {fileID: 1080903276} 747 | - component: {fileID: 1080903275} 748 | m_Layer: 0 749 | m_Name: EventSystem 750 | m_TagString: Untagged 751 | m_Icon: {fileID: 0} 752 | m_NavMeshLayer: 0 753 | m_StaticEditorFlags: 0 754 | m_IsActive: 1 755 | --- !u!114 &1080903275 756 | MonoBehaviour: 757 | m_ObjectHideFlags: 0 758 | m_PrefabParentObject: {fileID: 0} 759 | m_PrefabInternal: {fileID: 0} 760 | m_GameObject: {fileID: 1080903274} 761 | m_Enabled: 1 762 | m_EditorHideFlags: 0 763 | m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 764 | m_Name: 765 | m_EditorClassIdentifier: 766 | m_HorizontalAxis: Horizontal 767 | m_VerticalAxis: Vertical 768 | m_SubmitButton: Submit 769 | m_CancelButton: Cancel 770 | m_InputActionsPerSecond: 10 771 | m_RepeatDelay: 0.5 772 | m_ForceModuleActive: 1 773 | --- !u!114 &1080903276 774 | MonoBehaviour: 775 | m_ObjectHideFlags: 0 776 | m_PrefabParentObject: {fileID: 0} 777 | m_PrefabInternal: {fileID: 0} 778 | m_GameObject: {fileID: 1080903274} 779 | m_Enabled: 1 780 | m_EditorHideFlags: 0 781 | m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 782 | m_Name: 783 | m_EditorClassIdentifier: 784 | m_FirstSelected: {fileID: 663405135} 785 | m_sendNavigationEvents: 1 786 | m_DragThreshold: 5 787 | --- !u!4 &1080903277 788 | Transform: 789 | m_ObjectHideFlags: 0 790 | m_PrefabParentObject: {fileID: 0} 791 | m_PrefabInternal: {fileID: 0} 792 | m_GameObject: {fileID: 1080903274} 793 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 794 | m_LocalPosition: {x: 0, y: 0, z: 0} 795 | m_LocalScale: {x: 1, y: 1, z: 1} 796 | m_Children: [] 797 | m_Father: {fileID: 0} 798 | m_RootOrder: 3 799 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 800 | --- !u!1 &1444970830 801 | GameObject: 802 | m_ObjectHideFlags: 0 803 | m_PrefabParentObject: {fileID: 0} 804 | m_PrefabInternal: {fileID: 0} 805 | serializedVersion: 5 806 | m_Component: 807 | - component: {fileID: 1444970832} 808 | - component: {fileID: 1444970831} 809 | m_Layer: 0 810 | m_Name: ZombieObjectDetector 811 | m_TagString: Untagged 812 | m_Icon: {fileID: 0} 813 | m_NavMeshLayer: 0 814 | m_StaticEditorFlags: 0 815 | m_IsActive: 1 816 | --- !u!114 &1444970831 817 | MonoBehaviour: 818 | m_ObjectHideFlags: 0 819 | m_PrefabParentObject: {fileID: 0} 820 | m_PrefabInternal: {fileID: 0} 821 | m_GameObject: {fileID: 1444970830} 822 | m_Enabled: 1 823 | m_EditorHideFlags: 0 824 | m_Script: {fileID: 11500000, guid: da39880ba7957964c8e67d1816fe0a76, type: 3} 825 | m_Name: 826 | m_EditorClassIdentifier: 827 | m_LoggingOptions: 48 828 | m_DebugLoggingOptions: 0 829 | m_LogTag: 830 | m_IgnoredTypeStrings: [] 831 | m_TypesToScanStrings: [] 832 | m_LogZombieKeyCode: 122 833 | --- !u!4 &1444970832 834 | Transform: 835 | m_ObjectHideFlags: 0 836 | m_PrefabParentObject: {fileID: 0} 837 | m_PrefabInternal: {fileID: 0} 838 | m_GameObject: {fileID: 1444970830} 839 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 840 | m_LocalPosition: {x: 0, y: 0, z: 0} 841 | m_LocalScale: {x: 1, y: 1, z: 1} 842 | m_Children: [] 843 | m_Father: {fileID: 0} 844 | m_RootOrder: 4 845 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 846 | --- !u!1 &1794204492 847 | GameObject: 848 | m_ObjectHideFlags: 0 849 | m_PrefabParentObject: {fileID: 0} 850 | m_PrefabInternal: {fileID: 0} 851 | serializedVersion: 5 852 | m_Component: 853 | - component: {fileID: 1794204493} 854 | - component: {fileID: 1794204495} 855 | - component: {fileID: 1794204494} 856 | m_Layer: 5 857 | m_Name: Text 858 | m_TagString: Untagged 859 | m_Icon: {fileID: 0} 860 | m_NavMeshLayer: 0 861 | m_StaticEditorFlags: 0 862 | m_IsActive: 1 863 | --- !u!224 &1794204493 864 | RectTransform: 865 | m_ObjectHideFlags: 0 866 | m_PrefabParentObject: {fileID: 0} 867 | m_PrefabInternal: {fileID: 0} 868 | m_GameObject: {fileID: 1794204492} 869 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 870 | m_LocalPosition: {x: 0, y: 0, z: 0} 871 | m_LocalScale: {x: 1, y: 1, z: 1} 872 | m_Children: [] 873 | m_Father: {fileID: 1043399804} 874 | m_RootOrder: 0 875 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 876 | m_AnchorMin: {x: 0, y: 0} 877 | m_AnchorMax: {x: 1, y: 1} 878 | m_AnchoredPosition: {x: 0, y: 0} 879 | m_SizeDelta: {x: 0, y: 0} 880 | m_Pivot: {x: 0.5, y: 0.5} 881 | --- !u!114 &1794204494 882 | MonoBehaviour: 883 | m_ObjectHideFlags: 0 884 | m_PrefabParentObject: {fileID: 0} 885 | m_PrefabInternal: {fileID: 0} 886 | m_GameObject: {fileID: 1794204492} 887 | m_Enabled: 1 888 | m_EditorHideFlags: 0 889 | m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 890 | m_Name: 891 | m_EditorClassIdentifier: 892 | m_Material: {fileID: 0} 893 | m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} 894 | m_RaycastTarget: 1 895 | m_OnCullStateChanged: 896 | m_PersistentCalls: 897 | m_Calls: [] 898 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, 899 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 900 | m_FontData: 901 | m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} 902 | m_FontSize: 14 903 | m_FontStyle: 0 904 | m_BestFit: 0 905 | m_MinSize: 10 906 | m_MaxSize: 40 907 | m_Alignment: 4 908 | m_AlignByGeometry: 0 909 | m_RichText: 1 910 | m_HorizontalOverflow: 0 911 | m_VerticalOverflow: 0 912 | m_LineSpacing: 1 913 | m_Text: Load And Unload Multiple Levels 914 | --- !u!222 &1794204495 915 | CanvasRenderer: 916 | m_ObjectHideFlags: 0 917 | m_PrefabParentObject: {fileID: 0} 918 | m_PrefabInternal: {fileID: 0} 919 | m_GameObject: {fileID: 1794204492} 920 | --- !u!1 &1904561649 921 | GameObject: 922 | m_ObjectHideFlags: 0 923 | m_PrefabParentObject: {fileID: 0} 924 | m_PrefabInternal: {fileID: 0} 925 | serializedVersion: 5 926 | m_Component: 927 | - component: {fileID: 1904561651} 928 | - component: {fileID: 1904561650} 929 | m_Layer: 0 930 | m_Name: Directional Light 931 | m_TagString: Untagged 932 | m_Icon: {fileID: 0} 933 | m_NavMeshLayer: 0 934 | m_StaticEditorFlags: 0 935 | m_IsActive: 1 936 | --- !u!108 &1904561650 937 | Light: 938 | m_ObjectHideFlags: 0 939 | m_PrefabParentObject: {fileID: 0} 940 | m_PrefabInternal: {fileID: 0} 941 | m_GameObject: {fileID: 1904561649} 942 | m_Enabled: 1 943 | serializedVersion: 8 944 | m_Type: 1 945 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 946 | m_Intensity: 1 947 | m_Range: 10 948 | m_SpotAngle: 30 949 | m_CookieSize: 10 950 | m_Shadows: 951 | m_Type: 2 952 | m_Resolution: -1 953 | m_CustomResolution: -1 954 | m_Strength: 1 955 | m_Bias: 0.05 956 | m_NormalBias: 0.4 957 | m_NearPlane: 0.2 958 | m_Cookie: {fileID: 0} 959 | m_DrawHalo: 0 960 | m_Flare: {fileID: 0} 961 | m_RenderMode: 0 962 | m_CullingMask: 963 | serializedVersion: 2 964 | m_Bits: 4294967295 965 | m_Lightmapping: 4 966 | m_AreaSize: {x: 1, y: 1} 967 | m_BounceIntensity: 1 968 | m_ColorTemperature: 6570 969 | m_UseColorTemperature: 0 970 | m_ShadowRadius: 0 971 | m_ShadowAngle: 0 972 | --- !u!4 &1904561651 973 | Transform: 974 | m_ObjectHideFlags: 0 975 | m_PrefabParentObject: {fileID: 0} 976 | m_PrefabInternal: {fileID: 0} 977 | m_GameObject: {fileID: 1904561649} 978 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 979 | m_LocalPosition: {x: 0, y: 3, z: 0} 980 | m_LocalScale: {x: 1, y: 1, z: 1} 981 | m_Children: [] 982 | m_Father: {fileID: 0} 983 | m_RootOrder: 1 984 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 985 | --- !u!1 &1910380762 986 | GameObject: 987 | m_ObjectHideFlags: 0 988 | m_PrefabParentObject: {fileID: 0} 989 | m_PrefabInternal: {fileID: 0} 990 | serializedVersion: 5 991 | m_Component: 992 | - component: {fileID: 1910380763} 993 | - component: {fileID: 1910380765} 994 | - component: {fileID: 1910380764} 995 | m_Layer: 5 996 | m_Name: Text 997 | m_TagString: Untagged 998 | m_Icon: {fileID: 0} 999 | m_NavMeshLayer: 0 1000 | m_StaticEditorFlags: 0 1001 | m_IsActive: 1 1002 | --- !u!224 &1910380763 1003 | RectTransform: 1004 | m_ObjectHideFlags: 0 1005 | m_PrefabParentObject: {fileID: 0} 1006 | m_PrefabInternal: {fileID: 0} 1007 | m_GameObject: {fileID: 1910380762} 1008 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 1009 | m_LocalPosition: {x: 0, y: 0, z: 0} 1010 | m_LocalScale: {x: 1, y: 1, z: 1} 1011 | m_Children: [] 1012 | m_Father: {fileID: 663405136} 1013 | m_RootOrder: 0 1014 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 1015 | m_AnchorMin: {x: 0, y: 0} 1016 | m_AnchorMax: {x: 1, y: 1} 1017 | m_AnchoredPosition: {x: 0, y: 0} 1018 | m_SizeDelta: {x: 0, y: 0} 1019 | m_Pivot: {x: 0.5, y: 0.5} 1020 | --- !u!114 &1910380764 1021 | MonoBehaviour: 1022 | m_ObjectHideFlags: 0 1023 | m_PrefabParentObject: {fileID: 0} 1024 | m_PrefabInternal: {fileID: 0} 1025 | m_GameObject: {fileID: 1910380762} 1026 | m_Enabled: 1 1027 | m_EditorHideFlags: 0 1028 | m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 1029 | m_Name: 1030 | m_EditorClassIdentifier: 1031 | m_Material: {fileID: 0} 1032 | m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} 1033 | m_RaycastTarget: 1 1034 | m_OnCullStateChanged: 1035 | m_PersistentCalls: 1036 | m_Calls: [] 1037 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, 1038 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 1039 | m_FontData: 1040 | m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} 1041 | m_FontSize: 14 1042 | m_FontStyle: 0 1043 | m_BestFit: 0 1044 | m_MinSize: 10 1045 | m_MaxSize: 40 1046 | m_Alignment: 4 1047 | m_AlignByGeometry: 0 1048 | m_RichText: 1 1049 | m_HorizontalOverflow: 0 1050 | m_VerticalOverflow: 0 1051 | m_LineSpacing: 1 1052 | m_Text: Load 1053 | --- !u!222 &1910380765 1054 | CanvasRenderer: 1055 | m_ObjectHideFlags: 0 1056 | m_PrefabParentObject: {fileID: 0} 1057 | m_PrefabInternal: {fileID: 0} 1058 | m_GameObject: {fileID: 1910380762} 1059 | -------------------------------------------------------------------------------- /OldExample~/Scenes/Boot.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95355a90042b32641a761bad16b557cc 3 | timeCreated: 1506336986 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /OldExample~/Scenes/Empty.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 7 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 29 | m_HaloStrength: 0.5 30 | m_FlareStrength: 1 31 | m_FlareFadeSpeed: 3 32 | m_HaloTexture: {fileID: 0} 33 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 34 | m_DefaultReflectionMode: 0 35 | m_DefaultReflectionResolution: 128 36 | m_ReflectionBounces: 1 37 | m_ReflectionIntensity: 1 38 | m_CustomReflection: {fileID: 0} 39 | m_Sun: {fileID: 0} 40 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 41 | --- !u!157 &3 42 | LightmapSettings: 43 | m_ObjectHideFlags: 0 44 | serializedVersion: 7 45 | m_GIWorkflowMode: 1 46 | m_GISettings: 47 | serializedVersion: 2 48 | m_BounceScale: 1 49 | m_IndirectOutputScale: 1 50 | m_AlbedoBoost: 1 51 | m_TemporalCoherenceThreshold: 1 52 | m_EnvironmentLightingMode: 0 53 | m_EnableBakedLightmaps: 1 54 | m_EnableRealtimeLightmaps: 1 55 | m_LightmapEditorSettings: 56 | serializedVersion: 4 57 | m_Resolution: 2 58 | m_BakeResolution: 40 59 | m_TextureWidth: 1024 60 | m_TextureHeight: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_Padding: 2 66 | m_LightmapParameters: {fileID: 0} 67 | m_LightmapsBakeMode: 1 68 | m_TextureCompression: 1 69 | m_DirectLightInLightProbes: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_LightingDataAsset: {fileID: 0} 75 | m_RuntimeCPUUsage: 25 76 | --- !u!196 &4 77 | NavMeshSettings: 78 | serializedVersion: 2 79 | m_ObjectHideFlags: 0 80 | m_BuildSettings: 81 | serializedVersion: 2 82 | agentTypeID: 0 83 | agentRadius: 0.5 84 | agentHeight: 2 85 | agentSlope: 45 86 | agentClimb: 0.4 87 | ledgeDropHeight: 0 88 | maxJumpAcrossDistance: 0 89 | minRegionArea: 2 90 | manualCellSize: 0 91 | cellSize: 0.16666667 92 | accuratePlacement: 0 93 | m_NavMeshData: {fileID: 0} 94 | --- !u!1 &1089095127 95 | GameObject: 96 | m_ObjectHideFlags: 0 97 | m_PrefabParentObject: {fileID: 0} 98 | m_PrefabInternal: {fileID: 0} 99 | serializedVersion: 5 100 | m_Component: 101 | - component: {fileID: 1089095132} 102 | - component: {fileID: 1089095131} 103 | m_Layer: 0 104 | m_Name: Main Camera 105 | m_TagString: MainCamera 106 | m_Icon: {fileID: 0} 107 | m_NavMeshLayer: 0 108 | m_StaticEditorFlags: 0 109 | m_IsActive: 1 110 | --- !u!20 &1089095131 111 | Camera: 112 | m_ObjectHideFlags: 0 113 | m_PrefabParentObject: {fileID: 0} 114 | m_PrefabInternal: {fileID: 0} 115 | m_GameObject: {fileID: 1089095127} 116 | m_Enabled: 1 117 | serializedVersion: 2 118 | m_ClearFlags: 2 119 | m_BackGroundColor: {r: 0.21960786, g: 0.21960786, b: 0.21960786, a: 0} 120 | m_NormalizedViewPortRect: 121 | serializedVersion: 2 122 | x: 0 123 | y: 0 124 | width: 1 125 | height: 1 126 | near clip plane: 0.3 127 | far clip plane: 1000 128 | field of view: 60 129 | orthographic: 0 130 | orthographic size: 5 131 | m_Depth: -1 132 | m_CullingMask: 133 | serializedVersion: 2 134 | m_Bits: 4294967295 135 | m_RenderingPath: -1 136 | m_TargetTexture: {fileID: 0} 137 | m_TargetDisplay: 0 138 | m_TargetEye: 3 139 | m_HDR: 0 140 | m_OcclusionCulling: 1 141 | m_StereoConvergence: 10 142 | m_StereoSeparation: 0.022 143 | m_StereoMirrorMode: 0 144 | --- !u!4 &1089095132 145 | Transform: 146 | m_ObjectHideFlags: 0 147 | m_PrefabParentObject: {fileID: 0} 148 | m_PrefabInternal: {fileID: 0} 149 | m_GameObject: {fileID: 1089095127} 150 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 151 | m_LocalPosition: {x: 0, y: 1, z: -10} 152 | m_LocalScale: {x: 1, y: 1, z: 1} 153 | m_Children: [] 154 | m_Father: {fileID: 0} 155 | m_RootOrder: 0 156 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 157 | -------------------------------------------------------------------------------- /OldExample~/Scenes/Empty.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae1132b282f81c34b8509741894bc9cd 3 | timeCreated: 1510937235 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /OldExample~/Scenes/Reset.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 7 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 29 | m_HaloStrength: 0.5 30 | m_FlareStrength: 1 31 | m_FlareFadeSpeed: 3 32 | m_HaloTexture: {fileID: 0} 33 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 34 | m_DefaultReflectionMode: 0 35 | m_DefaultReflectionResolution: 128 36 | m_ReflectionBounces: 1 37 | m_ReflectionIntensity: 1 38 | m_CustomReflection: {fileID: 0} 39 | m_Sun: {fileID: 0} 40 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 41 | --- !u!157 &3 42 | LightmapSettings: 43 | m_ObjectHideFlags: 0 44 | serializedVersion: 7 45 | m_GIWorkflowMode: 1 46 | m_GISettings: 47 | serializedVersion: 2 48 | m_BounceScale: 1 49 | m_IndirectOutputScale: 1 50 | m_AlbedoBoost: 1 51 | m_TemporalCoherenceThreshold: 1 52 | m_EnvironmentLightingMode: 0 53 | m_EnableBakedLightmaps: 1 54 | m_EnableRealtimeLightmaps: 1 55 | m_LightmapEditorSettings: 56 | serializedVersion: 4 57 | m_Resolution: 2 58 | m_BakeResolution: 40 59 | m_TextureWidth: 1024 60 | m_TextureHeight: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_Padding: 2 66 | m_LightmapParameters: {fileID: 0} 67 | m_LightmapsBakeMode: 1 68 | m_TextureCompression: 1 69 | m_DirectLightInLightProbes: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_LightingDataAsset: {fileID: 0} 75 | m_RuntimeCPUUsage: 25 76 | --- !u!196 &4 77 | NavMeshSettings: 78 | serializedVersion: 2 79 | m_ObjectHideFlags: 0 80 | m_BuildSettings: 81 | serializedVersion: 2 82 | agentTypeID: 0 83 | agentRadius: 0.5 84 | agentHeight: 2 85 | agentSlope: 45 86 | agentClimb: 0.4 87 | ledgeDropHeight: 0 88 | maxJumpAcrossDistance: 0 89 | minRegionArea: 2 90 | manualCellSize: 0 91 | cellSize: 0.16666667 92 | accuratePlacement: 0 93 | m_NavMeshData: {fileID: 0} 94 | --- !u!1 &209389925 95 | GameObject: 96 | m_ObjectHideFlags: 0 97 | m_PrefabParentObject: {fileID: 0} 98 | m_PrefabInternal: {fileID: 0} 99 | serializedVersion: 5 100 | m_Component: 101 | - component: {fileID: 209389930} 102 | - component: {fileID: 209389929} 103 | m_Layer: 0 104 | m_Name: Camera 105 | m_TagString: Untagged 106 | m_Icon: {fileID: 0} 107 | m_NavMeshLayer: 0 108 | m_StaticEditorFlags: 0 109 | m_IsActive: 1 110 | --- !u!20 &209389929 111 | Camera: 112 | m_ObjectHideFlags: 0 113 | m_PrefabParentObject: {fileID: 0} 114 | m_PrefabInternal: {fileID: 0} 115 | m_GameObject: {fileID: 209389925} 116 | m_Enabled: 1 117 | serializedVersion: 2 118 | m_ClearFlags: 2 119 | m_BackGroundColor: {r: 0.21960784, g: 0.21960784, b: 0.21960784, a: 0} 120 | m_NormalizedViewPortRect: 121 | serializedVersion: 2 122 | x: 0 123 | y: 0 124 | width: 1 125 | height: 1 126 | near clip plane: 0.3 127 | far clip plane: 1000 128 | field of view: 60 129 | orthographic: 0 130 | orthographic size: 5 131 | m_Depth: 0 132 | m_CullingMask: 133 | serializedVersion: 2 134 | m_Bits: 4294967295 135 | m_RenderingPath: -1 136 | m_TargetTexture: {fileID: 0} 137 | m_TargetDisplay: 0 138 | m_TargetEye: 3 139 | m_HDR: 0 140 | m_OcclusionCulling: 1 141 | m_StereoConvergence: 10 142 | m_StereoSeparation: 0.022 143 | m_StereoMirrorMode: 0 144 | --- !u!4 &209389930 145 | Transform: 146 | m_ObjectHideFlags: 0 147 | m_PrefabParentObject: {fileID: 0} 148 | m_PrefabInternal: {fileID: 0} 149 | m_GameObject: {fileID: 209389925} 150 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 151 | m_LocalPosition: {x: 542, y: 305, z: 0} 152 | m_LocalScale: {x: 1, y: 1, z: 1} 153 | m_Children: [] 154 | m_Father: {fileID: 0} 155 | m_RootOrder: 1 156 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 157 | --- !u!1 &599977799 158 | GameObject: 159 | m_ObjectHideFlags: 0 160 | m_PrefabParentObject: {fileID: 0} 161 | m_PrefabInternal: {fileID: 0} 162 | serializedVersion: 5 163 | m_Component: 164 | - component: {fileID: 599977800} 165 | - component: {fileID: 599977801} 166 | - component: {fileID: 599977802} 167 | m_Layer: 0 168 | m_Name: ClearZombies 169 | m_TagString: Untagged 170 | m_Icon: {fileID: 0} 171 | m_NavMeshLayer: 0 172 | m_StaticEditorFlags: 0 173 | m_IsActive: 1 174 | --- !u!4 &599977800 175 | Transform: 176 | m_ObjectHideFlags: 0 177 | m_PrefabParentObject: {fileID: 0} 178 | m_PrefabInternal: {fileID: 0} 179 | m_GameObject: {fileID: 599977799} 180 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 181 | m_LocalPosition: {x: 0, y: 0, z: 0} 182 | m_LocalScale: {x: 1, y: 1, z: 1} 183 | m_Children: [] 184 | m_Father: {fileID: 0} 185 | m_RootOrder: 0 186 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 187 | --- !u!114 &599977801 188 | MonoBehaviour: 189 | m_ObjectHideFlags: 0 190 | m_PrefabParentObject: {fileID: 0} 191 | m_PrefabInternal: {fileID: 0} 192 | m_GameObject: {fileID: 599977799} 193 | m_Enabled: 1 194 | m_EditorHideFlags: 0 195 | m_Script: {fileID: 11500000, guid: 416828ca21d758a478a0c2dc93e6777b, type: 3} 196 | m_Name: 197 | m_EditorClassIdentifier: 198 | staticEventsObject: {fileID: 599977802} 199 | --- !u!114 &599977802 200 | MonoBehaviour: 201 | m_ObjectHideFlags: 0 202 | m_PrefabParentObject: {fileID: 0} 203 | m_PrefabInternal: {fileID: 0} 204 | m_GameObject: {fileID: 599977799} 205 | m_Enabled: 1 206 | m_EditorHideFlags: 0 207 | m_Script: {fileID: 11500000, guid: f2e9f55618de0d64dadb046e01955efd, type: 3} 208 | m_Name: 209 | m_EditorClassIdentifier: 210 | -------------------------------------------------------------------------------- /OldExample~/Scenes/Reset.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a729404e6e9a20449a5f3c554738422 3 | timeCreated: 1510931504 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /OldExample~/Scenes/Test.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 8 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.3731316, g: 0.38074902, b: 0.3587254, a: 1} 42 | --- !u!157 &3 43 | LightmapSettings: 44 | m_ObjectHideFlags: 0 45 | serializedVersion: 11 46 | m_GIWorkflowMode: 0 47 | m_GISettings: 48 | serializedVersion: 2 49 | m_BounceScale: 1 50 | m_IndirectOutputScale: 1 51 | m_AlbedoBoost: 1 52 | m_TemporalCoherenceThreshold: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 1 56 | m_LightmapEditorSettings: 57 | serializedVersion: 9 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_TextureWidth: 1024 61 | m_TextureHeight: 1024 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 1 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 0 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_LightingDataAsset: {fileID: 0} 92 | m_UseShadowmask: 0 93 | --- !u!196 &4 94 | NavMeshSettings: 95 | serializedVersion: 2 96 | m_ObjectHideFlags: 0 97 | m_BuildSettings: 98 | serializedVersion: 2 99 | agentTypeID: 0 100 | agentRadius: 0.5 101 | agentHeight: 2 102 | agentSlope: 45 103 | agentClimb: 0.4 104 | ledgeDropHeight: 0 105 | maxJumpAcrossDistance: 0 106 | minRegionArea: 2 107 | manualCellSize: 0 108 | cellSize: 0.16666667 109 | manualTileSize: 0 110 | tileSize: 256 111 | accuratePlacement: 0 112 | m_NavMeshData: {fileID: 0} 113 | --- !u!1 &39265676 114 | GameObject: 115 | m_ObjectHideFlags: 0 116 | m_PrefabParentObject: {fileID: 0} 117 | m_PrefabInternal: {fileID: 0} 118 | serializedVersion: 5 119 | m_Component: 120 | - component: {fileID: 39265678} 121 | - component: {fileID: 39265677} 122 | m_Layer: 0 123 | m_Name: EventListener 124 | m_TagString: Untagged 125 | m_Icon: {fileID: 0} 126 | m_NavMeshLayer: 0 127 | m_StaticEditorFlags: 0 128 | m_IsActive: 1 129 | --- !u!114 &39265677 130 | MonoBehaviour: 131 | m_ObjectHideFlags: 0 132 | m_PrefabParentObject: {fileID: 0} 133 | m_PrefabInternal: {fileID: 0} 134 | m_GameObject: {fileID: 39265676} 135 | m_Enabled: 1 136 | m_EditorHideFlags: 0 137 | m_Script: {fileID: 11500000, guid: 7ee84d55d2af51945b73b9da96366f0f, type: 3} 138 | m_Name: 139 | m_EditorClassIdentifier: 140 | --- !u!4 &39265678 141 | Transform: 142 | m_ObjectHideFlags: 0 143 | m_PrefabParentObject: {fileID: 0} 144 | m_PrefabInternal: {fileID: 0} 145 | m_GameObject: {fileID: 39265676} 146 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 147 | m_LocalPosition: {x: 0, y: 0, z: 0} 148 | m_LocalScale: {x: 1, y: 1, z: 1} 149 | m_Children: [] 150 | m_Father: {fileID: 0} 151 | m_RootOrder: 2 152 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 153 | --- !u!1 &166966154 154 | GameObject: 155 | m_ObjectHideFlags: 0 156 | m_PrefabParentObject: {fileID: 0} 157 | m_PrefabInternal: {fileID: 0} 158 | serializedVersion: 5 159 | m_Component: 160 | - component: {fileID: 166966156} 161 | - component: {fileID: 166966155} 162 | m_Layer: 0 163 | m_Name: BasicStaticObjectStack 164 | m_TagString: Untagged 165 | m_Icon: {fileID: 0} 166 | m_NavMeshLayer: 0 167 | m_StaticEditorFlags: 0 168 | m_IsActive: 1 169 | --- !u!114 &166966155 170 | MonoBehaviour: 171 | m_ObjectHideFlags: 0 172 | m_PrefabParentObject: {fileID: 0} 173 | m_PrefabInternal: {fileID: 0} 174 | m_GameObject: {fileID: 166966154} 175 | m_Enabled: 1 176 | m_EditorHideFlags: 0 177 | m_Script: {fileID: 11500000, guid: 31eabf8ada56dc046a69958943dd7d14, type: 3} 178 | m_Name: 179 | m_EditorClassIdentifier: 180 | --- !u!4 &166966156 181 | Transform: 182 | m_ObjectHideFlags: 0 183 | m_PrefabParentObject: {fileID: 0} 184 | m_PrefabInternal: {fileID: 0} 185 | m_GameObject: {fileID: 166966154} 186 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 187 | m_LocalPosition: {x: 0, y: 0, z: 0} 188 | m_LocalScale: {x: 1, y: 1, z: 1} 189 | m_Children: [] 190 | m_Father: {fileID: 0} 191 | m_RootOrder: 0 192 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 193 | --- !u!1 &226479685 194 | GameObject: 195 | m_ObjectHideFlags: 0 196 | m_PrefabParentObject: {fileID: 0} 197 | m_PrefabInternal: {fileID: 0} 198 | serializedVersion: 5 199 | m_Component: 200 | - component: {fileID: 226479687} 201 | - component: {fileID: 226479686} 202 | m_Layer: 0 203 | m_Name: EventListener (1) 204 | m_TagString: Untagged 205 | m_Icon: {fileID: 0} 206 | m_NavMeshLayer: 0 207 | m_StaticEditorFlags: 0 208 | m_IsActive: 1 209 | --- !u!114 &226479686 210 | MonoBehaviour: 211 | m_ObjectHideFlags: 0 212 | m_PrefabParentObject: {fileID: 0} 213 | m_PrefabInternal: {fileID: 0} 214 | m_GameObject: {fileID: 226479685} 215 | m_Enabled: 1 216 | m_EditorHideFlags: 0 217 | m_Script: {fileID: 11500000, guid: 7ee84d55d2af51945b73b9da96366f0f, type: 3} 218 | m_Name: 219 | m_EditorClassIdentifier: 220 | --- !u!4 &226479687 221 | Transform: 222 | m_ObjectHideFlags: 0 223 | m_PrefabParentObject: {fileID: 0} 224 | m_PrefabInternal: {fileID: 0} 225 | m_GameObject: {fileID: 226479685} 226 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 227 | m_LocalPosition: {x: 0, y: 0, z: 0} 228 | m_LocalScale: {x: 1, y: 1, z: 1} 229 | m_Children: [] 230 | m_Father: {fileID: 0} 231 | m_RootOrder: 3 232 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 233 | --- !u!1 &341312800 234 | GameObject: 235 | m_ObjectHideFlags: 0 236 | m_PrefabParentObject: {fileID: 0} 237 | m_PrefabInternal: {fileID: 0} 238 | serializedVersion: 5 239 | m_Component: 240 | - component: {fileID: 341312802} 241 | - component: {fileID: 341312801} 242 | m_Layer: 0 243 | m_Name: ObjectAttachedToDictionary 244 | m_TagString: Untagged 245 | m_Icon: {fileID: 0} 246 | m_NavMeshLayer: 0 247 | m_StaticEditorFlags: 0 248 | m_IsActive: 1 249 | --- !u!114 &341312801 250 | MonoBehaviour: 251 | m_ObjectHideFlags: 0 252 | m_PrefabParentObject: {fileID: 0} 253 | m_PrefabInternal: {fileID: 0} 254 | m_GameObject: {fileID: 341312800} 255 | m_Enabled: 1 256 | m_EditorHideFlags: 0 257 | m_Script: {fileID: 11500000, guid: 20e517c916eee7d4fa9b084e03c2faac, type: 3} 258 | m_Name: 259 | m_EditorClassIdentifier: 260 | --- !u!4 &341312802 261 | Transform: 262 | m_ObjectHideFlags: 0 263 | m_PrefabParentObject: {fileID: 0} 264 | m_PrefabInternal: {fileID: 0} 265 | m_GameObject: {fileID: 341312800} 266 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 267 | m_LocalPosition: {x: 0, y: 0, z: 0} 268 | m_LocalScale: {x: 1, y: 1, z: 1} 269 | m_Children: [] 270 | m_Father: {fileID: 0} 271 | m_RootOrder: 8 272 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 273 | --- !u!1 &983594588 274 | GameObject: 275 | m_ObjectHideFlags: 0 276 | m_PrefabParentObject: {fileID: 0} 277 | m_PrefabInternal: {fileID: 0} 278 | serializedVersion: 5 279 | m_Component: 280 | - component: {fileID: 983594590} 281 | - component: {fileID: 983594589} 282 | m_Layer: 0 283 | m_Name: ObjectAttachedToList 284 | m_TagString: Untagged 285 | m_Icon: {fileID: 0} 286 | m_NavMeshLayer: 0 287 | m_StaticEditorFlags: 0 288 | m_IsActive: 1 289 | --- !u!114 &983594589 290 | MonoBehaviour: 291 | m_ObjectHideFlags: 0 292 | m_PrefabParentObject: {fileID: 0} 293 | m_PrefabInternal: {fileID: 0} 294 | m_GameObject: {fileID: 983594588} 295 | m_Enabled: 1 296 | m_EditorHideFlags: 0 297 | m_Script: {fileID: 11500000, guid: f62f1ae82a3dfa94a902046b8adfd533, type: 3} 298 | m_Name: 299 | m_EditorClassIdentifier: 300 | --- !u!4 &983594590 301 | Transform: 302 | m_ObjectHideFlags: 0 303 | m_PrefabParentObject: {fileID: 0} 304 | m_PrefabInternal: {fileID: 0} 305 | m_GameObject: {fileID: 983594588} 306 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 307 | m_LocalPosition: {x: 0, y: 0, z: 0} 308 | m_LocalScale: {x: 1, y: 1, z: 1} 309 | m_Children: [] 310 | m_Father: {fileID: 0} 311 | m_RootOrder: 9 312 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 313 | --- !u!1 &1036149402 314 | GameObject: 315 | m_ObjectHideFlags: 0 316 | m_PrefabParentObject: {fileID: 0} 317 | m_PrefabInternal: {fileID: 0} 318 | serializedVersion: 5 319 | m_Component: 320 | - component: {fileID: 1036149404} 321 | - component: {fileID: 1036149403} 322 | m_Layer: 0 323 | m_Name: ReferenceHolder 324 | m_TagString: Untagged 325 | m_Icon: {fileID: 0} 326 | m_NavMeshLayer: 0 327 | m_StaticEditorFlags: 0 328 | m_IsActive: 1 329 | --- !u!114 &1036149403 330 | MonoBehaviour: 331 | m_ObjectHideFlags: 0 332 | m_PrefabParentObject: {fileID: 0} 333 | m_PrefabInternal: {fileID: 0} 334 | m_GameObject: {fileID: 1036149402} 335 | m_Enabled: 1 336 | m_EditorHideFlags: 0 337 | m_Script: {fileID: 11500000, guid: aef76b1d56037e54cac34a199bbc285e, type: 3} 338 | m_Name: 339 | m_EditorClassIdentifier: 340 | --- !u!4 &1036149404 341 | Transform: 342 | m_ObjectHideFlags: 0 343 | m_PrefabParentObject: {fileID: 0} 344 | m_PrefabInternal: {fileID: 0} 345 | m_GameObject: {fileID: 1036149402} 346 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 347 | m_LocalPosition: {x: 0, y: 0, z: 0} 348 | m_LocalScale: {x: 1, y: 1, z: 1} 349 | m_Children: [] 350 | m_Father: {fileID: 0} 351 | m_RootOrder: 12 352 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 353 | --- !u!1 &1040583105 354 | GameObject: 355 | m_ObjectHideFlags: 0 356 | m_PrefabParentObject: {fileID: 0} 357 | m_PrefabInternal: {fileID: 0} 358 | serializedVersion: 5 359 | m_Component: 360 | - component: {fileID: 1040583106} 361 | m_Layer: 0 362 | m_Name: ZombieableGameObject (1) 363 | m_TagString: Untagged 364 | m_Icon: {fileID: 0} 365 | m_NavMeshLayer: 0 366 | m_StaticEditorFlags: 0 367 | m_IsActive: 1 368 | --- !u!4 &1040583106 369 | Transform: 370 | m_ObjectHideFlags: 0 371 | m_PrefabParentObject: {fileID: 0} 372 | m_PrefabInternal: {fileID: 0} 373 | m_GameObject: {fileID: 1040583105} 374 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 375 | m_LocalPosition: {x: 0, y: 0, z: 0} 376 | m_LocalScale: {x: 1, y: 1, z: 1} 377 | m_Children: [] 378 | m_Father: {fileID: 0} 379 | m_RootOrder: 15 380 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 381 | --- !u!1 &1166188403 382 | GameObject: 383 | m_ObjectHideFlags: 0 384 | m_PrefabParentObject: {fileID: 0} 385 | m_PrefabInternal: {fileID: 0} 386 | serializedVersion: 5 387 | m_Component: 388 | - component: {fileID: 1166188405} 389 | - component: {fileID: 1166188404} 390 | m_Layer: 0 391 | m_Name: EventListener (2) 392 | m_TagString: Untagged 393 | m_Icon: {fileID: 0} 394 | m_NavMeshLayer: 0 395 | m_StaticEditorFlags: 0 396 | m_IsActive: 1 397 | --- !u!114 &1166188404 398 | MonoBehaviour: 399 | m_ObjectHideFlags: 0 400 | m_PrefabParentObject: {fileID: 0} 401 | m_PrefabInternal: {fileID: 0} 402 | m_GameObject: {fileID: 1166188403} 403 | m_Enabled: 1 404 | m_EditorHideFlags: 0 405 | m_Script: {fileID: 11500000, guid: 7ee84d55d2af51945b73b9da96366f0f, type: 3} 406 | m_Name: 407 | m_EditorClassIdentifier: 408 | --- !u!4 &1166188405 409 | Transform: 410 | m_ObjectHideFlags: 0 411 | m_PrefabParentObject: {fileID: 0} 412 | m_PrefabInternal: {fileID: 0} 413 | m_GameObject: {fileID: 1166188403} 414 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 415 | m_LocalPosition: {x: 0, y: 0, z: 0} 416 | m_LocalScale: {x: 1, y: 1, z: 1} 417 | m_Children: [] 418 | m_Father: {fileID: 0} 419 | m_RootOrder: 4 420 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 421 | --- !u!1 &1310850458 422 | GameObject: 423 | m_ObjectHideFlags: 0 424 | m_PrefabParentObject: {fileID: 0} 425 | m_PrefabInternal: {fileID: 0} 426 | serializedVersion: 5 427 | m_Component: 428 | - component: {fileID: 1310850460} 429 | - component: {fileID: 1310850459} 430 | m_Layer: 0 431 | m_Name: ObjectAttachedToReference 432 | m_TagString: Untagged 433 | m_Icon: {fileID: 0} 434 | m_NavMeshLayer: 0 435 | m_StaticEditorFlags: 0 436 | m_IsActive: 1 437 | --- !u!114 &1310850459 438 | MonoBehaviour: 439 | m_ObjectHideFlags: 0 440 | m_PrefabParentObject: {fileID: 0} 441 | m_PrefabInternal: {fileID: 0} 442 | m_GameObject: {fileID: 1310850458} 443 | m_Enabled: 1 444 | m_EditorHideFlags: 0 445 | m_Script: {fileID: 11500000, guid: f836d54c3f8ab6149a6295fac756c628, type: 3} 446 | m_Name: 447 | m_EditorClassIdentifier: 448 | m_ReferenceHolder: {fileID: 1036149403} 449 | --- !u!4 &1310850460 450 | Transform: 451 | m_ObjectHideFlags: 0 452 | m_PrefabParentObject: {fileID: 0} 453 | m_PrefabInternal: {fileID: 0} 454 | m_GameObject: {fileID: 1310850458} 455 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 456 | m_LocalPosition: {x: 0, y: 0, z: 0} 457 | m_LocalScale: {x: 1, y: 1, z: 1} 458 | m_Children: [] 459 | m_Father: {fileID: 0} 460 | m_RootOrder: 11 461 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 462 | --- !u!1 &1388031379 463 | GameObject: 464 | m_ObjectHideFlags: 0 465 | m_PrefabParentObject: {fileID: 0} 466 | m_PrefabInternal: {fileID: 0} 467 | serializedVersion: 5 468 | m_Component: 469 | - component: {fileID: 1388031380} 470 | m_Layer: 0 471 | m_Name: ZombieableGameObject 472 | m_TagString: Untagged 473 | m_Icon: {fileID: 0} 474 | m_NavMeshLayer: 0 475 | m_StaticEditorFlags: 0 476 | m_IsActive: 1 477 | --- !u!4 &1388031380 478 | Transform: 479 | m_ObjectHideFlags: 0 480 | m_PrefabParentObject: {fileID: 0} 481 | m_PrefabInternal: {fileID: 0} 482 | m_GameObject: {fileID: 1388031379} 483 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 484 | m_LocalPosition: {x: 0, y: 0, z: 0} 485 | m_LocalScale: {x: 1, y: 1, z: 1} 486 | m_Children: [] 487 | m_Father: {fileID: 0} 488 | m_RootOrder: 14 489 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 490 | --- !u!1 &1422219234 491 | GameObject: 492 | m_ObjectHideFlags: 0 493 | m_PrefabParentObject: {fileID: 0} 494 | m_PrefabInternal: {fileID: 0} 495 | serializedVersion: 5 496 | m_Component: 497 | - component: {fileID: 1422219236} 498 | - component: {fileID: 1422219235} 499 | m_Layer: 0 500 | m_Name: BasedOnIgnoredTypeParam 501 | m_TagString: Untagged 502 | m_Icon: {fileID: 0} 503 | m_NavMeshLayer: 0 504 | m_StaticEditorFlags: 0 505 | m_IsActive: 1 506 | --- !u!114 &1422219235 507 | MonoBehaviour: 508 | m_ObjectHideFlags: 0 509 | m_PrefabParentObject: {fileID: 0} 510 | m_PrefabInternal: {fileID: 0} 511 | m_GameObject: {fileID: 1422219234} 512 | m_Enabled: 1 513 | m_EditorHideFlags: 0 514 | m_Script: {fileID: 11500000, guid: ce34d95668afa90449a2cf8b63f55d66, type: 3} 515 | m_Name: 516 | m_EditorClassIdentifier: 517 | --- !u!4 &1422219236 518 | Transform: 519 | m_ObjectHideFlags: 0 520 | m_PrefabParentObject: {fileID: 0} 521 | m_PrefabInternal: {fileID: 0} 522 | m_GameObject: {fileID: 1422219234} 523 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 524 | m_LocalPosition: {x: 0, y: 0, z: 0} 525 | m_LocalScale: {x: 1, y: 1, z: 1} 526 | m_Children: [] 527 | m_Father: {fileID: 0} 528 | m_RootOrder: 1 529 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 530 | --- !u!1 &1431631644 531 | GameObject: 532 | m_ObjectHideFlags: 0 533 | m_PrefabParentObject: {fileID: 0} 534 | m_PrefabInternal: {fileID: 0} 535 | serializedVersion: 5 536 | m_Component: 537 | - component: {fileID: 1431631646} 538 | - component: {fileID: 1431631645} 539 | m_Layer: 0 540 | m_Name: ObjectAttachedToArray 541 | m_TagString: Untagged 542 | m_Icon: {fileID: 0} 543 | m_NavMeshLayer: 0 544 | m_StaticEditorFlags: 0 545 | m_IsActive: 1 546 | --- !u!114 &1431631645 547 | MonoBehaviour: 548 | m_ObjectHideFlags: 0 549 | m_PrefabParentObject: {fileID: 0} 550 | m_PrefabInternal: {fileID: 0} 551 | m_GameObject: {fileID: 1431631644} 552 | m_Enabled: 1 553 | m_EditorHideFlags: 0 554 | m_Script: {fileID: 11500000, guid: 608eb77b24f05144fb1a8eb93adf5dab, type: 3} 555 | m_Name: 556 | m_EditorClassIdentifier: 557 | --- !u!4 &1431631646 558 | Transform: 559 | m_ObjectHideFlags: 0 560 | m_PrefabParentObject: {fileID: 0} 561 | m_PrefabInternal: {fileID: 0} 562 | m_GameObject: {fileID: 1431631644} 563 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 564 | m_LocalPosition: {x: 0, y: 0, z: 0} 565 | m_LocalScale: {x: 1, y: 1, z: 1} 566 | m_Children: [] 567 | m_Father: {fileID: 0} 568 | m_RootOrder: 7 569 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 570 | --- !u!1 &1594492347 571 | GameObject: 572 | m_ObjectHideFlags: 0 573 | m_PrefabParentObject: {fileID: 0} 574 | m_PrefabInternal: {fileID: 0} 575 | serializedVersion: 5 576 | m_Component: 577 | - component: {fileID: 1594492349} 578 | - component: {fileID: 1594492348} 579 | m_Layer: 0 580 | m_Name: LambdaEventListener (1) 581 | m_TagString: Untagged 582 | m_Icon: {fileID: 0} 583 | m_NavMeshLayer: 0 584 | m_StaticEditorFlags: 0 585 | m_IsActive: 1 586 | --- !u!114 &1594492348 587 | MonoBehaviour: 588 | m_ObjectHideFlags: 0 589 | m_PrefabParentObject: {fileID: 0} 590 | m_PrefabInternal: {fileID: 0} 591 | m_GameObject: {fileID: 1594492347} 592 | m_Enabled: 1 593 | m_EditorHideFlags: 0 594 | m_Script: {fileID: 11500000, guid: b2fced4d3f7f4534e98eee1c24c75c5a, type: 3} 595 | m_Name: 596 | m_EditorClassIdentifier: 597 | --- !u!4 &1594492349 598 | Transform: 599 | m_ObjectHideFlags: 0 600 | m_PrefabParentObject: {fileID: 0} 601 | m_PrefabInternal: {fileID: 0} 602 | m_GameObject: {fileID: 1594492347} 603 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 604 | m_LocalPosition: {x: 0, y: 0, z: 0} 605 | m_LocalScale: {x: 1, y: 1, z: 1} 606 | m_Children: [] 607 | m_Father: {fileID: 0} 608 | m_RootOrder: 6 609 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 610 | --- !u!1 &1833271762 611 | GameObject: 612 | m_ObjectHideFlags: 0 613 | m_PrefabParentObject: {fileID: 0} 614 | m_PrefabInternal: {fileID: 0} 615 | serializedVersion: 5 616 | m_Component: 617 | - component: {fileID: 1833271764} 618 | - component: {fileID: 1833271763} 619 | m_Layer: 0 620 | m_Name: SerializedClassAddToHolder 621 | m_TagString: Untagged 622 | m_Icon: {fileID: 0} 623 | m_NavMeshLayer: 0 624 | m_StaticEditorFlags: 0 625 | m_IsActive: 1 626 | --- !u!114 &1833271763 627 | MonoBehaviour: 628 | m_ObjectHideFlags: 0 629 | m_PrefabParentObject: {fileID: 0} 630 | m_PrefabInternal: {fileID: 0} 631 | m_GameObject: {fileID: 1833271762} 632 | m_Enabled: 1 633 | m_EditorHideFlags: 0 634 | m_Script: {fileID: 11500000, guid: fcb986b4ac703f14fa13df36c42f591b, type: 3} 635 | m_Name: 636 | m_EditorClassIdentifier: 637 | serializedClassList: 638 | - material: {fileID: 10302, guid: 0000000000000000f000000000000000, type: 0} 639 | value: 2 640 | zombieableGameObject: {fileID: 1388031379} 641 | - material: {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} 642 | value: 25 643 | zombieableGameObject: {fileID: 1040583105} 644 | --- !u!4 &1833271764 645 | Transform: 646 | m_ObjectHideFlags: 0 647 | m_PrefabParentObject: {fileID: 0} 648 | m_PrefabInternal: {fileID: 0} 649 | m_GameObject: {fileID: 1833271762} 650 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 651 | m_LocalPosition: {x: 0, y: 0, z: 0} 652 | m_LocalScale: {x: 1, y: 1, z: 1} 653 | m_Children: [] 654 | m_Father: {fileID: 0} 655 | m_RootOrder: 13 656 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 657 | --- !u!1 &2015780533 658 | GameObject: 659 | m_ObjectHideFlags: 0 660 | m_PrefabParentObject: {fileID: 0} 661 | m_PrefabInternal: {fileID: 0} 662 | serializedVersion: 5 663 | m_Component: 664 | - component: {fileID: 2015780535} 665 | - component: {fileID: 2015780534} 666 | m_Layer: 0 667 | m_Name: LambdaEventListener 668 | m_TagString: Untagged 669 | m_Icon: {fileID: 0} 670 | m_NavMeshLayer: 0 671 | m_StaticEditorFlags: 0 672 | m_IsActive: 1 673 | --- !u!114 &2015780534 674 | MonoBehaviour: 675 | m_ObjectHideFlags: 0 676 | m_PrefabParentObject: {fileID: 0} 677 | m_PrefabInternal: {fileID: 0} 678 | m_GameObject: {fileID: 2015780533} 679 | m_Enabled: 1 680 | m_EditorHideFlags: 0 681 | m_Script: {fileID: 11500000, guid: b2fced4d3f7f4534e98eee1c24c75c5a, type: 3} 682 | m_Name: 683 | m_EditorClassIdentifier: 684 | --- !u!4 &2015780535 685 | Transform: 686 | m_ObjectHideFlags: 0 687 | m_PrefabParentObject: {fileID: 0} 688 | m_PrefabInternal: {fileID: 0} 689 | m_GameObject: {fileID: 2015780533} 690 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 691 | m_LocalPosition: {x: 0, y: 0, z: 0} 692 | m_LocalScale: {x: 1, y: 1, z: 1} 693 | m_Children: [] 694 | m_Father: {fileID: 0} 695 | m_RootOrder: 5 696 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 697 | --- !u!1 &2095937741 698 | GameObject: 699 | m_ObjectHideFlags: 0 700 | m_PrefabParentObject: {fileID: 0} 701 | m_PrefabInternal: {fileID: 0} 702 | serializedVersion: 5 703 | m_Component: 704 | - component: {fileID: 2095937743} 705 | - component: {fileID: 2095937742} 706 | m_Layer: 0 707 | m_Name: ObjectAttachedToStack 708 | m_TagString: Untagged 709 | m_Icon: {fileID: 0} 710 | m_NavMeshLayer: 0 711 | m_StaticEditorFlags: 0 712 | m_IsActive: 1 713 | --- !u!114 &2095937742 714 | MonoBehaviour: 715 | m_ObjectHideFlags: 0 716 | m_PrefabParentObject: {fileID: 0} 717 | m_PrefabInternal: {fileID: 0} 718 | m_GameObject: {fileID: 2095937741} 719 | m_Enabled: 1 720 | m_EditorHideFlags: 0 721 | m_Script: {fileID: 11500000, guid: 5cf655d1bbe411d4cbb88b4c8aff9c58, type: 3} 722 | m_Name: 723 | m_EditorClassIdentifier: 724 | --- !u!4 &2095937743 725 | Transform: 726 | m_ObjectHideFlags: 0 727 | m_PrefabParentObject: {fileID: 0} 728 | m_PrefabInternal: {fileID: 0} 729 | m_GameObject: {fileID: 2095937741} 730 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 731 | m_LocalPosition: {x: 0, y: 0, z: 0} 732 | m_LocalScale: {x: 1, y: 1, z: 1} 733 | m_Children: [] 734 | m_Father: {fileID: 0} 735 | m_RootOrder: 10 736 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 737 | -------------------------------------------------------------------------------- /OldExample~/Scenes/Test.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ddc959ead8b7084286662f2400cf601 3 | timeCreated: 1506336392 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /OldExample~/TestScripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcf3a9a3cb70f2b47addffa70bca9285 3 | folderAsset: yes 4 | timeCreated: 1507834141 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d266671177081844acb2aeb785a22fa 3 | folderAsset: yes 4 | timeCreated: 1507849446 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/BasicStaticObjectStack.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | public class BasicStaticObjectStack : MonoBehaviour 5 | { 6 | public static Stack stackOfObjects = new Stack(); 7 | } 8 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/BasicStaticObjectStack.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 31eabf8ada56dc046a69958943dd7d14 3 | timeCreated: 1507836514 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/ObjectAttachedToArray.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | /// 5 | /// Hacks an new object onto the array. 6 | /// Fixed by remember to remove it OnDestroy, not easy with simple array :/ 7 | /// 8 | public class ObjectAttachedToArray : MonoBehaviour 9 | { 10 | 11 | private void Start() 12 | { 13 | Array.Resize(ref StaticArray.objectArray, StaticArray.objectArray.Length + 1); 14 | StaticArray.objectArray[StaticArray.objectArray.Length - 1] = this; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/ObjectAttachedToArray.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 608eb77b24f05144fb1a8eb93adf5dab 3 | timeCreated: 1507849673 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/ObjectAttachedToDictionary.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// Adds it to the dictionary with a unique key. 5 | /// Fixed by remember to remove it OnDestroy 6 | /// 7 | public class ObjectAttachedToDictionary : MonoBehaviour 8 | { 9 | 10 | private void Start() 11 | { 12 | StaticStringObjectDictionary.stringObjectDictionary.Add( 13 | StaticStringObjectDictionary.stringObjectDictionary.Count.ToString(), this); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/ObjectAttachedToDictionary.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20e517c916eee7d4fa9b084e03c2faac 3 | timeCreated: 1507849673 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/ObjectAttachedToList.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// Adds itself to the object list. 5 | /// Fixed by remember to remove it OnDestroy 6 | /// 7 | public class ObjectAttachedToList : MonoBehaviour 8 | { 9 | 10 | private void Start() 11 | { 12 | StaticObjectList.objectList.Add(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/ObjectAttachedToList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f62f1ae82a3dfa94a902046b8adfd533 3 | timeCreated: 1507849673 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/ObjectAttachedToStack.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// Pushes it onto . 5 | /// 6 | public class ObjectAttachedToStack : MonoBehaviour 7 | { 8 | 9 | private void Start() 10 | { 11 | StaticObjectStack.stackOfObjects.Push(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/ObjectAttachedToStack.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5cf655d1bbe411d4cbb88b4c8aff9c58 3 | timeCreated: 1507849673 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/StaticArray.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class StaticArray : MonoBehaviour 4 | { 5 | public static ObjectAttachedToArray[] objectArray = new ObjectAttachedToArray[0]; 6 | } 7 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/StaticArray.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0d4638b11bf6ad44f9b73f4c0f040915 3 | timeCreated: 1507849490 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/StaticObjectList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | public class StaticObjectList : MonoBehaviour 5 | { 6 | public static List objectList = new List(); 7 | } 8 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/StaticObjectList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49a5ac94ef8c02146b63288aa9e99cee 3 | timeCreated: 1507849460 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/StaticObjectStack.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | public class StaticObjectStack : MonoBehaviour 5 | { 6 | public static Stack stackOfObjects = new Stack(); 7 | } 8 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/StaticObjectStack.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8ca316a2cbdbf6349b7de50a1eb08046 3 | timeCreated: 1507836514 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/StaticStringObjectDictionary.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | public class StaticStringObjectDictionary : MonoBehaviour 5 | { 6 | public static Dictionary stringObjectDictionary = new Dictionary(); 7 | } 8 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Arrays/StaticStringObjectDictionary.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6574261f27494cf48b034c91ed50eb90 3 | timeCreated: 1507849480 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/BasedOnIgnoredTypeParam.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// Classes based on will get scanned. 5 | /// All inherited member variables also get scanned. 6 | /// 7 | public class BasedOnIgnoredTypeParam : IgnoredTypeParam 8 | { 9 | 10 | public void Start() 11 | { 12 | BasicStaticObjectStack.stackOfObjects.Push(this); 13 | notIgnoredInDerivedClass = new TextureHolder(); 14 | notIgnoredInDerivedClass.texture = new Texture2D(1024, 1024, TextureFormat.RGBA32, false); 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/BasedOnIgnoredTypeParam.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ce34d95668afa90449a2cf8b63f55d66 3 | timeCreated: 1507835743 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/ClearKnownZombies.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | using UnityEngine; 5 | using UnityEngine.SceneManagement; 6 | 7 | public class ClearKnownZombies : MonoBehaviour { 8 | 9 | [SerializeField] 10 | StaticEvents staticEventsObject =null; 11 | 12 | private void Start() 13 | { 14 | BasicStaticObjectStack.stackOfObjects.Clear(); 15 | StaticArray.objectArray = new ObjectAttachedToArray[0]; 16 | StaticObjectList.objectList.Clear(); 17 | StaticObjectStack.stackOfObjects.Clear(); 18 | StaticStringObjectDictionary.stringObjectDictionary.Clear(); 19 | 20 | SerializedClassHolder.serializedClassList.Clear(); 21 | if (ReferenceHolderHolder.holderReference) 22 | { 23 | ReferenceHolderHolder.holderReference.objectReference = null; 24 | } 25 | ReferenceHolderHolder.holderReference = null; 26 | 27 | staticEventsObject.RemoveAllEventsHack(); 28 | StaticEvents.DoAThing(); 29 | StaticEvents.DoAThingPlusX(1); 30 | 31 | Debug.Log("Zombies Cleaned Up"); 32 | Resources.UnloadUnusedAssets(); 33 | SceneManager.LoadScene("Boot"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/ClearKnownZombies.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 416828ca21d758a478a0c2dc93e6777b 3 | timeCreated: 1510932292 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97fd8da5b5ff13d47b473d74d6ba247f 3 | folderAsset: yes 4 | timeCreated: 1507844605 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases/BadEqualsImplementation.cs: -------------------------------------------------------------------------------- 1 |  2 | public class BadEqualsImplementation 3 | { 4 | protected static BadEquals m_BadEquals = new BadEquals(); 5 | } 6 | 7 | /// 8 | /// Bad implementation of .Equals. 9 | /// 10 | /// Means it will fail when .Equals is invoked against something other than "BadEquals". 11 | /// This means we can't check if we have already scaned the object, so we just ignore it. 12 | /// 13 | /// Logged with 14 | /// 15 | public struct BadEquals 16 | { 17 | public int x; 18 | public int y; 19 | public int z; 20 | 21 | // Example Taken From bug found in 3rdparty tool. 22 | public override bool Equals(System.Object o) 23 | { 24 | if (o == null) 25 | return false; 26 | BadEquals rhs = (BadEquals)o; // throws an exception when not BadEquals. 27 | 28 | return x == rhs.x && 29 | y == rhs.y && 30 | z == rhs.z; 31 | } 32 | 33 | public override int GetHashCode() 34 | { 35 | return x * 73856093 ^ y * 19349663 ^ z * 83492791; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases/BadEqualsImplementation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0bb66e6168013664db5d67c4a6757a9f 3 | timeCreated: 1507212592 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases/FalsePositive.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Overriding ToString and returning "null" specifically causes a false positive. 3 | /// 4 | /// This is due to the way Zombie Objects are detected. 5 | /// 6 | /// See 7 | /// 8 | public class FalsePositiveOverrideString 9 | { 10 | 11 | public static FalsePositiveOverrideString falsePositiveExample = new FalsePositiveOverrideString(); 12 | 13 | public override string ToString() 14 | { 15 | return "null"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases/FalsePositive.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f41a0c8cef331e046aa7923cfa808c53 3 | timeCreated: 1507834252 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases/IgnoredTypeParam.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// The Value of T can't be determined so it gets ignored when scanning all the types from reflection. 5 | /// 6 | /// 7 | public class IgnoredTypeParam : MonoBehaviour where T : MonoBehaviour 8 | { 9 | public TextureHolder notIgnoredInDerivedClass; 10 | } 11 | 12 | public struct TextureHolder 13 | { 14 | public Texture2D texture; 15 | } -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases/IgnoredTypeParam.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98159c0d2bdf85b47942a5e7f5d67819 3 | timeCreated: 1507835743 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases/UnsafePointer.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// C# Unsafe code and Pointers will be ignored in scans. 3 | /// This Requires -unsafe added to the msc.rsp file, Unity 2017.1 or newer doesn't require this. 4 | /// Decent Explanation of steps for Unity. 5 | /// https://stackoverflow.com/questions/39132079/how-to-use-unsafe-code-unity/39132664#39132664 6 | /// 7 | public class UnsafePointer 8 | { 9 | 10 | #if UNITY_2017_1_OR_NEWER // comment out define once added -unsafe to msc.rsp 11 | unsafe public static Unsafe* unsafePointer; 12 | #endif 13 | } 14 | 15 | public struct Unsafe 16 | { 17 | public int test; 18 | } 19 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/EdgeCases/UnsafePointer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0dd57edc0b7f7949848a7efa296c14e 3 | timeCreated: 1507843849 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Events.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1fdf67291d5ece74983908c5181e08ce 3 | folderAsset: yes 4 | timeCreated: 1507849420 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Events/EventListener.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// Attachs itself to an event but doesn't remove itself when destroyed. 5 | /// 6 | public class EventListener : MonoBehaviour 7 | { 8 | Texture2D textureAsset; 9 | 10 | void Start() 11 | { 12 | StaticEvents.OnDoAThing += TheThingToDo; 13 | } 14 | 15 | private void TheThingToDo() 16 | { 17 | textureAsset = new Texture2D(1024, 1024, TextureFormat.RGBA32, false); 18 | Debug.Log("Created Texture: " + textureAsset.ToString()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Events/EventListener.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ee84d55d2af51945b73b9da96366f0f 3 | timeCreated: 1507849342 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Events/LambdaEventListener.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// Attachs itself to an event but doesn't remove itself when destroyed. 5 | /// Lambda's can show up differently as no predefined function associated. 6 | /// 7 | public class LambdaEventListener : MonoBehaviour 8 | { 9 | 10 | Texture2D textureAsset; 11 | 12 | void Start() 13 | { 14 | StaticEvents.OnDoAThingPlusX += (x) => 15 | { 16 | 17 | textureAsset = new Texture2D(1024, 1024, TextureFormat.RGBA32, false); 18 | Debug.Log("Created Texture: " + textureAsset.ToString()); 19 | }; 20 | // if no refrence to a member variable of this class, will create a standalone class with 21 | // function (x) => 22 | //textureAsset = new Texture2D(1024, 1024, TextureFormat.RGBA32, false); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Events/LambdaEventListener.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b2fced4d3f7f4534e98eee1c24c75c5a 3 | timeCreated: 1507849342 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Events/StaticEvents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Reflection; 4 | using UnityEngine; 5 | 6 | public class StaticEvents : MonoBehaviour 7 | { 8 | 9 | public delegate void EventHandlerForThing(); 10 | 11 | public static event EventHandlerForThing OnDoAThing; 12 | 13 | public static event EventHandlerForThing OnDoNothingTesterDontListen; 14 | 15 | public delegate void EventHandlerForThingPlusX(int x); 16 | 17 | public static event EventHandlerForThingPlusX OnDoAThingPlusX; 18 | 19 | public static void DoAThing() 20 | { 21 | // notify all listeners to event. 22 | if (OnDoAThing != null) 23 | { 24 | OnDoAThing(); 25 | } 26 | } 27 | 28 | public static void DoNothingListening(int x) 29 | { 30 | // notify all listeners to event. 31 | if (OnDoNothingTesterDontListen != null) 32 | { 33 | OnDoNothingTesterDontListen(); 34 | } 35 | } 36 | 37 | public static void DoAThingPlusX(int x) 38 | { 39 | // notify all listeners to event. 40 | if (OnDoAThingPlusX != null) 41 | { 42 | OnDoAThingPlusX(x); 43 | } 44 | } 45 | 46 | public void RemoveAllEventsHack() 47 | { 48 | // NOT TO BE USED, just for debuging, these should be removed properly from the object that assigns it. 49 | if (OnDoAThing != null) 50 | { 51 | foreach (Delegate onDoAThingDelegate in OnDoAThing.GetInvocationList()) 52 | { 53 | OnDoAThing -= (EventHandlerForThing)onDoAThingDelegate; 54 | } 55 | } 56 | if (OnDoAThingPlusX != null) 57 | { 58 | foreach (Delegate onDoAThingDelegate in OnDoAThingPlusX.GetInvocationList()) 59 | { 60 | OnDoAThingPlusX -= (EventHandlerForThingPlusX)onDoAThingDelegate; 61 | } 62 | } 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/Events/StaticEvents.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f2e9f55618de0d64dadb046e01955efd 3 | timeCreated: 1507848969 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/References.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ec6583d937b8fd34fa139eb38182cd83 3 | folderAsset: yes 4 | timeCreated: 1507850909 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/References/ObjectAttachedToReference.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class ObjectAttachedToReference : MonoBehaviour 4 | { 5 | [SerializeField] 6 | ReferenceHolder m_ReferenceHolder; 7 | private void Start() 8 | { 9 | m_ReferenceHolder.objectReference = this; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/References/ObjectAttachedToReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f836d54c3f8ab6149a6295fac756c628 3 | timeCreated: 1507850881 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/References/ReferenceHolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | public class ReferenceHolder : MonoBehaviour 5 | { 6 | 7 | [NonSerialized] 8 | public ObjectAttachedToReference objectReference; 9 | 10 | private void Start() 11 | { 12 | ReferenceHolderHolder.holderReference = this; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/References/ReferenceHolder.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aef76b1d56037e54cac34a199bbc285e 3 | timeCreated: 1507850587 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/References/ReferenceHolderHolder.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class ReferenceHolderHolder : MonoBehaviour 4 | { 5 | public static ReferenceHolder holderReference; 6 | } 7 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/References/ReferenceHolderHolder.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2da075edfac5b743943f8fd053b5707 3 | timeCreated: 1507850925 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/SerializedClass.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4a802145a10fec946a70b2fe99fda1be 3 | folderAsset: yes 4 | timeCreated: 1509469898 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/SerializedClass/SerializedClass.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | [System.Serializable] 4 | public class SerializedClass 5 | { 6 | [SerializeField] 7 | Material material; 8 | 9 | [SerializeField] 10 | int value; 11 | 12 | [SerializeField] 13 | GameObject zombieableGameObject; 14 | } 15 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/SerializedClass/SerializedClass.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a7706a3d66f94bc4999127c4efdfdc4d 3 | timeCreated: 1509469907 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/SerializedClass/SerializedClassAddToHolder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class SerializedClassAddToHolder : MonoBehaviour 6 | { 7 | 8 | [SerializeField] 9 | SerializedClass[] serializedClassList = new SerializedClass[2]; 10 | 11 | private void Start() 12 | { 13 | foreach (var serializedClass in serializedClassList) 14 | { 15 | SerializedClassHolder.serializedClassList.Add(serializedClass); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/SerializedClass/SerializedClassAddToHolder.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcb986b4ac703f14fa13df36c42f591b 3 | timeCreated: 1509469943 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/SerializedClass/SerializedClassHolder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class SerializedClassHolder : MonoBehaviour 6 | { 7 | 8 | public static List serializedClassList = new List(); 9 | } 10 | -------------------------------------------------------------------------------- /OldExample~/TestScripts/SerializedClass/SerializedClassHolder.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba7f184fdfdcc4e47bd18137906d2a28 3 | timeCreated: 1509469920 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /OldExample~/ZombieSceneLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | using UnityEngine.EventSystems; 4 | using UnityEngine.SceneManagement; 5 | using UnityEngine.UI; 6 | 7 | public class ZombieSceneLoader : MonoBehaviour 8 | { 9 | enum SceneState 10 | { 11 | kUnloaded, 12 | kUnloading, 13 | kLoaded, 14 | kLoading 15 | } 16 | 17 | [SerializeField] 18 | string m_SceneToLoadAndUnload = ""; 19 | 20 | [SerializeField] 21 | Button m_Button; 22 | 23 | [SerializeField] 24 | Text m_ButtonText; 25 | 26 | 27 | SceneState m_sceneState = SceneState.kUnloaded; 28 | 29 | private void Start() 30 | { 31 | m_ButtonText.text = "LoadScene"; 32 | m_Button.onClick.AddListener(CycleScene); 33 | } 34 | 35 | private void OnDestroy() 36 | { 37 | m_Button.onClick.RemoveAllListeners(); 38 | } 39 | 40 | private void CycleScene() 41 | { 42 | switch (m_sceneState) 43 | { 44 | case SceneState.kUnloaded: 45 | StartCoroutine(LoadScene()); 46 | break; 47 | case SceneState.kLoaded: 48 | StartCoroutine(UnloadScene()); 49 | break; 50 | default: 51 | break; 52 | } 53 | } 54 | 55 | private IEnumerator UnloadScene() 56 | { 57 | m_sceneState = SceneState.kUnloading; 58 | m_Button.interactable = false; 59 | m_ButtonText.text = "Unloading"; 60 | yield return SceneManager.UnloadSceneAsync(m_SceneToLoadAndUnload); 61 | yield return Resources.UnloadUnusedAssets(); 62 | m_ButtonText.text = "LoadScene"; 63 | m_Button.interactable = true; 64 | EventSystem.current.SetSelectedGameObject(m_Button.gameObject); 65 | m_sceneState = SceneState.kUnloaded; 66 | } 67 | 68 | private IEnumerator LoadScene() 69 | { 70 | m_sceneState = SceneState.kLoading; 71 | m_Button.interactable = false; 72 | m_ButtonText.text = "Loading"; 73 | yield return SceneManager.LoadSceneAsync(m_SceneToLoadAndUnload, LoadSceneMode.Additive); 74 | m_ButtonText.text = "UnLoadScene"; 75 | m_Button.interactable = true; 76 | EventSystem.current.SetSelectedGameObject(m_Button.gameObject); 77 | m_sceneState = SceneState.kLoaded; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /OldExample~/ZombieSceneLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 61c26c9030a36d44bb2f33e8181612a7 3 | timeCreated: 1506336940 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zombie Object Detector 2 | 3 | Scripts to detect and diagnose zombie objects. 4 | 5 | ## Important Notice 6 | 7 | Version 1.1 of the _com.unity.memoryprofiler_ package now includes support for detecting the same types of objects as this tool. See [Managed Shell Objects](https://docs.unity3d.com/Packages/com.unity.memoryprofiler@1.1/manual/managed-shell-objects.html) in the package documentation. I expect that this will allow me to deprecate this tool at some point in the future. - @peter-pimley-unity 8 | 9 | ## Quick Start 10 | 11 | ### Package import 12 | 13 | In the Unity Package Manager window, select `Add package from git URL` and add the URL as shown in the green Code button in GitHub. For example `https://github.com/Unity-Technologies/ZombieObjectDetector.git`. 14 | 15 | ### Scene Configuration 16 | 17 | In a scene where you would like to run zombie object detection, place a GameObject with two components; a `ZombieObjectDetector` and a `ZombieObjectDetector_Report_TTY`. The two components must be on the same GameObject. 18 | 19 | ![A screenshot of the Unity Inspector window, showing a ZombieObjectDetector and a ZombieObjectDetector_Report_TTY](Documentation~/Inspector.png) 20 | 21 | ### Detection 22 | 23 | To run detection in play mode in the editor, simply click `Log Zombies` in the Inspector window. 24 | 25 | To run detection in a standalone build, call the method `RunZombieObjectDetection` on the ZombieObjectDetector component. The output will appear in the TTY (wherever `Debug.Log` goes on your target platform). 26 | 27 | #### Memory 28 | 29 | The detection process uses a great deal of managed memory. If your target platform has any sort of developer option to enable extra memory for development, then you should enable it. 30 | 31 | #### Avoiding tests that cause reproduceable crashes 32 | 33 | On some platforms (particularly consoles), detection has sometimes crashed reproducably when it tests objects of a particular type. To avoid this, add whatever types are causing problems to the inspector field `Do not recurse into these Types during search`. The values are all C# regular expressions. See [here](https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference) for reference. After adding a regular expression to the list you can type any string into the `Test` field, and it will tell you whether that string matches any of the regular expressions above it. 34 | 35 | To discover exactly which type(s) are causing the crash in the first place, check the `Report Test` checkbox on the `ZombieObjectDetector_Report_TTY`. This will print a `Debug.Log` line before _every single object_ that is tested. This is incredibly verbose and slow, but it will show you exactly which object (and type) caused the crash. 36 | 37 | # Background 38 | 39 | Many of the user-facing C# classes in Unity act as lightweight handles to data that is actually held internally in native code. The most obvious example is `UnityEngine.GameObject`. Because C# GameObject instances **are C# objects**, they are subject to the usual garbage collection rules of the C# language; they will stay alive until they are no longer referenced by anything else, and then some time after that they will be collected by the garbage collector. 40 | 41 | However the _actual data_ for these objects is held in natively-allocated memory by the native player executable, and the lifespan of this data and memory is entirely deterministic. The memory holding the data for a GameObject will be deleted when the GameObject is `Destroy()`-ed manually or when the scene is exited. 42 | 43 | This means that there is an opportunity for a C# object to outlive its native counterpart. The C# instance can be "kept alive" by virtue of being referenced by another C# object, even after the native-side object has been destroyed. 44 | 45 | For example a developer might keep a `List` of GameObjects that are interesting to them in some way, such as the enemies in a shoot-em-up. Suppose the developer has a line of code passes the enemy GameObject in to `GameObject.Destroy` when its health reaches zero. At that point, if the developer fails also to remove it from their `List`, then the C# instance will remain referenced and alive **even after its native counterpart has been destroyed**. 46 | 47 | The class GameObject has a unique special trick which can make this situation even more difficult to diagnose. A C# GameObject can detect if its native counterpart is no longer alive, and when it is in this special case it will return `true` if it is compared with null. 48 | 49 | Therefore in the code: 50 | ``` 51 | GameObject obj = ... 52 | if (obj != null) { 53 | ``` 54 | ... the GameObject `obj` will know if its native counterpart has been destroyed, and will _not_ enter the `if` statement in that case. 55 | 56 | There is a good discussion of this situation in this blog post from 2014. As of 2022 nothing has changed in this regard. https://blogs.unity3d.com/2014/05/16/custom-operator-should-we-keep-it/. Specifically the paragraph labelled "purpose two": 57 | 58 | >When you get a c# object of type "GameObject", it contains almost nothing. this is because Unity is a C/C++ engine. All the actual information about this GameObject (its name, the list of components it has, its HideFlags, etc) lives in the c++ side. The only thing that the c# object has is a pointer to the native object. We call these c# objects "wrapper objects". The lifetime of these c++ objects like GameObject and everything else that derives from UnityEngine.Object is explicitly managed. These objects get destroyed when you load a new scene. Or when you call Object.Destroy(myObject); on them. Lifetime of c# objects gets managed the c# way, with a garbage collector. This means that it's possible to have a c# wrapper object that still exists, that wraps a c++ object that has already been destroyed. If you compare this object to null, our custom == operator will return "true" in this case, even though the actual c# variable is in reality not really null. 59 | 60 | 61 | # Interpreting the output 62 | 63 | ## Output format 64 | For any zombie object encountered, the message in the TTY will be of the form: 65 | ``` 66 | Found zombie of type {t}, at {path} 67 | ``` 68 | 69 | ... where _t_ is the type of the zombie object, and _path_ is the period-separated route taken from one class' static field to that object. This is one of _possibly-many_ references keeping that object alive. Once an object is tested via one route, it will not be tested again via other routes. 70 | 71 | The first component of _path_ will be a class name. The next component will be a static field of that class, and then each subsequent component will be a field of some object leading up to the zombie object. 72 | 73 | ## Effective interpretation 74 | 75 | When a zombie object is discovered, it is possible that that object itself contains references to more objects, causing those objects also to be reported as zombies. This means that a single fix in code can "fix" a huge number of reported objects (hundreds, or even more). 76 | 77 | For this reason it is best to treat the tool somewhat like a C compiler. Every time it reports errors, fix _just the first one_ or _just the last one_. Then re-run the tool to see what effect that single code change produced. 78 | 79 | # Common Causes 80 | 81 | ### Singleton Pattern 82 | 83 | It is common for a singleton class `Thing` to have a static field `private static Thing instance;` along with `instance = this` in `Awake`. For an object that stays alive for the entire duration of the executable this is fine. However consider an object that is only alive for one run of a level, and dies when going back to the frontend (e.g. some sort of `CameraManager` in a 3rd person platformer). If you do not also `instance = null` in `OnDestroy`, then the object will be kept alive when the player returns to the frontend. 84 | 85 | ### C# Events between objects with different lifetimes. 86 | 87 | Suppose you have an instance of a class called something like `SaveDataManager` that stays alive for the entire duration of the executable. It might have a C# event `public event System.Action PrepareToSave` which is fired when the game is about to save the player's progress. Separately, suppose you also have a class `Enemy` for a short-lived NPC (e.g. in a shoot-em-up). `Enemy` might want to know when a save is about to happen. The code might look like this: 88 | 89 | ``` 90 | class Enemy : MonoBehaviour 91 | { 92 | void Awake () { 93 | SaveDataManager saveMan = ...; // Maybe a global, maybe a [SerializeField], etc. 94 | saveMan.PrepareToSave += OnPrepareToSave; 95 | } 96 | 97 | void OnPrepareToSave () { 98 | // ... 99 | } 100 | 101 | // Code continues below 102 | ``` 103 | 104 | This is C#'s idiomatic support for the [Observer Pattern](https://en.wikipedia.org/wiki/Observer_pattern). It is a very common idiom in C#, and in games generally. **The problem is if the observer has a lifetime that is _shorter_ than the subject**. In our example it means it is a problem if the `Enemy` has a shorter lifetime than the `SaveDataManager`, which _is_ the case here; the `SaveDataManager` lives forever, and the `Enemy` lives for just a short while. In this case, if the observer (the Enemy) fails to detach its listener from the subject at the end of its normal lifetime, then it will be "kept alive" by the backing field of the subject's event. 105 | 106 | The example above can be fixed by detaching the listener at the end of the Enemy's normal lifetime: 107 | ``` 108 | // Code continues from above 109 | 110 | void OnDestroy() 111 | { 112 | saveMan.PrepareToSave -= OnPrepareToSave; 113 | } 114 | } 115 | ``` 116 | 117 | A variation of the above is when a C# event is `static` in its enclosing class. Perhaps there is no instance of that class at all. Again, the observer must detach its listeners from the subject (_i.e._ from the C# event) when it detects the end of its expected lifetime. 118 | 119 | 120 | # How this tool determines Zombie Objects 121 | 122 | The tool attempts to traverse every C# object in existence, and tests each one to see if it is a zombie. The challenge of finding every object is split into two parts. The first part is to find all classes (all _Types_) and then, for each class, to gather every static field that could point to an object. These are the start points of the search. The second half is to recurse for each object; testing that object itself and then recursing into every one of its (non-static) fields. 123 | 124 | In both cases, reflection is used to gather all the fields of the object being tested. Fields that are references to _other objects_ (including arrays and C# events) are recursed into. Fields of basic types such as `int` are ignored. 125 | 126 | An object is considered a zombie if it satisfies all of the following criteria: 127 | * It is not *actually* null. 128 | * It is a subclass of `UnityEngine.Object`. 129 | * When you compare it to null using `(obj as UnityEngine.Object) == null`, it returns `true`. 130 | 131 | 132 | # Credits 133 | 134 | The project was started by Stewart McCready ([@StewMcc](https://github.com/StewMcc)) during his internship at Unity, with subsequent work by Peter Pimley ([@peter-pimley-unity](https://github.com/peter-pimley-unity)). 135 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b316ad6c026e6704992497c383f596c2 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 511f57ee31304784eaba6a1bc9239b6f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/TypeHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.Assertions; 4 | 5 | 6 | namespace CSharpZombieDetector 7 | { 8 | 9 | /// 10 | /// Helper for testing type information. 11 | /// 12 | /// Can test for zombie objects, and whether a string type exists in the assembly. 13 | /// 14 | public class TypeHelper 15 | { 16 | 17 | /// 18 | /// Determines if a type can be a possible Zombie object. 19 | /// 20 | public static bool IsPotentialZombieType(Type type) 21 | { 22 | if (type == null) 23 | return false; 24 | if (type.IsValueType) // Primitives and structs. 25 | return false; 26 | 27 | if (Type.GetTypeCode(type) != TypeCode.Object) 28 | return false; 29 | 30 | // For a nullable "Something?", recurse into the "Something" part. 31 | if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) 32 | return IsPotentialZombieType(Nullable.GetUnderlyingType(type)); 33 | 34 | return true; 35 | } 36 | 37 | 38 | /// 39 | /// Tests the IsZombieType method. 40 | /// 41 | public static void TestIsZombieType() 42 | { 43 | // Note* Testing with GetType because of handling with non-numerics. See: 44 | // http://msdn.microsoft.com/en-us/library/ms366789.aspx 45 | 46 | //*** Not Zombies *** 47 | Assert.IsFalse(IsPotentialZombieType(null)); 48 | Assert.IsFalse(IsPotentialZombieType(typeof(DBNull))); 49 | Assert.IsFalse(IsPotentialZombieType(typeof(DateTime))); 50 | Assert.IsFalse(IsPotentialZombieType(DBNull.Value.GetType())); 51 | Assert.IsFalse(IsPotentialZombieType((new DateTime(2009, 1, 1)).GetType())); 52 | // Using GetType - nullable non-numeric types 53 | DateTime? nullableDateTime = new DateTime(2009, 1, 1); 54 | Assert.IsFalse(IsPotentialZombieType(nullableDateTime.GetType())); 55 | Assert.IsFalse(IsPotentialZombieType(typeof(DateTime?))); 56 | 57 | // strings and bools 58 | Assert.IsFalse(IsPotentialZombieType(typeof(bool))); 59 | Assert.IsFalse(IsPotentialZombieType(typeof(char))); 60 | Assert.IsFalse(IsPotentialZombieType(typeof(string))); 61 | Assert.IsFalse(IsPotentialZombieType(typeof(bool?))); 62 | Assert.IsFalse(IsPotentialZombieType(typeof(char?))); 63 | Assert.IsFalse(IsPotentialZombieType(true.GetType())); 64 | Assert.IsFalse(IsPotentialZombieType('a'.GetType())); 65 | Assert.IsFalse(IsPotentialZombieType(string.Empty.GetType())); 66 | bool? nullableBool = true; 67 | Assert.IsFalse(IsPotentialZombieType(nullableBool.GetType())); 68 | char? nullableChar = ' '; 69 | Assert.IsFalse(IsPotentialZombieType(nullableChar.GetType())); 70 | // Numeric types 71 | Assert.IsFalse(IsPotentialZombieType(typeof(byte))); 72 | Assert.IsFalse(IsPotentialZombieType(typeof(decimal))); 73 | Assert.IsFalse(IsPotentialZombieType(typeof(double))); 74 | Assert.IsFalse(IsPotentialZombieType(typeof(short))); 75 | Assert.IsFalse(IsPotentialZombieType(typeof(int))); 76 | Assert.IsFalse(IsPotentialZombieType(typeof(long))); 77 | Assert.IsFalse(IsPotentialZombieType(typeof(sbyte))); 78 | Assert.IsFalse(IsPotentialZombieType(typeof(float))); 79 | Assert.IsFalse(IsPotentialZombieType(typeof(ushort))); 80 | Assert.IsFalse(IsPotentialZombieType(typeof(uint))); 81 | Assert.IsFalse(IsPotentialZombieType(typeof(ulong))); 82 | // Nullable numeric types 83 | Assert.IsFalse(IsPotentialZombieType(typeof(byte?))); 84 | Assert.IsFalse(IsPotentialZombieType(typeof(decimal?))); 85 | Assert.IsFalse(IsPotentialZombieType(typeof(double?))); 86 | Assert.IsFalse(IsPotentialZombieType(typeof(short?))); 87 | Assert.IsFalse(IsPotentialZombieType(typeof(int?))); 88 | Assert.IsFalse(IsPotentialZombieType(typeof(long?))); 89 | Assert.IsFalse(IsPotentialZombieType(typeof(sbyte?))); 90 | Assert.IsFalse(IsPotentialZombieType(typeof(float?))); 91 | Assert.IsFalse(IsPotentialZombieType(typeof(ushort?))); 92 | Assert.IsFalse(IsPotentialZombieType(typeof(uint?))); 93 | Assert.IsFalse(IsPotentialZombieType(typeof(ulong?))); 94 | // Using GetType - numeric types 95 | Assert.IsFalse(IsPotentialZombieType((new byte()).GetType())); 96 | Assert.IsFalse(IsPotentialZombieType(43.2m.GetType())); 97 | Assert.IsFalse(IsPotentialZombieType(43.2d.GetType())); 98 | Assert.IsFalse(IsPotentialZombieType(((short)2).GetType())); 99 | Assert.IsFalse(IsPotentialZombieType(((int)2).GetType())); 100 | Assert.IsFalse(IsPotentialZombieType(((long)2).GetType())); 101 | Assert.IsFalse(IsPotentialZombieType(((sbyte)2).GetType())); 102 | Assert.IsFalse(IsPotentialZombieType(2f.GetType())); 103 | Assert.IsFalse(IsPotentialZombieType(((ushort)2).GetType())); 104 | Assert.IsFalse(IsPotentialZombieType(((uint)2).GetType())); 105 | Assert.IsFalse(IsPotentialZombieType(((ulong)2).GetType())); 106 | 107 | uint test = 2; 108 | Assert.IsFalse(IsPotentialZombieType(((object)test).GetType())); 109 | // Using GetType - nullable numeric types 110 | byte? nullableByte = 12; 111 | Assert.IsFalse(IsPotentialZombieType(nullableByte.GetType())); 112 | decimal? nullableDecimal = 12.2m; 113 | Assert.IsFalse(IsPotentialZombieType(nullableDecimal.GetType())); 114 | double? nullableDouble = 12.32; 115 | Assert.IsFalse(IsPotentialZombieType(nullableDouble.GetType())); 116 | short? nullableInt16 = 12; 117 | Assert.IsFalse(IsPotentialZombieType(nullableInt16.GetType())); 118 | short? nullableInt32 = 12; 119 | Assert.IsFalse(IsPotentialZombieType(nullableInt32.GetType())); 120 | short? nullableInt64 = 12; 121 | Assert.IsFalse(IsPotentialZombieType(nullableInt64.GetType())); 122 | sbyte? nullableSByte = 12; 123 | Assert.IsFalse(IsPotentialZombieType(nullableSByte.GetType())); 124 | float? nullableSingle = 3.2f; 125 | Assert.IsFalse(IsPotentialZombieType(nullableSingle.GetType())); 126 | ushort? nullableUInt16 = 12; 127 | Assert.IsFalse(IsPotentialZombieType(nullableUInt16.GetType())); 128 | ushort? nullableUInt32 = 12; 129 | Assert.IsFalse(IsPotentialZombieType(nullableUInt32.GetType())); 130 | ushort? nullableUInt64 = 12; 131 | Assert.IsFalse(IsPotentialZombieType(nullableUInt64.GetType())); 132 | 133 | //*** Possible Zombies *** 134 | 135 | Assert.IsTrue(IsPotentialZombieType(typeof(object))); 136 | Assert.IsTrue(IsPotentialZombieType((new object()).GetType())); 137 | 138 | // Arrays of numeric and non-numeric types 139 | Assert.IsTrue(IsPotentialZombieType(typeof(object[]))); 140 | Assert.IsTrue(IsPotentialZombieType(typeof(DBNull[]))); 141 | Assert.IsTrue(IsPotentialZombieType(typeof(bool[]))); 142 | Assert.IsTrue(IsPotentialZombieType(typeof(char[]))); 143 | Assert.IsTrue(IsPotentialZombieType(typeof(DateTime[]))); 144 | Assert.IsTrue(IsPotentialZombieType(typeof(string[]))); 145 | Assert.IsTrue(IsPotentialZombieType(typeof(byte[]))); 146 | Assert.IsTrue(IsPotentialZombieType(typeof(decimal[]))); 147 | Assert.IsTrue(IsPotentialZombieType(typeof(double[]))); 148 | Assert.IsTrue(IsPotentialZombieType(typeof(short[]))); 149 | Assert.IsTrue(IsPotentialZombieType(typeof(int[]))); 150 | Assert.IsTrue(IsPotentialZombieType(typeof(long[]))); 151 | Assert.IsTrue(IsPotentialZombieType(typeof(sbyte[]))); 152 | Assert.IsTrue(IsPotentialZombieType(typeof(float[]))); 153 | Assert.IsTrue(IsPotentialZombieType(typeof(ushort[]))); 154 | Assert.IsTrue(IsPotentialZombieType(typeof(uint[]))); 155 | Assert.IsTrue(IsPotentialZombieType(typeof(ulong[]))); 156 | 157 | 158 | 159 | Debug.Log("Finished ZombieType Test"); 160 | } 161 | 162 | } 163 | 164 | } -------------------------------------------------------------------------------- /Runtime/TypeHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f90e2af224e2b24e9a2e0479aaf0828 3 | timeCreated: 1507069077 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Runtime/Unity.ZombieObjectDetector.Runtime.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Unity.ZombieObjectDetector.Runtime" 3 | } 4 | -------------------------------------------------------------------------------- /Runtime/Unity.ZombieObjectDetector.Runtime.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5adcca6eb4c13094e98ff197186a0ca6 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/ZombieObjectDetector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text.RegularExpressions; 7 | using UnityEngine; 8 | 9 | namespace CSharpZombieDetector 10 | { 11 | 12 | public class ZombieObjectDetector : MonoBehaviour 13 | { 14 | 15 | [SerializeField] 16 | private bool m_runOnStart = false; 17 | 18 | // Types within Assemblies whose name matches any of the following patterns will not be used as starting points. 19 | [SerializeField] 20 | private string[] m_ignoreAssemblyPatterns = DefaultAssemblyIgnorePatterns; 21 | 22 | public static readonly string[] DefaultAssemblyIgnorePatterns = { 23 | "^Unity\\.", "^UnityEngine", "^UnityEditor", "^mscorlib$", "^System", "^Mono\\." 24 | }; 25 | 26 | 27 | 28 | // Types whose name matches any of these regex patterns will not be used as starting points. 29 | [SerializeField] 30 | private string[] m_ignoreTypePatterns = DefaultIgnoreTypePatterns; 31 | 32 | public static readonly string[] DefaultIgnoreTypePatterns = 33 | { 34 | "^System\\.", "^Unity\\.", "^UnityEngine\\.", "^UnityEditor\\.", "^Mono\\." 35 | }; 36 | 37 | 38 | // Types whose name matches any of these regex patterns will be skipped from the recursion. 39 | [SerializeField] 40 | private string[] m_ignoreTypePatternsDuringSearch; 41 | 42 | // An exception will be thrown if we recurse deeper than this. 43 | // (Avoids crashing the editor/player) 44 | [SerializeField] 45 | private int m_maxDepth = 200; 46 | 47 | 48 | 49 | 50 | 51 | // An individual invocation of a search. 52 | public class SearchContext 53 | { 54 | 55 | public struct TestInfo 56 | { 57 | public object obj; 58 | public Type type; 59 | public FieldInfo fieldInfo; 60 | }; 61 | public event System.Action TestingObjectField; 62 | 63 | public event System.Action CaughtExceptionAndContinued; 64 | 65 | public event System.Action ZombieHit; 66 | public event System.Action SearchCompleted; 67 | 68 | /// 69 | /// Fired every 1024 objects. 70 | /// Allows for progress reporting, e.g. to prove the process has not hung. 71 | /// 72 | public event System.Action MadeProgress; 73 | 74 | 75 | private HashSet m_scannedObjects = new HashSet(); 76 | private Stack m_fieldInfos = new Stack(); 77 | 78 | /// 79 | /// Note that the order is "backwards"; the most recent field is first, 80 | /// and the static field where the search started is last. 81 | /// 82 | public IEnumerable FieldInfoChain => m_fieldInfos; 83 | 84 | private int m_maxDepth; 85 | 86 | public uint NumTestsPerformed { get; private set; } 87 | 88 | private IEnumerable m_ignoreTypes; 89 | 90 | public SearchContext (int maxDepth, IEnumerable ignoreTypeNameRegexStrings) 91 | { 92 | m_maxDepth = maxDepth; 93 | if (ignoreTypeNameRegexStrings != null && ignoreTypeNameRegexStrings.Any()) 94 | m_ignoreTypes = ignoreTypeNameRegexStrings.Select(s => new Regex(s)).ToList(); 95 | } 96 | 97 | public static bool IsValidZombieType(Type type) 98 | { 99 | if (!TypeHelper.IsPotentialZombieType(type)) 100 | return false; 101 | 102 | if (type.IsPointer) 103 | return false; 104 | 105 | if (type == typeof(System.Reflection.Pointer)) 106 | return false; // Otherwise FieldInfo.GetValue recurses infinitely. 107 | 108 | if (type.ContainsGenericParameters || type.IsGenericParameter || type.IsGenericTypeDefinition) 109 | return false; // (Why?) 110 | 111 | return true; 112 | } 113 | 114 | 115 | 116 | private void CheckObjectField(object o, Type oType, FieldInfo fieldInfo) 117 | { 118 | if (m_fieldInfos.Count > m_maxDepth) 119 | throw new System.OverflowException("Max depth exceeded."); 120 | 121 | string typeName = oType.FullName; 122 | if (m_ignoreTypes != null && m_ignoreTypes.Any(r => r.IsMatch(typeName))) 123 | return; 124 | 125 | TestingObjectField?.Invoke(new TestInfo { obj = o, type = oType, fieldInfo = fieldInfo }); 126 | 127 | m_fieldInfos.Push(fieldInfo); 128 | try 129 | { 130 | object val = null; 131 | try { val = fieldInfo.GetValue(o); } 132 | catch (System.Exception) { } // val stays null. See next line. 133 | if (val == null) 134 | return; // (Still runs the "finally" below) 135 | TestAndRecurse(val); 136 | 137 | // Special cases: 138 | 139 | // If the value is an array then iterate through the values. 140 | if (val.GetType().IsArray) 141 | { 142 | IEnumerable collection = val as IEnumerable; 143 | foreach (object arrayEntry in collection) 144 | TestAndRecurse(arrayEntry); 145 | } 146 | 147 | // If the value is the backing field of an event, then iterate through the listeners. 148 | if (val is MulticastDelegate) 149 | { 150 | var mcd = val as MulticastDelegate; 151 | Delegate[] children = mcd.GetInvocationList(); 152 | foreach (Delegate d in children) 153 | TestAndRecurse(d.Target); 154 | } 155 | } 156 | finally 157 | { 158 | FieldInfo x = m_fieldInfos.Pop(); 159 | Debug.Assert(x == fieldInfo); // Otherwise we have a Push/Pop mismatch. 160 | } 161 | } 162 | 163 | 164 | private void TestAndRecurse(object obj) 165 | { 166 | if (obj == null) 167 | return; 168 | 169 | System.Type objType = obj.GetType(); 170 | // Note that we're thinking about the *runtime* type of this object, 171 | // rather than the compile-time type of whatever field it was stored under. 172 | 173 | if (!IsValidZombieType(objType)) 174 | return; 175 | 176 | bool testedAlready = true; 177 | try { testedAlready = m_scannedObjects.Contains(obj); } 178 | catch (System.Exception x) { } // testedAlready remains true. See subsequent line. 179 | if (testedAlready) 180 | return; 181 | 182 | m_scannedObjects.Add(obj); 183 | 184 | TestObject(obj); 185 | 186 | // Recurse into this object's instance fields. 187 | BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; 188 | FieldInfo[] fields = objType.GetFields(flags); 189 | foreach (FieldInfo field in fields) 190 | CheckObjectField(obj, objType, field); 191 | } 192 | 193 | /// 194 | /// Uses Unity Fake Null 195 | /// https://blogs.unity3d.com/2014/05/16/custom-operator-should-we-keep-it/ 196 | /// https://forum.unity.com/threads/fun-with-null.148090/ 197 | /// 198 | private void TestObject(object obj) 199 | { 200 | // An object is a zombie if: 201 | // 202 | // * It is not actually null. 203 | // * It is a subclass of UnityEngine.Object 204 | // * It compares itself as equal to null. 205 | // 206 | bool exists = obj != null; // Comparing a System.object. "Fake null" doesn't get a chance to run here. 207 | bool isUnityObj = obj is UnityEngine.Object; 208 | UnityEngine.Object unityObj = obj as UnityEngine.Object; 209 | bool zombie = exists && isUnityObj && (unityObj == null); 210 | 211 | ++NumTestsPerformed; 212 | // Emit an event every 1024 tests. 213 | bool madeProgress = (NumTestsPerformed & 0x3ff) == 0; 214 | if (madeProgress) 215 | MadeProgress?.Invoke(); 216 | 217 | if (zombie) 218 | ZombieHit?.Invoke(obj); 219 | } 220 | 221 | 222 | private void CheckStaticFields(Type type) 223 | { 224 | BindingFlags flags = 225 | BindingFlags.Public | BindingFlags.NonPublic | 226 | BindingFlags.Static | BindingFlags.FlattenHierarchy; 227 | // We *do* need FlattenHierarchy here. 228 | // A parent type might have been skipped if it was generic (See IsValidZombieType)). 229 | // (TODO I wonder why generic types are skipped?) 230 | FieldInfo[] staticFields = type.GetFields(flags); 231 | foreach (FieldInfo field in staticFields) 232 | CheckObjectField(null, type, field); 233 | } 234 | 235 | 236 | public void Search (IEnumerable types) 237 | { 238 | foreach (Type type in types) 239 | CheckStaticFields(type); 240 | SearchCompleted?.Invoke(); 241 | } 242 | } 243 | 244 | public event System.Action SearchStarted; 245 | 246 | 247 | 248 | private IEnumerable GetAssemblies () 249 | { 250 | IEnumerable assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); 251 | 252 | // Ignore the ones whose names match any of m_ignoreAssembyPatterns. 253 | // There are many "names" to do with an assembly. We use the following: 254 | System.Func assemblyGetName = a => a.GetName().Name; 255 | var assemblyIgnoreRegexes = m_ignoreAssemblyPatterns 256 | .Select(x => new Regex(x)) 257 | .ToList(); 258 | System.Func assemblyIsIgnored = a => assemblyIgnoreRegexes.Any(r => r.IsMatch(assemblyGetName(a))); 259 | assemblies = assemblies.Where(x => !assemblyIsIgnored(x)); 260 | Debug.Log($"Assemblies are: {string.Join(", ", assemblies.Select(a => assemblyGetName(a)))}"); 261 | return assemblies; 262 | } 263 | 264 | 265 | private IEnumerable GetStartTypes () 266 | { 267 | IEnumerable assemblies = GetAssemblies(); 268 | IEnumerable types = assemblies.SelectMany(a => a.GetTypes()); 269 | 270 | // Ignore the ones whose names are in m_ignoreTypePatterns. 271 | var typeIgnoreRegexes = m_ignoreTypePatterns 272 | .Select(x => new Regex(x)) 273 | .ToList(); 274 | System.Func typeIsIgnored = t => typeIgnoreRegexes.Any(r => r.IsMatch(t.FullName)); 275 | types = types.Where(t => !typeIsIgnored(t)); 276 | 277 | // Also ignore some types. I cannot remember the reasoning here. 278 | types = types.Where(t => SearchContext.IsValidZombieType(t)); 279 | 280 | Debug.Log($"Types are {string.Join(", ", types.Select(t => t.FullName))}"); 281 | return types; 282 | } 283 | 284 | private void Start() 285 | { 286 | if (m_runOnStart) 287 | RunZombieObjectDetection(); 288 | } 289 | 290 | public void RunZombieObjectDetection() 291 | { 292 | IEnumerable types = GetStartTypes(); 293 | 294 | SearchContext ctx = new SearchContext(m_maxDepth, m_ignoreTypePatternsDuringSearch); 295 | if (SearchStarted != null) 296 | SearchStarted(ctx); 297 | 298 | ctx.Search(types); 299 | } 300 | 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /Runtime/ZombieObjectDetector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da39880ba7957964c8e67d1816fe0a76 3 | timeCreated: 1506342768 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Runtime/ZombieObjectDetector_Report_TTY.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Reflection; 7 | 8 | 9 | namespace CSharpZombieDetector 10 | { 11 | 12 | 13 | 14 | public class ZombieObjectDetector_Report_TTY : MonoBehaviour 15 | { 16 | 17 | [SerializeField] 18 | [Tooltip("Print every test performed (VERY verbose)")] 19 | private bool m_reportTest = false; 20 | 21 | [SerializeField] 22 | [Tooltip("Print when a zombie is encountered (You probably want this on)")] 23 | private bool m_reportHit = true; 24 | 25 | [SerializeField] 26 | [Tooltip("Print a message every 1024 tests (useful to show it hasn't hung)")] 27 | private bool m_reportProgress = false; 28 | 29 | [SerializeField] 30 | [Tooltip("Print when the search completes")] 31 | private bool m_reportCompletion = true; 32 | 33 | private void Awake() 34 | { 35 | var zod = GetComponent(); 36 | zod.SearchStarted += StartSearch; 37 | } 38 | 39 | private void StartSearch(ZombieObjectDetector.SearchContext search) 40 | { 41 | var startTime = System.DateTime.Now; 42 | Debug.Log($"Search started at {startTime}"); 43 | if (m_reportTest) 44 | search.TestingObjectField += ReportTest; 45 | if (m_reportProgress) 46 | search.MadeProgress += () => PrintProgress(search); 47 | if (m_reportHit) 48 | search.ZombieHit += (obj) => PrintHit(search, obj); 49 | if (m_reportCompletion) 50 | search.SearchCompleted += () => CompleteSearch(search, startTime); 51 | } 52 | 53 | private void PrintProgress (ZombieObjectDetector.SearchContext ctx) 54 | { 55 | Debug.Log($"Searched {ctx.NumTestsPerformed} objects."); 56 | } 57 | 58 | private void ReportTest (ZombieObjectDetector.SearchContext.TestInfo info) 59 | { 60 | System.Type type = info.type; 61 | FieldInfo fieldInfo = info.fieldInfo; 62 | 63 | Debug.Log($"Testing field {fieldInfo.Name} of type {type.FullName}."); 64 | } 65 | 66 | private void PrintHit(ZombieObjectDetector.SearchContext ctx, object o) 67 | { 68 | string objType = o.GetType().FullName; 69 | var fieldChain = ctx.FieldInfoChain; 70 | // The class holding the very first field 71 | // (The one with the static field) 72 | System.Type startType = fieldChain.Last().DeclaringType; 73 | IEnumerable chain = fieldChain.Reverse().Select(m => m.Name); 74 | Debug.Log($"Found zombie of type {objType}, at {startType.FullName}.{string.Join(".", chain)}"); 75 | } 76 | 77 | private void CompleteSearch (ZombieObjectDetector.SearchContext ctx, System.DateTime startTime) 78 | { 79 | var now = System.DateTime.Now; 80 | System.TimeSpan duration = now - startTime; 81 | Debug.Log($"Search completed at {now} after {duration}. Tested {ctx.NumTestsPerformed} object(s)."); 82 | } 83 | 84 | 85 | } 86 | 87 | 88 | } -------------------------------------------------------------------------------- /Runtime/ZombieObjectDetector_Report_TTY.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2116a90b49e72e04bb949c9b144df377 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "com.unity.zombieobjectdetector", 3 | "version" : "0.4.2", 4 | "displayName" : "Zombie Object Detector", 5 | "description" : "Tool to detect \"fake null\" GameObjects and Components. https://github.com/Unity-Technologies/ZombieObjectDetector", 6 | "unity" : "2018.4", 7 | "keywords" : [ "zombie", "fake", "null", "leak" ], 8 | "author" : { 9 | "name" : "Peter Pimley", 10 | "email" : "peter.pimley@unity3d.com", 11 | "url" : "https://github.com/peter-pimley-unity" 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3010311be87043a4e918f014c7b6ab79 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------