///////////////////////////////////////////////////////////////////////// // Scriptable Objects Processing ///////////////////////////////////////////////////////////////////////// public static void ProcessScriptableObject(AssetInfo asset, Object scriptableObject) { currentLocation = RecordLocation.Asset; if (missingComponentDetector.TryDetectScriptableObjectIssue(asset.Path, scriptableObject)) { return; } var shouldTraverseProperties = missingReferenceDetector.Enabled; if (shouldTraverseProperties) { var initialInfo = new SerializedObjectTraverseInfo(scriptableObject); CSTraverseTools.TraverseObjectProperties(initialInfo, (info, property) => { if (property.type == "UnityEvent") { missingReferenceDetector.TryDetectScriptableObjectUnityEventIssue(asset.Path, info.TraverseTarget.GetType().Name, property); info.skipCurrentTree = true; return; } missingReferenceDetector.TryDetectScriptableObjectIssue(asset.Path, info.TraverseTarget.GetType().Name, property); }); } currentLocation = RecordLocation.Unknown; }
public static List <IssueRecord> CheckSettingsAssetForMissingReferences(AssetInfo asset, AssetSettingsKind kind) { var result = new List <IssueRecord>(); // include only supported settings files with object references if (kind != AssetSettingsKind.EditorSettings && kind != AssetSettingsKind.GraphicsSettings && kind != AssetSettingsKind.DynamicsManager && kind != AssetSettingsKind.Physics2DSettings && kind != AssetSettingsKind.PresetManager && kind != AssetSettingsKind.VFXManager) { return(result); } var allAssets = AssetDatabase.LoadAllAssetsAtPath(asset.Path); if (allAssets == null || allAssets.Length <= 0) { return(result); } foreach (var assetObject in allAssets) { if (assetObject == null) { return(result); } var traverseInfo = new SerializedObjectTraverseInfo(assetObject); CSTraverseTools.TraverseObjectProperties(traverseInfo, (info, property) => { if (MissingReferenceDetector.IsPropertyHasMissingReference(property)) { var issue = SettingsIssueRecord.Create(kind, IssueKind.MissingReference, asset.Path, property.propertyPath); result.Add(issue); } }); } return(result); }
public void ProcessComponent(Component component, Type componentType) { if (!enabled) { return; } existingData = null; newHash = 0; if (!uniqueTypes.TryGetValue(componentType, out existingData)) { var newData = new List <ComponentDuplicateInfo> { new ComponentDuplicateInfo(component) }; uniqueTypes.Add(componentType, newData); } else { foreach (var duplicateInfo in existingData) { if (duplicateInfo.hash == 0) { var initialInfo = new SerializedObjectTraverseInfo(duplicateInfo.reference); var duplicateInfoInClosure = duplicateInfo; CSTraverseTools.TraverseObjectProperties(initialInfo, (info, property) => { duplicateInfoInClosure.hash += CSEditorTools.GetPropertyHash(property); }); } } existingData.Add(new ComponentDuplicateInfo(component)); } }
public static void ProcessObject(Location currentLocation, Object inspectedUnityObject, Object target, EntryAddSettings addSettings, ProcessObjectReferenceHandler processReferenceCallback) { var onlyVisibleProperties = currentLocation != Location.ScriptAsset; var componentTraverseInfo = new SerializedObjectTraverseInfo(target, onlyVisibleProperties); string lastScriptPropertyName = null; CSTraverseTools.TraverseObjectProperties(componentTraverseInfo, (info, sp) => { if (currentLocation == Location.ScriptAsset) { if (sp.isArray) { if (sp.type == "string") { if (sp.propertyPath.IndexOf("m_DefaultReferences.Array.data[", StringComparison.OrdinalIgnoreCase) == 0) { if (sp.stringValue != null) { lastScriptPropertyName = sp.stringValue; // skipping first pair item of the m_DefaultReferences array item sp.Next(false); } } } } } if (sp.propertyType == SerializedPropertyType.ObjectReference && sp.objectReferenceValue != null) { string propertyName; if (lastScriptPropertyName != null) { propertyName = lastScriptPropertyName; lastScriptPropertyName = string.Empty; } else { propertyName = sp.propertyPath; } /*if (string.Equals(propertyName, "m_Script", StringComparison.OrdinalIgnoreCase)) * { * propertyName = "Script source"; * }*/ addSettings.propertyPath = propertyName; processReferenceCallback(inspectedUnityObject, sp.objectReferenceInstanceIDValue, addSettings); /* material instance handling */ var material = sp.objectReferenceValue as Material; if (material == null) { return; } if (currentLocation == Location.PrefabAssetGameObject) { if (AssetDatabase.GetAssetPath(material) != AssetDatabase.GetAssetPath(target)) { return; } if (AssetDatabase.IsSubAsset(material)) { return; } } else { if (AssetDatabase.Contains(material)) { return; } } addSettings.prefix = "[Material Instance]"; addSettings.suffix = "(Main Texture)"; var mainTextureInstanceId = 0; if (material.HasProperty(MainTextureShaderProperty)) { var mainTexture = material.mainTexture; mainTextureInstanceId = mainTexture != null ? mainTexture.GetInstanceID() : 0; } processReferenceCallback(inspectedUnityObject, mainTextureInstanceId, addSettings); addSettings.suffix = "(Shader)"; var shaderInstanceId = material.shader != null ? material.shader.GetInstanceID() : 0; processReferenceCallback(inspectedUnityObject, shaderInstanceId, addSettings); var materialSo = new SerializedObject(material); var texEnvs = materialSo.FindProperty("m_SavedProperties.m_TexEnvs.Array"); if (texEnvs != null) { for (var k = 0; k < texEnvs.arraySize; k++) { var arrayItem = texEnvs.GetArrayElementAtIndex(k); var fieldName = arrayItem.displayName; if (fieldName == MainTexturePropertyName) { continue; } var textureProperty = arrayItem.FindPropertyRelative("second.m_Texture"); if (textureProperty != null) { if (textureProperty.propertyType == SerializedPropertyType.ObjectReference) { addSettings.suffix = " (" + fieldName + ")"; processReferenceCallback(inspectedUnityObject, textureProperty.objectReferenceInstanceIDValue, addSettings); } } else { Debug.LogError(Maintainer.ConstructError("Can't get second.m_Texture from texEnvs at " + inspectedUnityObject.name)); } } } else { Debug.LogError(Maintainer.ConstructError("Can't get m_SavedProperties.m_TexEnvs.Array from material instance at " + inspectedUnityObject.name)); } } lastScriptPropertyName = null; }); }
///////////////////////////////////////////////////////////////////////// // Game Object's Components Processing ///////////////////////////////////////////////////////////////////////// public static void ProcessComponent(Component component, int orderIndex) { #if !UNITY_2019_1_OR_NEWER if (missingComponentDetector.CheckAndRecordNullComponent(component)) { return; } #else if (component == null) { return; } #endif if ((component.hideFlags & HideFlags.HideInInspector) != 0) { return; } if (!MaintainerSettings.Issues.touchDisabledComponents) { if (EditorUtility.GetObjectEnabled(component) == 0) { return; } } var componentType = component.GetType(); var componentName = componentType.Name; if (MaintainerSettings.Issues.componentIgnoresFilters != null && MaintainerSettings.Issues.componentIgnoresFilters.Length > 0) { if (CSFilterTools.IsValueMatchesAnyFilterOfKind(componentName, MaintainerSettings.Issues.componentIgnoresFilters, FilterKind.Type)) { return; } } duplicateComponentDetector.ProcessComponent(component, componentType); var shouldCheckPropertiesForDuplicate = duplicateComponentDetector.IsPropertiesHashCalculationRequired(); if (shouldCheckPropertiesForDuplicate) { // skipping duplicate search for non-standard components with invisible properties var baseType = componentType.BaseType; if (baseType != null) { if (baseType.Name == "MegaModifier") { shouldCheckPropertiesForDuplicate = false; duplicateComponentDetector.SkipComponent(); } } } var shouldTraverseProperties = missingReferenceDetector.Enabled || shouldCheckPropertiesForDuplicate; if (shouldTraverseProperties) { var initialInfo = new SerializedObjectTraverseInfo(component); CSTraverseTools.TraverseObjectProperties(initialInfo, (info, property) => { if (property.type == "UnityEvent") { missingReferenceDetector.TryDetectUnityEventIssues(currentLocation, currentAsset.Path, currentGameObject, componentType, componentName, orderIndex, property); info.skipCurrentTree = true; return; } missingReferenceDetector.TryDetectIssue(currentLocation, currentAsset.Path, currentGameObject, componentType, componentName, orderIndex, property); if (shouldCheckPropertiesForDuplicate) { duplicateComponentDetector.ProcessProperty(property); } }); } if (shouldCheckPropertiesForDuplicate) { duplicateComponentDetector.TryDetectIssue(currentLocation, currentAsset.Path, currentGameObject, componentType, componentName, orderIndex); } if (component is Terrain) { inconsistentTerrainDataDetector.ProcessTerrainComponent((Terrain)component, componentType, componentName, orderIndex); } else if (component is TerrainCollider) { inconsistentTerrainDataDetector.ProcessTerrainColliderComponent((TerrainCollider)component); } //Debug.Log("ProcessComponent: " + target.name + ":" + component); }