protected override IEnumerator workerMethod() { umaData.generatedMaterials.rendererCount = rendererCount; umaData.generatedMaterials.materials = generatedMaterials; GenerateAtlasData(); OptimizeAtlas(); textureProcessCoroutine.Prepare(umaData, umaGenerator); yield return(textureProcessCoroutine); CleanBackUpTextures(); UpdateUV(); // HACK - is this the right place? SlotData[] slots = umaData.umaRecipe.slotDataList; for (int i = 0; i < slots.Length; i++) { var slot = slots[i]; if (slot == null) { continue; } for (int j = 1; j < slot.OverlayCount; j++) { OverlayData overlay = slot.GetOverlay(j); #if UNITY_STANDALONE || UNITY_IOS || UNITY_ANDROID || UNITY_PS4 || UNITY_XBOXONE //supported platforms for procedural materials if ((overlay != null) && (overlay.isProcedural)) { overlay.ReleaseProceduralTextures(); } #endif } } if (updateMaterialList) { for (int j = 0; j < umaData.rendererCount; j++) { var renderer = umaData.GetRenderer(j); var mats = renderer.sharedMaterials; var newMats = new Material[mats.Length]; var atlasses = umaData.generatedMaterials.materials; int materialIndex = 0; for (int i = 0; i < atlasses.Count; i++) { if (atlasses[i].renderer == j) { UMAUtils.DestroySceneObject(mats[materialIndex]); newMats[materialIndex] = atlasses[i].material; materialIndex++; } } renderer.sharedMaterials = newMats; } } }
/// <summary> /// Update the avatar of a UMA character. /// </summary> /// <param name="umaData">UMA data.</param> public virtual void UpdateAvatar(UMAData umaData) { if (umaData) { if (umaData.animationController != null) { var umaTransform = umaData.transform; var oldParent = umaTransform.parent; var originalRot = umaTransform.localRotation; var originalPos = umaTransform.localPosition; var animator = umaData.animator; umaTransform.SetParent(null, false); umaTransform.localRotation = Quaternion.identity; umaTransform.localPosition = Vector3.zero; if (animator == null) { animator = umaData.gameObject.GetComponent <Animator>(); if (animator == null) { animator = umaData.gameObject.AddComponent <Animator>(); } SetAvatar(umaData, animator); animator.runtimeAnimatorController = umaData.animationController; umaData.animator = animator; } else { AnimatorState snapshot = new AnimatorState(); snapshot.SaveAnimatorState(animator); if (!umaData.KeepAvatar || animator.avatar == null) { UMAUtils.DestroySceneObject(animator.avatar); SetAvatar(umaData, animator); } if (animator.runtimeAnimatorController != null) { snapshot.RestoreAnimatorState(animator); } } umaTransform.SetParent(oldParent, false); umaTransform.localRotation = originalRot; umaTransform.localPosition = originalPos; } } }
/// <summary> /// Hide the avatar and clean up its components. /// </summary> public virtual void Hide() { if (umaData != null) { umaData.CleanTextures(); umaData.CleanMesh(true); umaData.CleanAvatar(); UMAUtils.DestroySceneObject(umaData.umaRoot); umaData.umaRoot = null; umaData.SetRenderers(null); umaData.animator = null; umaData.firstBake = true; umaData.skeleton = null; } umaRace = null; }
public void ProcessTexture(UMAGeneratorBase _umaGenerator, UMAData _umaData, bool updateMaterialList, int InitialScaleFactor) { umaGenerator = _umaGenerator; umaData = _umaData; this.updateMaterialList = updateMaterialList; scaleFactor = InitialScaleFactor; textureProcesser = new TextureProcessPRO(); Start(); umaData.generatedMaterials.rendererAssets = uniqueRenderers; umaData.generatedMaterials.materials = generatedMaterials; GenerateAtlasData(); OptimizeAtlas(); textureProcesser.ProcessTexture(_umaData, _umaGenerator); CleanBackUpTextures(); UpdateUV(); // Procedural textures were done here if (updateMaterialList) { for (int j = 0; j < umaData.rendererCount; j++) { var renderer = umaData.GetRenderer(j); var mats = renderer.sharedMaterials; var newMats = new Material[mats.Length]; var atlasses = umaData.generatedMaterials.materials; int materialIndex = 0; for (int i = 0; i < atlasses.Count; i++) { if (atlasses[i].rendererAsset == umaData.GetRendererAsset(j)) { UMAUtils.DestroySceneObject(mats[materialIndex]); newMats[materialIndex] = atlasses[i].material; atlasses[i].skinnedMeshRenderer = renderer; atlasses[i].materialIndex = materialIndex; materialIndex++; } } renderer.sharedMaterials = newMats; } } }
private void CleanBackUpTextures() { for (int textureIndex = 0; textureIndex < backUpTexture.Length; textureIndex++) { if (backUpTexture[textureIndex] != null) { Texture tempTexture = backUpTexture[textureIndex]; if (tempTexture is RenderTexture) { RenderTexture tempRenderTexture = tempTexture as RenderTexture; tempRenderTexture.Release(); UMAUtils.DestroySceneObject(tempRenderTexture); tempRenderTexture = null; } else { UMAUtils.DestroySceneObject(tempTexture); } backUpTexture[textureIndex] = null; } } }
protected override IEnumerator workerMethod() { umaData.generatedMaterials.rendererAssets = uniqueRenderers; umaData.generatedMaterials.materials = generatedMaterials; GenerateAtlasData(); OptimizeAtlas(); textureProcessCoroutine.Prepare(umaData, umaGenerator); yield return(textureProcessCoroutine); CleanBackUpTextures(); UpdateUV(); // Procedural textures were done here if (updateMaterialList) { for (int j = 0; j < umaData.rendererCount; j++) { var renderer = umaData.GetRenderer(j); var mats = renderer.sharedMaterials; var newMats = new Material[mats.Length]; var atlasses = umaData.generatedMaterials.materials; int materialIndex = 0; for (int i = 0; i < atlasses.Count; i++) { if (atlasses[i].rendererAsset == umaData.GetRendererAsset(j)) { UMAUtils.DestroySceneObject(mats[materialIndex]); newMats[materialIndex] = atlasses[i].material; atlasses[i].skinnedMeshRenderer = renderer; atlasses[i].materialIndex = materialIndex; materialIndex++; } } renderer.sharedMaterials = newMats; } } }
/// <summary> /// Updates the UMA mesh and skeleton to match current slots. /// </summary> /// <param name="updatedAtlas">If set to <c>true</c> atlas has changed.</param> /// <param name="umaData">UMA data.</param> /// <param name="atlasResolution">Atlas resolution.</param> public override void UpdateUMAMesh(bool updatedAtlas, UMAData umaData, int atlasResolution) { this.umaData = umaData; this.atlasResolution = atlasResolution; combinedMeshList = new List <SkinnedMeshCombiner.CombineInstance>(umaData.umaRecipe.slotDataList.Length); combinedMaterialList = new List <Material>(); EnsureUMADataSetup(umaData); umaData.skeleton.BeginSkeletonUpdate(); for (currentRendererIndex = 0; currentRendererIndex < umaData.generatedMaterials.rendererCount; currentRendererIndex++) { //Move umaMesh creation to with in the renderer loops //May want to make sure to set all it's buffers to null instead of creating a new UMAMeshData UMAMeshData umaMesh = new UMAMeshData(); umaMesh.ClaimSharedBuffers(); umaMesh.subMeshCount = 0; umaMesh.vertexCount = 0; combinedMeshList.Clear(); combinedMaterialList.Clear(); clothProperties = null; BuildCombineInstances(); if (combinedMeshList.Count == 1) { // fast track var tempMesh = SkinnedMeshCombiner.ShallowInstanceMesh(combinedMeshList[0].meshData, combinedMeshList[0].triangleMask); tempMesh.ApplyDataToUnityMesh(renderers[currentRendererIndex], umaData.skeleton); } else { SkinnedMeshCombiner.CombineMeshes(umaMesh, combinedMeshList.ToArray(), umaData.blendShapeSettings); if (updatedAtlas) { RecalculateUV(umaMesh); } umaMesh.ApplyDataToUnityMesh(renderers[currentRendererIndex], umaData.skeleton); } var cloth = renderers[currentRendererIndex].GetComponent <Cloth>(); if (clothProperties != null) { if (cloth != null) { clothProperties.ApplyValues(cloth); } } else { UMAUtils.DestroySceneObject(cloth); } var materials = combinedMaterialList.ToArray(); renderers[currentRendererIndex].sharedMaterials = materials; umaMesh.ReleaseSharedBuffers(); } umaData.umaRecipe.ClearDNAConverters(); for (int i = 0; i < umaData.umaRecipe.slotDataList.Length; i++) { SlotData slotData = umaData.umaRecipe.slotDataList[i]; if (slotData != null) { umaData.umaRecipe.AddDNAUpdater(slotData.asset.slotDNA); } } umaData.firstBake = false; }
public static GameObject CreateEditorContext() { GameObject EditorUMAContextBase = null; if (UnityEditor.BuildPipeline.isBuildingPlayer) { return(null); } if (Application.isPlaying) { if (Debug.isDebugBuild) { Debug.LogWarning("There was no UMAContext in this scene. Please add the UMA context prefab to this scene before you try to generate an UMA."); } return(null); } if (Debug.isDebugBuild) { Debug.Log("UMA Recipe Editor created an UMAEditorContext to enable editing. This will auto delete once you have finished editing your recipe or you add a UMA prefab with a context to this scene."); } //if there is already an EditorUMAContextBase use it if (UMAContextBase.FindInstance() != null) { if (UMAContextBase.FindInstance().gameObject.name == "UMAEditorContext") { EditorUMAContextBase = UMAContextBase.FindInstance().gameObject; //if the UMAContextBase itself is on this game object, it means this was created and not deleted by the previous version of 'CreateEditorContext' //(The new version creates the UMAContextBase on a child game object called 'UMAContextBase' so that UMAContextBase.FindInstance can find it properly) //so in this case delete all the components that would have been added from the found gameObject from the previous code if (EditorUMAContextBase.GetComponent <UMAContextBase>()) { UMAUtils.DestroySceneObject(EditorUMAContextBase.GetComponent <UMAContextBase>()); //should also make the instance null again } } else if (UMAContextBase.FindInstance().gameObject.transform.parent.gameObject.name == "UMAEditorContext") { EditorUMAContextBase = UMAContextBase.FindInstance().gameObject.transform.parent.gameObject; } } else if (GameObject.Find("UMAEditorContext")) { EditorUMAContextBase = GameObject.Find("UMAEditorContext"); } else { EditorUMAContextBase = new GameObject(); EditorUMAContextBase.name = "UMAEditorContext"; } //Make this GameObject not show up in the scene or save EditorUMAContextBase.hideFlags = HideFlags.DontSave | HideFlags.NotEditable; //if this gameobject does not contain an UMAContextBase add it - we have to call it UMAContextBase because UMAContextBase.FindInstance searches for that game object var context = UMAContextBase.Instance = EditorUMAContextBase.GetComponentInChildren <UMAContextBase>(); if (UMAContextBase.Instance == null) { var GO = new GameObject(); GO.name = "UMAContext"; GO.transform.parent = EditorUMAContextBase.transform; context = GO.AddComponent <UMAGlobalContext>(); GO.AddComponent <UMADefaultMeshCombiner>(); var gen = GO.AddComponent <UMAGenerator>(); gen.fitAtlas = true; gen.SharperFitTextures = true; gen.AtlasOverflowFitMethod = UMAGeneratorBase.FitMethod.BestFitSquare; gen.convertRenderTexture = false; gen.editorAtlasResolution = 1024; gen.InitialScaleFactor = 2; gen.collectGarbage = false; gen.IterationCount = 1; gen.fastGeneration = true; gen.processAllPending = false; gen.NoCoroutines = true; UMAContextBase.Instance = context; } return(EditorUMAContextBase); }
protected void EnsureUMADataSetup(UMAData umaData) { if (umaData.umaRoot == null) { GameObject newRoot = new GameObject("Root"); //make root of the UMAAvatar respect the layer setting of the UMAAvatar so cameras can just target this layer newRoot.layer = umaData.gameObject.layer; newRoot.transform.parent = umaData.transform; newRoot.transform.localPosition = Vector3.zero; newRoot.transform.localRotation = Quaternion.Euler(270f, 0, 0f); newRoot.transform.localScale = Vector3.one; umaData.umaRoot = newRoot; GameObject newGlobal = new GameObject("Global"); newGlobal.transform.parent = newRoot.transform; newGlobal.transform.localPosition = Vector3.zero; newGlobal.transform.localRotation = Quaternion.Euler(90f, 90f, 0f); umaData.skeleton = new UMASkeleton(newGlobal.transform); renderers = new SkinnedMeshRenderer[umaData.generatedMaterials.rendererCount]; for (int i = 0; i < umaData.generatedMaterials.rendererCount; i++) { renderers[i] = MakeRenderer(i, newGlobal.transform); } umaData.SetRenderers(renderers); } else { umaData.CleanMesh(false); if (umaData.rendererCount == umaData.generatedMaterials.rendererCount) { renderers = umaData.GetRenderers(); } else { var oldRenderers = umaData.GetRenderers(); var globalTransform = umaData.GetGlobalTransform(); renderers = new SkinnedMeshRenderer[umaData.generatedMaterials.rendererCount]; for (int i = 0; i < umaData.generatedMaterials.rendererCount; i++) { if (oldRenderers != null && oldRenderers.Length > i) { renderers[i] = oldRenderers[i]; continue; } renderers[i] = MakeRenderer(i, globalTransform); } if (oldRenderers != null) { for (int i = umaData.generatedMaterials.rendererCount; i < oldRenderers.Length; i++) { UMAUtils.DestroySceneObject(oldRenderers[i].gameObject); //For cloth, be aware of issue: 845868 //https://issuetracker.unity3d.com/issues/cloth-repeatedly-destroying-objects-with-cloth-components-causes-a-crash-in-unity-cloth-updatenormals } } umaData.SetRenderers(renderers); } } //Clear out old cloth components for (int i = 0; i < umaData.rendererCount; i++) { Cloth cloth = renderers[i].GetComponent <Cloth>(); if (cloth != null) { DestroyImmediate(cloth, false); //Crashes if trying to use Destroy() } } }
public static GameObject CreateEditorContext() { GameObject EditorUMAContext = null; if (UnityEditor.BuildPipeline.isBuildingPlayer) { return(null); } if (Application.isPlaying) { if (Debug.isDebugBuild) { Debug.LogWarning("There was no UMAContext in this scene. Please add the UMA_DCS prefab to this scene before you try to generate an UMA."); } return(null); } if (Debug.isDebugBuild) { Debug.Log("UMA Recipe Editor created an UMAEditorContext to enable editing. This will auto delete once you have finished editing your recipe or you add the UMA_DCS prefab to this scene."); } //if there is already an EditorUMAContext use it if (UMAContext.FindInstance() != null) { if (UMAContext.FindInstance().gameObject.name == "UMAEditorContext") { EditorUMAContext = UMAContext.FindInstance().gameObject; //if the UMAContext itself is on this game object, it means this was created and not deleted by the previous version of 'CreateEditorContext' //(The new version creates the UMAContext on a child game object called 'UMAContext' so that UMAContext.FindInstance can find it properly) //so in this case delete all the components that would have been added from the found gameObject from the previous code if (EditorUMAContext.GetComponent <UMAContext>()) { UMAUtils.DestroySceneObject(EditorUMAContext.GetComponent <UMAContext>()); //should also make the instance null again if (EditorUMAContext.GetComponent <DynamicRaceLibrary>()) { UMAUtils.DestroySceneObject(EditorUMAContext.GetComponent <DynamicRaceLibrary>()); } if (EditorUMAContext.GetComponent <DynamicSlotLibrary>()) { UMAUtils.DestroySceneObject(EditorUMAContext.GetComponent <DynamicSlotLibrary>()); } if (EditorUMAContext.GetComponent <DynamicOverlayLibrary>()) { UMAUtils.DestroySceneObject(EditorUMAContext.GetComponent <DynamicOverlayLibrary>()); } if (EditorUMAContext.GetComponent <DynamicCharacterSystem>()) { UMAUtils.DestroySceneObject(EditorUMAContext.GetComponent <DynamicCharacterSystem>()); } if (EditorUMAContext.GetComponent <DynamicAssetLoader>()) { UMAUtils.DestroySceneObject(EditorUMAContext.GetComponent <DynamicAssetLoader>()); } } } else if (UMAContext.FindInstance().gameObject.transform.parent.gameObject.name == "UMAEditorContext") { EditorUMAContext = UMAContext.FindInstance().gameObject.transform.parent.gameObject; } } else if (GameObject.Find("UMAEditorContext")) { EditorUMAContext = GameObject.Find("UMAEditorContext"); } else { EditorUMAContext = new GameObject(); EditorUMAContext.name = "UMAEditorContext"; } //Make this GameObject not show up in the scene or save EditorUMAContext.hideFlags = HideFlags.DontSave | HideFlags.NotEditable; //if this gameobject does not contain an UMAContext add it - we have to call it UMAContext because UMAContext.FindInstance searches for that game object var thisUMAContext = UMAContext.Instance = EditorUMAContext.GetComponentInChildren <UMAContext>(); if (UMAContext.Instance == null) { var thisUMAContextGO = new GameObject(); thisUMAContextGO.name = "UMAContext"; thisUMAContextGO.transform.parent = EditorUMAContext.transform; thisUMAContext = thisUMAContextGO.AddComponent <UMAContext>(); UMAContext.Instance = thisUMAContext; } //we need to add the libraries as components of the game object too //and then set THOSE components to the umaContext component thisUMAContext.raceLibrary = thisUMAContext.gameObject.AddComponent <DynamicRaceLibrary>(); (thisUMAContext.raceLibrary as DynamicRaceLibrary).dynamicallyAddFromResources = true; (thisUMAContext.raceLibrary as DynamicRaceLibrary).dynamicallyAddFromAssetBundles = true; thisUMAContext.overlayLibrary = thisUMAContext.gameObject.AddComponent <DynamicOverlayLibrary>(); (thisUMAContext.overlayLibrary as DynamicOverlayLibrary).dynamicallyAddFromResources = true; (thisUMAContext.overlayLibrary as DynamicOverlayLibrary).dynamicallyAddFromAssetBundles = true; thisUMAContext.slotLibrary = thisUMAContext.gameObject.AddComponent <DynamicSlotLibrary>(); (thisUMAContext.slotLibrary as DynamicSlotLibrary).dynamicallyAddFromResources = true; (thisUMAContext.slotLibrary as DynamicSlotLibrary).dynamicallyAddFromAssetBundles = true; thisUMAContext.dynamicCharacterSystem = thisUMAContext.gameObject.AddComponent <DynamicCharacterSystem>(); (thisUMAContext.dynamicCharacterSystem as DynamicCharacterSystem).dynamicallyAddFromResources = true; (thisUMAContext.dynamicCharacterSystem as DynamicCharacterSystem).dynamicallyAddFromAssetBundles = true; var thisDAL = thisUMAContext.gameObject.AddComponent <DynamicAssetLoader>(); DynamicAssetLoader.Instance = thisDAL; return(EditorUMAContext); }
public static GameObject CreateEditorContext() { GameObject EditorUMAContextBase = null; if (UnityEditor.BuildPipeline.isBuildingPlayer) { return(null); } if (Application.isPlaying) { if (Debug.isDebugBuild) { Debug.LogWarning("There was no UMAContext in this scene. Please add the UMA_DCS prefab to this scene before you try to generate an UMA."); } return(null); } if (Debug.isDebugBuild) { Debug.Log("UMA Recipe Editor created an UMAEditorContext to enable editing. This will auto delete once you have finished editing your recipe or you add the UMA_DCS prefab to this scene."); } //if there is already an EditorUMAContextBase use it if (UMAContextBase.FindInstance() != null) { if (UMAContextBase.FindInstance().gameObject.name == "UMAEditorContext") { EditorUMAContextBase = UMAContextBase.FindInstance().gameObject; //if the UMAContextBase itself is on this game object, it means this was created and not deleted by the previous version of 'CreateEditorContext' //(The new version creates the UMAContextBase on a child game object called 'UMAContextBase' so that UMAContextBase.FindInstance can find it properly) //so in this case delete all the components that would have been added from the found gameObject from the previous code if (EditorUMAContextBase.GetComponent <UMAContextBase>()) { UMAUtils.DestroySceneObject(EditorUMAContextBase.GetComponent <UMAContextBase>()); //should also make the instance null again } } else if (UMAContextBase.FindInstance().gameObject.transform.parent.gameObject.name == "UMAEditorContext") { EditorUMAContextBase = UMAContextBase.FindInstance().gameObject.transform.parent.gameObject; } } else if (GameObject.Find("UMAEditorContext")) { EditorUMAContextBase = GameObject.Find("UMAEditorContext"); } else { EditorUMAContextBase = new GameObject(); EditorUMAContextBase.name = "UMAEditorContext"; } //Make this GameObject not show up in the scene or save EditorUMAContextBase.hideFlags = HideFlags.DontSave | HideFlags.NotEditable; //if this gameobject does not contain an UMAContextBase add it - we have to call it UMAContextBase because UMAContextBase.FindInstance searches for that game object var thisUMAContextBase = UMAContextBase.Instance = EditorUMAContextBase.GetComponentInChildren <UMAContextBase>(); if (UMAContextBase.Instance == null) { var thisUMAContextBaseGO = new GameObject(); thisUMAContextBaseGO.name = "UMAContext"; thisUMAContextBaseGO.transform.parent = EditorUMAContextBase.transform; thisUMAContextBase = thisUMAContextBaseGO.AddComponent <UMAGlobalContext>(); UMAContextBase.Instance = thisUMAContextBase; } return(EditorUMAContextBase); }