static Rect DrawElement_Modified(Object obj, Rect rect) { if (!PrefabUtilityEx.IsPrefabInstanceModified(obj, true)) { return(rect); } Rect buttonRect = GetRightAligned(rect, 12, 12); var icon = EditorGUIUtility.ObjectContent(obj, obj.GetType()).image; if (!icon) { icon = AssetDatabase.GetCachedIcon(AssetDatabase.GetAssetPath(PrefabUtility.GetPrefabParent(obj))); } var description = PrefabUtilityEx.GetModificationDescription(obj, true); bool result = false; bool isAdded = PrefabUtility.IsComponentAddedToPrefabInstance(obj); result = GUI.Button(buttonRect, new GUIContent(" ", description), isAdded?"flow node 0 on":"flow node 0"); if (icon) { GUI.DrawTexture(buttonRect, icon); } if (result) { if (isAdded) { Selection.objects = new[] { obj }; // EditorUtility.DisplayPopupMenu(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 0, 0), "Prefab/Added Component", null); } else { Selection.objects = new[] { obj }; // EditorUtility.DisplayPopupMenu(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 0, 0), "Prefab/Modified Component", null); } } return(new Rect(rect.x, rect.y, buttonRect.x - rect.x - 2, rect.height)); }
public static string GetModificationDescription(Object obj, bool thisObjectOnly) { string output = ""; bool modified = false; var mods = PrefabUtilityEx.GetPropertyModifications(obj, thisObjectOnly); if (mods != null && mods.Length > 0) { output += "Modified values:"; foreach (var i in mods) { output += string.Concat("\n", i.target.name, ".", i.target.GetType().Name, " - ", i.propertyPath, ":", i.objectReference? i.objectReference.name:i.value); } modified = true; } if (PrefabUtility.IsComponentAddedToPrefabInstance(obj)) { output += string.Concat("Added: ", obj.GetType().Name); modified = true; } var removedChildren = GetRemovedChildrenFromPrefab(obj, thisObjectOnly); if (removedChildren.Length > 0) { output += "Removed Children: "; foreach (var i in removedChildren) { output += string.Concat("\n", i.name); } modified = true; } if (modified) { return(output); } return("Not modified"); }
static void DrawRightPanel(Object obj, Rect rect) { if (!obj) { return; } var prefabType = PrefabUtility.GetPrefabType(obj); switch (prefabType) { case PrefabType.MissingPrefabInstance: return; case PrefabType.None: return; case PrefabType.ModelPrefab: return; case PrefabType.Prefab: return; } rect = DrawElement_Modified(obj, rect); foreach (var comp in (obj as GameObject).GetComponents <Component>()) { rect = DrawElement_Modified(comp, rect); } foreach (var comp in PrefabUtilityEx.GetRemovedComponentsFromPrefab(obj, true)) { rect = DrawElement_Removed(obj as GameObject, comp, rect); } if (PrefabUtilityEx.IsPrefabRoot(obj) && (prefabType == PrefabType.DisconnectedPrefabInstance || prefabType == PrefabType.DisconnectedModelPrefabInstance)) { rect = DrawElement_Reconnect(obj, rect); } }
public void Simplify(WorkingMesh inputMesh, WorkingMesh outputMesh, float quality) { var isMainThread = MonoBehaviourHelper.IsMainThread(); Renderer renderer = null; UnityCloudJob job = null; string jobName = null; var assembly = typeof(SharedData).Assembly; var cloudJobType = assembly.GetType("Simplygon.Cloud.Yoda.IntegrationClient.CloudJob"); var jobNameField = cloudJobType.GetField("name", BindingFlags.NonPublic | BindingFlags.Instance); lock (executionLock) { const int kSimultaneousJobs = 4; //var processSubscriptionRestrictionsType = assembly.GetType("Simplygon.Cloud.Yoda.Client.ProcessSubscriptionRestrictions23"); //var simultaneousJobsProperty = processSubscriptionRestrictionsType.GetProperty("SimultaneousJobs"); //var accountType = assembly.GetType("Simplygon.Cloud.Yoda.Client.User23"); //var processSubscriptionsRestrictionsProperty = accountType.GetProperty("ProcessSubscriptionRestrictions"); //var processSubscriptionRestrictions = processSubscriptionsRestrictionsProperty.GetValue(SharedData.Instance.Account, null); //var simultaneousJobs = (int)simultaneousJobsProperty.GetValue(processSubscriptionRestrictions, null); while (SharedData.Instance.GeneralManager.JobManager.ProcessingJobCount >= kSimultaneousJobs) { if (!isMainThread) { Thread.Sleep(1000); } } MonoBehaviourHelper.ExecuteOnMainThread(() => { var go = EditorUtility.CreateGameObjectWithHideFlags("Temp", HideFlags.HideAndDontSave, typeof(MeshRenderer), typeof(MeshFilter)); var mf = go.GetComponent <MeshFilter>(); var mesh = new Mesh(); inputMesh.ApplyToMesh(mesh); mf.sharedMesh = mesh; renderer = go.GetComponent <MeshRenderer>(); var material = new Material(Shader.Find("Standard")); var sharedMaterials = new Material[mesh.subMeshCount]; for (int i = 0; i < mesh.subMeshCount; i++) { sharedMaterials[i] = material; } renderer.sharedMaterials = sharedMaterials; renderer.enabled = false; EditorWindow.GetWindow <Window>(); // Must be visible for background processing SharedData.Instance.Settings.SetDownloadAssetsAutomatically(true); var lodChainProperty = typeof(SharedData).GetProperty("LODChain"); var lodChainList = lodChainProperty.GetValue(SharedData.Instance, null) as IList; var lodChain = lodChainList[0]; var processNodeType = assembly.GetType("Simplygon.SPL.v80.Node.ProcessNode"); var processorProperty = processNodeType.GetProperty("Processor"); var processor = processorProperty.GetValue(lodChain, null); var reductionProcessorType = assembly.GetType("Simplygon.SPL.v80.Processor.ReductionProcessor"); var reductionSettingsProperty = reductionProcessorType.GetProperty("ReductionSettings"); var reductionSettingsType = assembly.GetType("Simplygon.SPL.v80.Settings.ReductionSettings"); var reductionSettings = reductionSettingsProperty.GetValue(processor, null); var triangleRatioProperty = reductionSettingsType.GetProperty("TriangleRatio"); triangleRatioProperty.SetValue(reductionSettings, quality, null); jobName = Path.GetRandomFileName().Replace(".", string.Empty); var prefabList = PrefabUtilityEx.GetPrefabsForSelection(new List <GameObject>() { go }); var generalManager = SharedData.Instance.GeneralManager; generalManager.CreateJob(jobName, "myPriority", prefabList, () => { foreach (var j in generalManager.JobManager.Jobs) { var name = (string)jobNameField.GetValue(j.CloudJob); if (name == jobName) { job = j; } } }); }); while (job == null) { if (!isMainThread) { Thread.Sleep(100); } } } while (string.IsNullOrEmpty(job.AssetDirectory)) { if (!isMainThread) { Thread.Sleep(100); } } MonoBehaviourHelper.ExecuteOnMainThread(() => { var customDataType = assembly.GetType("Simplygon.Cloud.Yoda.IntegrationClient.CloudJob+CustomData"); var pendingFolderNameProperty = customDataType.GetProperty("UnityPendingLODFolderName"); var jobCustomDataProperty = cloudJobType.GetProperty("JobCustomData"); var jobCustomData = jobCustomDataProperty.GetValue(job.CloudJob, null); var jobFolderName = pendingFolderNameProperty.GetValue(jobCustomData, null) as string; var lodAssetDir = "Assets/LODs/" + job.AssetDirectory; var mesh = AssetDatabase.LoadAssetAtPath <Mesh>(string.Format("{0}/{1}_LOD1.prefab", lodAssetDir, jobName)); mesh.ApplyToWorkingMesh(ref outputMesh); //job.CloudJob.StateHandler.RequestJobDeletion(); AssetDatabaseEx.DeletePendingLODFolder(jobFolderName); AssetDatabase.DeleteAsset(lodAssetDir); UnityObject.DestroyImmediate(renderer.gameObject); }); }
static Rect DrawElement_Reconnect(Object obj, Rect rect) { Rect buttonRect = GetRightAligned(rect, 12, 12); var icon = GUI.skin.GetStyle("CN EntryWarn").normal.background; var description = string.Concat("Disconnected Prefab: ", AssetDatabase.GetAssetPath(PrefabUtility.GetPrefabParent(obj)), "\n\n", PrefabUtilityEx.GetModificationDescription(obj, false)); var result = GUI.Button(buttonRect, new GUIContent(" ", description)); if (icon) { GUI.DrawTexture(buttonRect, icon); } if (result) { var selection = Selection.objects; Selection.objects = new[] { obj }; // EditorUtility.DisplayPopupMenu(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 0, 0), "Prefab/Disconnected Prefab", null); Selection.objects = selection; } return(new Rect(rect.x, rect.y, buttonRect.x - rect.x - 2, rect.height)); }
protected override IEnumerator GetSimplifiedMesh(Mesh origin, float quality, Action <Mesh> resultCallback) { Renderer renderer = null; UnityCloudJob job = null; string jobName = null; var assembly = typeof(SharedData).Assembly; var cloudJobType = assembly.GetType("Simplygon.Cloud.Yoda.IntegrationClient.CloudJob"); var jobNameField = cloudJobType.GetField("name", BindingFlags.NonPublic | BindingFlags.Instance); var go = EditorUtility.CreateGameObjectWithHideFlags("Temp", HideFlags.HideAndDontSave, typeof(MeshRenderer), typeof(MeshFilter)); var mf = go.GetComponent <MeshFilter>(); var mesh = UnityEngine.Object.Instantiate(origin); mf.sharedMesh = mesh; renderer = go.GetComponent <MeshRenderer>(); var sharedMaterials = new Material[mesh.subMeshCount]; if (Directory.Exists(materialPath) == false) { Directory.CreateDirectory(materialPath); } //For submesh, we should create material asset. //otherwise, simplygon will be combine uv of submesh. for (int i = 0; i < mesh.subMeshCount; i++) { var material = new Material(Shader.Find("Standard")); material.name = "Material " + i.ToString(); AssetDatabase.CreateAsset(material, materialPath + "/" + material.name); sharedMaterials[i] = material; } renderer.sharedMaterials = sharedMaterials; renderer.enabled = false; EditorWindow.GetWindow <Window>(); // Must be visible for background processing SharedData.Instance.Settings.SetDownloadAssetsAutomatically(true); var lodChainProperty = typeof(SharedData).GetProperty("LODChain"); var lodChainList = lodChainProperty.GetValue(SharedData.Instance, null) as IList; var lodChain = lodChainList[0]; var processNodeType = assembly.GetType("Simplygon.SPL.v80.Node.ProcessNode"); var processorProperty = processNodeType.GetProperty("Processor"); var processor = processorProperty.GetValue(lodChain, null); var reductionProcessorType = assembly.GetType("Simplygon.SPL.v80.Processor.ReductionProcessor"); var reductionSettingsProperty = reductionProcessorType.GetProperty("ReductionSettings"); var reductionSettingsType = assembly.GetType("Simplygon.SPL.v80.Settings.ReductionSettings"); var reductionSettings = reductionSettingsProperty.GetValue(processor, null); var triangleRatioProperty = reductionSettingsType.GetProperty("TriangleRatio"); triangleRatioProperty.SetValue(reductionSettings, quality, null); jobName = Path.GetRandomFileName().Replace(".", string.Empty); var prefabList = PrefabUtilityEx.GetPrefabsForSelection(new List <GameObject>() { go }); var generalManager = SharedData.Instance.GeneralManager; generalManager.CreateJob(jobName, "myPriority", prefabList, () => { foreach (var j in generalManager.JobManager.Jobs) { var name = (string)jobNameField.GetValue(j.CloudJob); if (name == jobName) { job = j; } } }); while (job == null) { yield return(null); } while (string.IsNullOrEmpty(job.AssetDirectory)) { yield return(null); } var customDataType = assembly.GetType("Simplygon.Cloud.Yoda.IntegrationClient.CloudJob+CustomData"); var pendingFolderNameProperty = customDataType.GetProperty("UnityPendingLODFolderName"); var jobCustomDataProperty = cloudJobType.GetProperty("JobCustomData"); var jobCustomData = jobCustomDataProperty.GetValue(job.CloudJob, null); var jobFolderName = pendingFolderNameProperty.GetValue(jobCustomData, null) as string; var lodAssetDir = lodPath + job.AssetDirectory; var simplifiedMesh = AssetDatabase.LoadAssetAtPath <Mesh>(string.Format("{0}/{1}_LOD1.prefab", lodAssetDir, jobName)); Mesh resultMesh = UnityEngine.Object.Instantiate(simplifiedMesh); //job.CloudJob.StateHandler.RequestJobDeletion(); AssetDatabaseEx.DeletePendingLODFolder(jobFolderName); AssetDatabase.DeleteAsset(lodAssetDir); AssetDatabase.DeleteAsset(materialPath); UnityEngine.Object.DestroyImmediate(renderer.gameObject); if (resultCallback != null) { resultCallback(resultMesh); } }
public static void AddInstanceComponentToPrefab(Component obj) { var gameObject = PrefabUtility.FindPrefabRoot(GetGameObject(obj)); var prefab = (GameObject)PrefabUtility.GetPrefabParent(gameObject); foreach (var i in GetRequiredComponents(obj)) { if (i && PrefabUtility.GetPrefabParent(i) == null && prefab.GetComponent(i.GetType()) == null) { AddInstanceComponentToPrefab(i); } } // add the prefab to the target var prefabComp = prefab.AddComponent(obj.GetType()); if (prefabComp) { var mods = new List <PropertyModification>(PrefabUtility.GetPropertyModifications(gameObject)); // copy data EditorUtility.CopySerialized(obj, prefabComp); // fix up any references to their prefabs SerializedObject so = new SerializedObject(obj); SerializedObject prefabCompSo = new SerializedObject(prefabComp); prefabCompSo.Update(); so.Update(); var i = so.GetIterator(); while (i.Next(true)) { if (i.propertyType == SerializedPropertyType.ObjectReference) { if (i.propertyPath == "m_PrefabParentObject" || i.propertyPath == "m_PrefabInternal" || i.propertyPath == "m_GameObject" || i.propertyPath == "m_Script") { continue; } var prefabRef = PrefabUtility.GetPrefabParent(i.objectReferenceValue); var prefabRefRoot = PrefabUtility.GetPrefabParent(PrefabUtility.FindPrefabRoot(PrefabUtilityEx.GetGameObject(i.objectReferenceValue))); var prefabType = i.objectReferenceValue != null?PrefabUtility.GetPrefabType(i.objectReferenceValue) : PrefabType.None; if (prefabType != PrefabType.Prefab && prefabType != PrefabType.ModelPrefab) { // link to an object in the scene. // we must add a modification for this. if (i.objectReferenceValue != null && (prefabRef == null || prefab != prefabRefRoot)) { var propertyMod = new PropertyModification(); propertyMod.objectReference = i.objectReferenceValue; propertyMod.target = prefabComp; propertyMod.propertyPath = i.propertyPath; mods.Add(propertyMod); prefabCompSo.FindProperty(i.propertyPath).objectReferenceValue = null; } else { prefabCompSo.FindProperty(i.propertyPath).objectReferenceValue = prefabRef; } } } } so = null; // save prefabCompSo.ApplyModifiedProperties(); EditorUtility.SetDirty(prefab); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(prefab)); // remove the applied value from our instance. UnityEngine.GameObject.DestroyImmediate(obj); // add property mods var components = gameObject.GetComponents(prefabComp.GetType()); Component newComponent = System.Array.Find(components, ((arg) => PrefabUtility.GetPrefabParent(arg) == prefabComp)); PrefabUtility.SetPropertyModifications(newComponent, mods.ToArray()); } else { EditorUtility.DisplayDialog("Error", "Can't apply this component to the prefab as it cannot own more than one prefab of this type", "Ok"); } }