private SlotDataAsset CreateSlot() { if (slotName == null || slotName == "") { Debug.LogError("slotName must be specified."); return(null); } SlotDataAsset sd = CreateSlot_Internal(); return(sd); }
private SlotDataAsset[] GetSlotDataAssetArray() { int arrayCount = m_SlotDataAssetCount.intValue; SlotDataAsset[] SlotDataAssetArray = new SlotDataAsset[arrayCount]; for (int i = 0; i < arrayCount; i++) { SlotDataAssetArray[i] = m_Object.FindProperty(string.Format(kArrayData, i)).objectReferenceValue as SlotDataAsset; } return(SlotDataAssetArray); }
private void DropAreaGUI(Rect dropArea) { var evt = Event.current; if (evt.type == EventType.DragUpdated) { if (dropArea.Contains(evt.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } } if (evt.type == EventType.DragPerform) { if (dropArea.Contains(evt.mousePosition)) { DragAndDrop.AcceptDrag(); UnityEngine.Object[] draggedObjects = DragAndDrop.objectReferences as UnityEngine.Object[]; var meshes = new HashSet <SkinnedMeshRenderer>(); for (int i = 0; i < draggedObjects.Length; i++) { RecurseObject(draggedObjects[i], meshes); } SlotDataAsset sd = null; float current = 1f; float total = (float)meshes.Count; foreach (var mesh in meshes) { EditorUtility.DisplayProgressBar(string.Format("Creating Slots {0} of {1}", current, total), string.Format("Slot: {0}", mesh.name), (current / total)); slotMesh = mesh; GetMaterialName(mesh.name, mesh); sd = CreateSlot(); if (sd != null) { Debug.Log("Batch importer processed mesh: " + slotName); string AssetPath = AssetDatabase.GetAssetPath(sd.GetInstanceID()); if (createOverlay) { CreateOverlay(AssetPath.Replace(sd.name, sd.slotName + "_Overlay"), sd); } if (createRecipe) { CreateRecipe(AssetPath.Replace(sd.name, sd.slotName + "_Recipe"), sd, null); } } current++; } EditorUtility.ClearProgressBar(); } } }
private OverlayDataAsset CreateOverlay(string path, SlotDataAsset sd) { OverlayDataAsset asset = ScriptableObject.CreateInstance <OverlayDataAsset>(); asset.overlayName = slotName + "_Overlay"; asset.material = sd.material; AssetDatabase.CreateAsset(asset, path); AssetDatabase.SaveAssets(); if (addToGlobalLibrary) { UMAAssetIndexer.Instance.EvilAddAsset(typeof(OverlayDataAsset), asset); } return(asset); }
private bool DropAreaGUI(Rect dropArea) { int count = 0; var evt = Event.current; if (evt.type == EventType.DragUpdated) { if (dropArea.Contains(evt.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } } if (evt.type == EventType.DragPerform) { if (dropArea.Contains(evt.mousePosition)) { DragAndDrop.AcceptDrag(); UnityEngine.Object[] draggedObjects = DragAndDrop.objectReferences as UnityEngine.Object[]; for (int i = 0; i < draggedObjects.Length; i++) { if (draggedObjects[i]) { SlotDataAsset tempSlotDataAsset = draggedObjects[i] as SlotDataAsset; if (tempSlotDataAsset) { AddSlotDataAsset(tempSlotDataAsset); count++; continue; } var path = AssetDatabase.GetAssetPath(draggedObjects[i]); if (System.IO.Directory.Exists(path)) { RecursiveScanFoldersForAssets(path, ref count); } } } if (count > 0) { return(true); } } } return(false); }
private void DropAreaGUI(Rect dropArea) { var evt = Event.current; if (evt.type == EventType.DragUpdated) { if (dropArea.Contains(evt.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } } if (evt.type == EventType.DragPerform) { if (dropArea.Contains(evt.mousePosition)) { DragAndDrop.AcceptDrag(); UnityEngine.Object[] draggedObjects = DragAndDrop.objectReferences as UnityEngine.Object[]; var meshes = new HashSet <SkinnedMeshRenderer>(); for (int i = 0; i < draggedObjects.Length; i++) { RecurseObject(draggedObjects[i], meshes); } SlotDataAsset sd = null; foreach (var mesh in meshes) { slotMesh = mesh; GetMaterialName(mesh.name, mesh); sd = CreateSlot(); if (sd != null) { Debug.Log("Batch importer processed mesh: " + slotName); string AssetPath = AssetDatabase.GetAssetPath(sd.GetInstanceID()); if (createOverlay) { CreateOverlay(AssetPath.Replace(sd.name, sd.slotName + "_Overlay"), sd); } if (createRecipe) { CreateRecipe(AssetPath.Replace(sd.name, sd.slotName + "_Recipe")); } } } } } }
public SlotDataAsset Creat() { if (slotMaterial == null || string.IsNullOrEmpty(foldpath) || string.IsNullOrEmpty(assetName)) { throw new System.Exception("slotMaterial or foldpath or assetName is null"); } if (!Directory.Exists(foldpath)) { Directory.CreateDirectory(foldpath); } string path = PathHelper.GetRelativeAssetPath(foldpath); SlotDataAsset tmpSlot = UMASlotProcessingUtil.CreateSlotData(path, assetName, slotMesh, slotMaterial, null); return(tmpSlot); }
private void CreateOverlay(string path, SlotDataAsset sd) { OverlayDataAsset asset = ScriptableObject.CreateInstance <OverlayDataAsset>(); asset.overlayName = slotName + "_Overlay"; asset.material = sd.material; AssetDatabase.CreateAsset(asset, path); AssetDatabase.SaveAssets(); if (addToGlobalLibrary) { UMAAssetIndexer.Instance.EvilAddAsset(typeof(OverlayDataAsset), asset); } if (addToLocalLibrary && UMAContext.Instance != null) { if (UMAContext.Instance.overlayLibrary != null) { UMAContext.Instance.overlayLibrary.AddOverlayAsset(asset); } } }
public SlotDataAsset CreatSlot() { string fold = string.Format("{0}/{1}/{2}", baseFold, PartName, UMAUtils.Slot); GameObject go = gameObject.FindInChildren(gameObject.name + "_" + PartName); SkinnedMeshRenderer slotMesh = go.GetComponentInChildren <SkinnedMeshRenderer>(); if (slotMesh == null) { throw new System.Exception(gameObject.name + " SkinnedMeshRenderer is null"); } slotMesh.sharedMaterial = null; slotMesh.sharedMaterials = new Material[0]; SlotEditor se = new SlotEditor(slotMesh, go.name, fold, uMaterial); SlotDataAsset slot = se.Creat(); return(slot); }
private SlotDataAsset CreateSlot_Internal() { var material = slotMaterial; if (slotName == null || slotName == "") { Debug.LogError("slotName must be specified."); return(null); } if (material == null) { Debug.LogWarning("No UMAMaterial specified, you need to specify that later."); return(null); } if (slotFolder == null) { Debug.LogError("Slot folder not supplied"); return(null); } if (slotMesh == null) { Debug.LogError("Slot Mesh not supplied."); return(null); } List <string> KeepList = new List <string>(); foreach (BoneName b in KeepBones) { KeepList.Add(b.strValue); } SlotDataAsset slot = UMASlotProcessingUtil.CreateSlotData(AssetDatabase.GetAssetPath(slotFolder), GetAssetFolder(), GetAssetName(), GetSlotName(slotMesh), nameAfterMaterial, slotMesh, material, normalReferenceMesh, KeepList, RootBone, binarySerialization); slot.tags = Tags.ToArray(); return(slot); }
private void InitTagList(SlotDataAsset _slotDataAsset) { var HideTagsProperty = serializedObject.FindProperty("tags"); slot.tagList = new ReorderableList(serializedObject, HideTagsProperty, true, true, true, true); slot.tagList.drawHeaderCallback = (Rect rect) => { if (_slotDataAsset.isWildCardSlot) { EditorGUI.LabelField(rect, "Match the following tags:"); } else { EditorGUI.LabelField(rect, "Tags"); } }; slot.tagList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = (target as SlotDataAsset).tagList.serializedProperty.GetArrayElementAtIndex(index); rect.y += 2; element.stringValue = EditorGUI.TextField(new Rect(rect.x + 10, rect.y, rect.width - 10, EditorGUIUtility.singleLineHeight), element.stringValue); }; }
public override void OnInspectorGUI() { SlotDataAsset _slotDataAsset = target as SlotDataAsset; if (!tagListInitialized) { InitTagList(_slotDataAsset); } serializedObject.Update(); EditorGUI.BeginChangeCheck(); EditorGUILayout.DelayedTextField(slotName); if ((target as SlotDataAsset).isWildCardSlot) { EditorGUILayout.HelpBox("This is a wildcard slot", MessageType.Info); } if (_slotDataAsset.isWildCardSlot) { Editor.DrawPropertiesExcluding(serializedObject, WildcardSlotFields); } else { Editor.DrawPropertiesExcluding(serializedObject, RegularSlotFields); } GUILayout.Space(10); tagList.DoLayoutList(); eventsFoldout = EditorGUILayout.Foldout(eventsFoldout, "Slot Events"); if (eventsFoldout) { EditorGUILayout.PropertyField(CharacterBegun); if (!_slotDataAsset.isWildCardSlot) { EditorGUILayout.PropertyField(SlotAtlassed); EditorGUILayout.PropertyField(DNAApplied); } EditorGUILayout.PropertyField(CharacterCompleted); } foreach (var t in targets) { var slotDataAsset = t as SlotDataAsset; if (slotDataAsset != null) { if (slotDataAsset.animatedBoneHashes.Length != slotDataAsset.animatedBoneNames.Length) { slotDataAsset.animatedBoneHashes = new int[slotDataAsset.animatedBoneNames.Length]; for (int i = 0; i < slotDataAsset.animatedBoneNames.Length; i++) { slotDataAsset.animatedBoneHashes[i] = UMASkeleton.StringToHash(slotDataAsset.animatedBoneNames[i]); } GUI.changed = true; EditorUtility.SetDirty(slotDataAsset); } } } if (!(target as SlotDataAsset).isWildCardSlot) { GUILayout.Space(20); Rect updateDropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true)); GUI.Box(updateDropArea, "Drag SkinnedMeshRenderers here to update the slot meshData."); GUILayout.Space(10); UpdateSlotDropAreaGUI(updateDropArea); GUILayout.Space(10); Rect boneDropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true)); GUI.Box(boneDropArea, "Drag Bone Transforms here to add their names to the Animated Bone Names.\nSo the power tools will preserve them!"); GUILayout.Space(10); AnimatedBoneDropAreaGUI(boneDropArea); } serializedObject.ApplyModifiedProperties(); if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(target); AssetDatabase.SaveAssets(); } }
public override void OnInspectorGUI() { EditorGUILayout.LabelField("Mesh Selector Utilities", EditorStyles.largeLabel, GUILayout.MaxHeight(25)); scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUIStyle.none); GUILayout.Space(20); EditorGUILayout.BeginHorizontal(); bool newNormals = EditorGUILayout.Toggle("Visualize Normals", _Source.visualizeNormals); if (newNormals != _Source.visualizeNormals) { _Source.visualizeNormals = newNormals; SceneView.RepaintAll(); } Color32 newNormalColor = EditorGUILayout.ColorField(_Source.normalsColor); if (!newNormalColor.Equals(_Source.normalsColor)) { _Source.normalsColor = newNormalColor; SceneView.RepaintAll(); } EditorGUILayout.EndHorizontal(); float newNormalLength = EditorGUILayout.Slider("Normals Length", _Source.normalsLength, 0.01f, 1.5f); if (newNormalLength != _Source.normalsLength) { _Source.normalsLength = newNormalLength; SceneView.RepaintAll(); } GUILayout.Space(20); EditorGUILayout.LabelField(new GUIContent("Occlusion Slot (Optional)", "Use this mesh to attempt to automatically detect occluded triangles")); EditorGUILayout.BeginHorizontal(); SlotDataAsset newOccluderSlotData = (SlotDataAsset)EditorGUILayout.ObjectField(_OccluderSlotData, typeof(SlotDataAsset), false); MeshHideAsset newOccluderMeshHide = (MeshHideAsset)EditorGUILayout.ObjectField(_OccluderMeshHide, typeof(MeshHideAsset), false); if (GUILayout.Button("Clear", GUILayout.MaxWidth(60))) { _OccluderSlotData = null; newOccluderSlotData = null; _OccluderMeshHide = null; newOccluderMeshHide = null; _Source.occlusionMesh = null; SceneView.RepaintAll(); } if (newOccluderSlotData != _OccluderSlotData) { _OccluderSlotData = newOccluderSlotData; _OccluderMeshHide = null; newOccluderMeshHide = null; if (_OccluderSlotData != null) { _Source.UpdateOcclusionMesh(_OccluderSlotData.meshData, _occluderOffset, _occluderPosition, _occluderRotation, _occluderScale); } else { _Source.occlusionMesh = null; } SceneView.RepaintAll(); } if (newOccluderMeshHide != _OccluderMeshHide) { if (newOccluderMeshHide == _Source.meshAsset) { EditorUtility.DisplayDialog("Error", "Can not select the same MeshHideAsset currently being edited!", "OK"); } else { _OccluderMeshHide = newOccluderMeshHide; _OccluderSlotData = null; newOccluderSlotData = null; if (_OccluderMeshHide != null && _OccluderMeshHide != _Source.meshAsset) { _Source.UpdateOcclusionMesh(_OccluderMeshHide, _occluderOffset, _occluderPosition, _occluderRotation, _occluderScale); } else { _Source.occlusionMesh = null; } SceneView.RepaintAll(); } } EditorGUILayout.EndHorizontal(); EditorGUI.BeginDisabledGroup(_Source.occlusionMesh == null); bool changed = false; Color32 newOcclusionColor = EditorGUILayout.ColorField("Occlusion Mesh Color", _Source.occlusionColor); if (!newOcclusionColor.Equals(_Source.occlusionColor)) { _Source.occlusionColor = newOcclusionColor; SceneView.RepaintAll(); } bool newWireframe = EditorGUILayout.Toggle("Occlusion Mesh Wireframe", _Source.occlusionWireframe); if (newWireframe != _Source.occlusionWireframe) { _Source.occlusionWireframe = newWireframe; SceneView.RepaintAll(); } float newOffset = EditorGUILayout.Slider(new GUIContent("Normal Offset", "Distance along the normal to offset each vertex of the occlusion mesh"), _occluderOffset, -0.1f, 0.25f); if (!Mathf.Approximately(newOffset, _occluderOffset)) { _occluderOffset = newOffset; changed = true; } Vector3 newPosition = EditorGUILayout.Vector3Field(new GUIContent("Position", "Offset the position of the occluder"), _occluderPosition); if (newPosition != _occluderPosition) { _occluderPosition = newPosition; changed = true; } Vector3 newRotation = EditorGUILayout.Vector3Field(new GUIContent("Rotation", "Offset the rotation (degrees) of the occluder"), _occluderRotation); if (newRotation != _occluderRotation) { _occluderRotation = newRotation; changed = true; } Vector3 newScale = EditorGUILayout.Vector3Field(new GUIContent("Scale", "Offset the scale of the occluder"), _occluderScale); if (newScale != _occluderScale) { _occluderScale = newScale; changed = true; } bothDirections = EditorGUILayout.Toggle(new GUIContent("RayCast Both Directions", "Determines whether to raycast only outward along the normal from the source mesh or in both directions. Both directions can be helpful if the occlusion slot is close to the surface of the source mesh or even slightly under it."), bothDirections); if (changed) { if (_OccluderSlotData) { _Source.UpdateOcclusionMesh(_OccluderSlotData.meshData, _occluderOffset, _occluderPosition, _occluderRotation, _occluderScale); } if (_OccluderMeshHide) { _Source.UpdateOcclusionMesh(_OccluderMeshHide, _occluderOffset, _occluderPosition, _occluderRotation, _occluderScale); } } if (GUILayout.Button(new GUIContent("Raycast Hidden Faces", "Warning! This will clear the current selection."))) { RaycastHide(bothDirections); } EditorGUI.EndDisabledGroup(); GUILayout.Space(20); textureMap = EditorGUILayout.ObjectField("Set From Texture Map", textureMap, typeof(Texture2D), false) as Texture2D; if (GUILayout.Button("Calculate occlusion from texture.")) { if (_Source != null) { if (textureMap == null) { EditorUtility.DisplayDialog("Warning", "A readable texture must be selected before processing.", "OK"); } else { _Source.UpdateFromTexture(textureMap); } } } GUILayout.Space(20); if (GUILayout.Button(new GUIContent("View UV Layout", "Brings up a window displaying the uv layout of the currently selected object and export to texture options."))) { GeometryUVEditorWindow.Init(_Source); } GUILayout.EndScrollView(); }
public virtual void AddSlotAsset(SlotDataAsset slot) { throw new NotFiniteNumberException(); }
void OnGUI() { GUILayout.Label("UMA Slot Builder"); GUILayout.Space(20); normalReferenceMesh = EditorGUILayout.ObjectField("Seams Mesh (Optional) ", normalReferenceMesh, typeof(SkinnedMeshRenderer), false) as SkinnedMeshRenderer; slotMesh = EditorGUILayout.ObjectField("Slot Mesh ", slotMesh, typeof(SkinnedMeshRenderer), false) as SkinnedMeshRenderer; slotMaterial = EditorGUILayout.ObjectField("UMAMaterial ", slotMaterial, typeof(UMAMaterial), false) as UMAMaterial; slotFolder = EditorGUILayout.ObjectField("Slot Destination Folder", slotFolder, typeof(UnityEngine.Object), false) as UnityEngine.Object; EnforceFolder(ref slotFolder); RootBone = EditorGUILayout.TextField("Root Bone (ex:'Global')", RootBone); slotName = EditorGUILayout.TextField("Element Name", slotName); EditorGUILayout.BeginHorizontal(); createOverlay = EditorGUILayout.Toggle("Create Overlay", createOverlay); EditorGUILayout.LabelField(slotName + "_Overlay"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); createRecipe = EditorGUILayout.Toggle("Create Wardrobe Recipe ", createRecipe); EditorGUILayout.LabelField(slotName + "_Recipe"); EditorGUILayout.EndHorizontal(); addToGlobalLibrary = EditorGUILayout.Toggle("Add To Global Library", addToGlobalLibrary); if (UMAContext.Instance != null) { if (UMAContext.Instance.slotLibrary != null) { addToLocalLibrary = EditorGUILayout.Toggle("Add to Scene Library", addToLocalLibrary); } } if (GUILayout.Button("Create Slot")) { Debug.Log("Processing..."); SlotDataAsset sd = CreateSlot(); if (sd != null) { Debug.Log("Success."); string AssetPath = AssetDatabase.GetAssetPath(sd.GetInstanceID()); if (addToGlobalLibrary) { UMAAssetIndexer.Instance.EvilAddAsset(typeof(SlotDataAsset), sd); } if (addToLocalLibrary && UMAContext.Instance != null) { if (UMAContext.Instance.slotLibrary != null) { UMAContext.Instance.slotLibrary.AddSlotAsset(sd); } } if (createOverlay) { CreateOverlay(AssetPath.Replace(sd.name, sd.slotName + "_Overlay"), sd); } if (createRecipe) { CreateRecipe(AssetPath.Replace(sd.name, sd.slotName + "_Recipe")); } } } if (slotMesh != null) { if (slotMesh.localBounds.size.x > 10.0f || slotMesh.localBounds.size.y > 10.0f || slotMesh.localBounds.size.z > 10.0f) { EditorGUILayout.HelpBox("This slot's size is very large. It's import scale may be incorrect!", MessageType.Warning); } if (slotMesh.localBounds.size.x < 0.01f || slotMesh.localBounds.size.y < 0.01f || slotMesh.localBounds.size.z < 0.01f) { EditorGUILayout.HelpBox("This slot's size is very small. It's import scale may be incorrect!", MessageType.Warning); } } GUILayout.Label("", EditorStyles.boldLabel); Rect dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true)); GUI.Box(dropArea, "Drag meshes here"); GUILayout.Label("Automatic Drag and Drop processing", EditorStyles.boldLabel); relativeFolder = EditorGUILayout.ObjectField("Relative Folder", relativeFolder, typeof(UnityEngine.Object), false) as UnityEngine.Object; EnforceFolder(ref relativeFolder); DropAreaGUI(dropArea); }
/// <summary> /// Removes a list of downloadingAssetItems from the downloadingItems List. /// </summary> /// <param name="assetName"></param> public IEnumerator RemoveDownload(List <DownloadingAssetItem> itemsToRemove) { //Not used any more UMAs check the status of stuff they asked for themselves //Dictionary<UMAAvatarBase, List<string>> updatedUMAs = new Dictionary<UMAAvatarBase, List<string>>(); foreach (DownloadingAssetItem item in itemsToRemove) { item.isBeingRemoved = true; } foreach (DownloadingAssetItem item in itemsToRemove) { string error = ""; //we need to check everyitem in this batch belongs to an asset bundle that has actually been loaded LoadedAssetBundle loadedBundleTest = AssetBundleManager.GetLoadedAssetBundle(item.containingBundle, out error); AssetBundle loadedBundleABTest = loadedBundleTest.m_AssetBundle; if (loadedBundleABTest == null && (String.IsNullOrEmpty(error))) { while (loadedBundleTest.m_AssetBundle == null) { //could say we are unpacking here yield return(null); } } if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); yield break; } } //Now every item in the batch should be in a loaded bundle that is ready to use. foreach (DownloadingAssetItem item in itemsToRemove) { if (item != null) { string error = ""; var loadedBundle = AssetBundleManager.GetLoadedAssetBundle(item.containingBundle, out error); var loadedBundleAB = loadedBundle.m_AssetBundle; if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); yield break; } var assetType = item.tempAsset.GetType(); //deal with RuntimeAnimatorController funkiness //the actual type of an instantiated clone of a RuntimeAnimatorController in the editor is UnityEditor.Animations.AnimatorController if (assetType.ToString().IndexOf("AnimatorController") > -1) { assetType = typeof(RuntimeAnimatorController); } var itemFilename = AssetBundleManager.AssetBundleIndexObject.GetFilenameFromAssetName(item.containingBundle, item.requiredAssetName, assetType.ToString()); if (assetType == typeof(RaceData)) { //HACK TO FIX RACEDATA DYNAMICDNACONVERTERS DYNAMICDNA ASSETS CAUSING LOAD FAILURES in UNITY 5.5+ //As of Unity 5.5 a bug has reappeared when loading some types of assets that reference assets in other bundles. //AssetBundleManager successfully ensures these required bundles are loaded first, but even so Unity fils to load //the required asset from them in some cases, notably it seems when the required asset is set in the field of a Prefab (like our DNAAssets are) //To fix this generally we could 'LoadAllAssets' from any dependent bundles, but this could incur significant memory overhead //So for now we will just fix this for UMA and hope a patch is forthcoming in a subsequent version of Unity //FIXED as of Unity5.6.2f1 #if UNITY_5_5 || UNITY_5_6_0 || UNITY_5_6_1 if (AssetBundleManager.AssetBundleIndexObject.GetAllDependencies(item.containingBundle).Length > 0) { var allDeps = AssetBundleManager.AssetBundleIndexObject.GetAllDependencies(item.containingBundle); for (int i = 0; i < allDeps.Length; i++) { string depsError = ""; LoadedAssetBundle depsBundle = AssetBundleManager.GetLoadedAssetBundle(allDeps[i], out depsError); if (String.IsNullOrEmpty(depsError) && depsBundle != null) { depsBundle.m_AssetBundle.LoadAllAssets <DynamicUMADnaAsset>(); } } } #endif RaceData actualRace = loadedBundleAB.LoadAsset <RaceData>(itemFilename); UMAContext.Instance.raceLibrary.AddRace(actualRace); UMAContext.Instance.raceLibrary.UpdateDictionary(); //Refresh DCS so that anything that this race is cross compatible with gets added to its list of available recipes (UMAContext.Instance.dynamicCharacterSystem as DynamicCharacterSystem).RefreshRaceKeys(); } else if (assetType == typeof(SlotDataAsset)) { SlotDataAsset thisSlot = null; thisSlot = loadedBundleAB.LoadAsset <SlotDataAsset>(itemFilename); if (thisSlot != null) { UMAContext.Instance.slotLibrary.AddSlotAsset(thisSlot); } else { Debug.LogWarning("[DynamicAssetLoader] could not add downloaded slot" + item.requiredAssetName); } } else if (assetType == typeof(OverlayDataAsset)) { OverlayDataAsset thisOverlay = null; thisOverlay = loadedBundleAB.LoadAsset <OverlayDataAsset>(itemFilename); if (thisOverlay != null) { UMAContext.Instance.overlayLibrary.AddOverlayAsset(thisOverlay); } else { Debug.LogWarning("[DynamicAssetLoader] could not add downloaded overlay" + item.requiredAssetName + " from assetbundle " + item.containingBundle); } } else if (assetType == typeof(UMATextRecipe)) { UMATextRecipe downloadedRecipe = loadedBundleAB.LoadAsset <UMATextRecipe>(itemFilename); (UMAContext.Instance.dynamicCharacterSystem as DynamicCharacterSystem).AddRecipe(downloadedRecipe); } else if (assetType == typeof(UMAWardrobeRecipe)) { UMAWardrobeRecipe downloadedRecipe = loadedBundleAB.LoadAsset <UMAWardrobeRecipe>(itemFilename); (UMAContext.Instance.dynamicCharacterSystem as DynamicCharacterSystem).AddRecipe(downloadedRecipe); } else if (item.dynamicCallback.Count > 0) { //get the asset as whatever the type of the tempAsset is //send this as an array to the dynamicCallback var downloadedAsset = loadedBundleAB.LoadAsset(itemFilename, assetType); var downloadedAssetArray = Array.CreateInstance(assetType, 1); downloadedAssetArray.SetValue(downloadedAsset, 0); for (int i = 0; i < item.dynamicCallback.Count; i++) { item.dynamicCallback[i].DynamicInvoke(downloadedAssetArray); } } if (!String.IsNullOrEmpty(error)) { Debug.LogError(error); } } downloadingItems.Remove(item); } if (downloadingItems.Count == 0) { areDownloadedItemsReady = true; //AssetBundleManager.UnloadAllAssetBundles();//we cant do this yet } //yield break; }
protected virtual bool DrawWardrobeSlotsFields(Type TargetType, bool ShowHelp = false) { #region Setup bool doUpdate = false; //Field Infos FieldInfo ReplacesField = TargetType.GetField("replaces", BindingFlags.Public | BindingFlags.Instance); FieldInfo CompatibleRacesField = TargetType.GetField("compatibleRaces", BindingFlags.Public | BindingFlags.Instance); FieldInfo WardrobeSlotField = TargetType.GetField("wardrobeSlot", BindingFlags.Public | BindingFlags.Instance); FieldInfo SuppressWardrobeSlotField = TargetType.GetField("suppressWardrobeSlots", BindingFlags.Public | BindingFlags.Instance); FieldInfo HidesField = TargetType.GetField("Hides", BindingFlags.Public | BindingFlags.Instance); FieldInfo DisplayValueField = TargetType.GetField("DisplayValue", BindingFlags.Public | BindingFlags.Instance); FieldInfo UserField = TargetType.GetField("UserField", BindingFlags.Public | BindingFlags.Instance); // ************************************ // field values // ************************************ string replaces = ""; if (ReplacesField != null) { object o = ReplacesField.GetValue(target); if (o != null) { replaces = (string)ReplacesField.GetValue(target); } } List <string> compatibleRaces = (List <string>)CompatibleRacesField.GetValue(target); string wardrobeSlot = (string)WardrobeSlotField.GetValue(target); List <string> suppressWardrobeSlot = (List <string>)SuppressWardrobeSlotField.GetValue(target); List <string> hides = (List <string>)HidesField.GetValue(target); string displayValue = (string)DisplayValueField.GetValue(target); string userFieldValue = (string)UserField.GetValue(target); #endregion #region Display Value UI //displayValue UI string PreviousValue = displayValue; displayValue = EditorGUILayout.DelayedTextField("Display Value", displayValue); if (displayValue != PreviousValue) { DisplayValueField.SetValue(target, displayValue); doUpdate = true; } if (ShowHelp) { EditorGUILayout.HelpBox("Display Value can be used to store a user-friendly name for this item. It's not used for constructing the character, but it can be used in UI design by accessing the .DisplayValue field on the recipe.", MessageType.Info); } PreviousValue = userFieldValue; userFieldValue = EditorGUILayout.DelayedTextField("User Field", userFieldValue); if (userFieldValue != PreviousValue) { UserField.SetValue(target, userFieldValue); doUpdate = true; } if (ShowHelp) { EditorGUILayout.HelpBox("User Field is ignored by the system. You can use this to store data that can later be used by your application to provide filtering or categorizing, etc.", MessageType.Info); } #endregion #region Wardrobe Slot UI //wardrobeSlot UI int selectedWardrobeSlotIndex = GenerateWardrobeSlotsEnum(wardrobeSlot, compatibleRaces, false); string newWardrobeSlot; int newSuppressFlags = 0; List <string> newSuppressWardrobeSlot = new List <string>(); if (selectedWardrobeSlotIndex == -1) { EditorGUILayout.LabelField("No Compatible Races set. You need to select a compatible race in order to set a wardrobe slot"); newWardrobeSlot = "None"; } else if (selectedWardrobeSlotIndex == -2) { EditorGUILayout.LabelField("Not all compatible races found. Do you have the all correct Race(s) available Locally?"); newWardrobeSlot = "None"; } else { int newSelectedWardrobeSlotIndex = EditorGUILayout.Popup("Wardrobe Slot", selectedWardrobeSlotIndex, generatedWardrobeSlotOptionsLabels.ToArray()); if (newSelectedWardrobeSlotIndex != selectedWardrobeSlotIndex) { WardrobeSlotField.SetValue(target, generatedWardrobeSlotOptions[newSelectedWardrobeSlotIndex]); doUpdate = true; } newWardrobeSlot = generatedWardrobeSlotOptions.Count > 0 ? generatedWardrobeSlotOptions[selectedWardrobeSlotIndex] : "None"; } if (ShowHelp) { EditorGUILayout.HelpBox("Wardrobe Slot: This assigns the recipe to a Wardrobe Slot. The wardrobe slots are defined on the race. Characters can have only one recipe per Wardrobe Slot at a time, so for example, adding a 'beard' recipe to a character will replace the existing 'beard' if there is one", MessageType.Info); } #endregion #region Suppress UI //SuppressedSlots UI int suppressFlags = 0; for (int i = 0; i < generatedWardrobeSlotOptions.Count; i++) { if (suppressWardrobeSlot.Contains(generatedWardrobeSlotOptions[i])) { suppressFlags |= 0x1 << i; } } newSuppressFlags = EditorGUILayout.MaskField("Suppress Wardrobe Slot(s)", suppressFlags, generatedWardrobeSlotOptionsLabels.ToArray()); for (int i = 0; i < generatedWardrobeSlotOptions.Count; i++) { if ((newSuppressFlags & (1 << i)) == (1 << i)) { newSuppressWardrobeSlot.Add(generatedWardrobeSlotOptions[i]); } } if (newSuppressWardrobeSlot.Count > 1) { GUI.enabled = false; string swsl2Result = String.Join(", ", newSuppressWardrobeSlot.ToArray()); EditorGUILayout.TextField(swsl2Result); GUI.enabled = true; } if (ShowHelp) { EditorGUILayout.HelpBox("Suppress: This will stop a different wardrobe slot from displaying. For example, if you have a full-length robe assigned to a 'chest' wardrobe slot, you would want to suppress whatever is assigned to the 'legs' wardrobe slot, so they don't poke through. This is typically used for dresses, robes, and other items that cover multiple body areas.", MessageType.Info); } #endregion #region Hides UI //Hides UI EditorGUILayout.BeginHorizontal(); GenerateBaseSlotsEnum(compatibleRaces, false, hides); int hiddenBaseFlags = 0; List <string> newHides = new List <string>(); for (int i = 0; i < generatedBaseSlotOptions.Count; i++) { if (hides.Contains(generatedBaseSlotOptions[i])) { hiddenBaseFlags |= 0x1 << i; } } if (generatedBaseSlotOptionsLabels.Count > 0) { int newHiddenBaseFlags = 0; newHiddenBaseFlags = EditorGUILayout.MaskField("Hides Base Slot(s)", hiddenBaseFlags, generatedBaseSlotOptionsLabels.ToArray()); for (int i = 0; i < generatedBaseSlotOptionsLabels.Count; i++) { if ((newHiddenBaseFlags & (1 << i)) == (1 << i)) { newHides.Add(generatedBaseSlotOptions[i]); } } } else { EditorGUILayout.Popup("Hides Base Slots(s)", 0, new string[1] { "Nothing" }); } GUILayout.Space(8); if (GUILayout.Button("Select", GUILayout.MaxWidth(64), GUILayout.MaxHeight(16))) { slotHidePickerID = EditorGUIUtility.GetControlID(FocusType.Passive) + 101; EditorGUIUtility.ShowObjectPicker <SlotDataAsset>(null, false, "", slotHidePickerID); } if (Event.current.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == slotHidePickerID) { SlotDataAsset sda = EditorGUIUtility.GetObjectPickerObject() as SlotDataAsset; newHides.Add(sda.slotName); Event.current.Use(); GenerateBaseSlotsEnum(compatibleRaces, true, hides); } EditorGUILayout.EndHorizontal(); if (newHides.Count > 1) { GUI.enabled = false; string newHidesResult = String.Join(", ", newHides.ToArray()); EditorGUILayout.TextField(newHidesResult); GUI.enabled = true; } if (ShowHelp) { EditorGUILayout.HelpBox("Hides: This is used to hide parts of the base recipe. For example, if you create gloves, you may want to hide the 'hands', so you don't get poke-through", MessageType.Info); } #endregion #region Replaces UI if (ReplacesField != null) { List <string> ReplacesSlots = new List <string>(generatedBaseSlotOptions); ReplacesSlots.Insert(0, "Nothing"); int selectedIndex = ReplacesSlots.IndexOf(replaces); if (selectedIndex < 0) { selectedIndex = 0; // not found, point at "nothing" } selectedIndex = EditorGUILayout.Popup("Replaces", selectedIndex, ReplacesSlots.ToArray()); ReplacesField.SetValue(target, ReplacesSlots[selectedIndex]); } if (ShowHelp) { EditorGUILayout.HelpBox("Replaces: This is used to replace part of the base recipe while keeping it's overlays. For example, if you want to replace the head from the base race recipe with a High Poly head, you would 'replace' the head, not hide it. Only one slot can be replaced, and the recipe should only contain one slot.", MessageType.Info); } #endregion #region MeshHideArray //EditorGUIUtility.LookLikeInspector(); SerializedProperty meshHides = serializedObject.FindProperty("MeshHideAssets"); EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("+", GUILayout.MaxWidth(30))) { meshHideAssetPickerID = EditorGUIUtility.GetControlID(FocusType.Passive) + 100; EditorGUIUtility.ShowObjectPicker <MeshHideAsset>(null, false, "", meshHideAssetPickerID); } GUILayout.Space(10); if (Event.current.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == meshHideAssetPickerID) { meshHides.InsertArrayElementAtIndex(0); SerializedProperty element = meshHides.GetArrayElementAtIndex(0); element.objectReferenceValue = EditorGUIUtility.GetObjectPickerObject(); meshHideAssetPickerID = -1; } EditorGUILayout.PropertyField(meshHides, true); EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); } //EditorGUIUtility.LookLikeControls(); if (ShowHelp) { EditorGUILayout.HelpBox("MeshHideAssets: This is a list of advanced mesh hiding assets to hide their corresponding slot meshes on a per triangle basis.", MessageType.Info); } #endregion #region Update //Update the values if (newWardrobeSlot != wardrobeSlot) { WardrobeSlotField.SetValue(target, newWardrobeSlot); doUpdate = true; } if (!AreListsEqual <string>(newSuppressWardrobeSlot, suppressWardrobeSlot)) { SuppressWardrobeSlotField.SetValue(target, newSuppressWardrobeSlot); doUpdate = true; } if (!AreListsEqual <string>(newHides, hides)) { HidesField.SetValue(target, newHides); doUpdate = true; } #endregion return(doUpdate); }
public override void OnInspectorGUI() { EditorGUILayout.LabelField("Mesh Selector Utilities", EditorStyles.largeLabel, GUILayout.MaxHeight(25)); scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUIStyle.none); GUILayout.Space(20); EditorGUILayout.LabelField(new GUIContent("Occlusion Slot (Optional)", "Use this mesh to attempt to automatically detect occluded triangles")); SlotDataAsset newOccluder = (SlotDataAsset)EditorGUILayout.ObjectField(_Occluder, typeof(SlotDataAsset), false); if (newOccluder != _Occluder) { _Occluder = newOccluder; if (_Occluder != null) { _Source.CreateOcclusionMesh(_Occluder.meshData); } else { _Source.occlusionMesh = null; } } if (_Occluder != null) { bool newOffset = false; bool newRot = false; float previousOffset = EditorGUILayout.FloatField(new GUIContent("Occluder Offset", "Distance along the normal to offset each vertex of the occlusion mesh"), _occluderOffset); if (!Mathf.Approximately(previousOffset, _occluderOffset)) { _occluderOffset = previousOffset; newOffset = true; } Vector3 previousRot = EditorGUILayout.Vector3Field(new GUIContent("Rotation", "Offset the rotation (degrees) of the occluder"), _occluderRotation); if (previousRot != _occluderRotation) { _occluderRotation = previousRot; newRot = true; } if (newOffset || newRot) { _Source.UpdateOcclusionMesh(_occluderOffset, _occluderRotation); } if (GUILayout.Button(new GUIContent("Raycast Hidden Faces", "Warning! This will clear the current selection."))) { RaycastHide(); } } GUILayout.Space(20); textureMap = EditorGUILayout.ObjectField("Set From Texture Map", textureMap, typeof(Texture2D), false) as Texture2D; if (GUILayout.Button("Calculate occlusion from texture.")) { if (_Source != null) { if (textureMap == null) { EditorUtility.DisplayDialog("Warning", "A readable texture must be selected before processing.", "OK"); } else { _Source.UpdateFromTexture(textureMap); } } } GUILayout.EndScrollView(); }
void OnGUI() { GUILayout.Label("UMA Slot Builder"); GUILayout.Space(20); normalReferenceMesh = EditorGUILayout.ObjectField("Seams Mesh (Optional) ", normalReferenceMesh, typeof(SkinnedMeshRenderer), false) as SkinnedMeshRenderer; var newslotMesh = EditorGUILayout.ObjectField("Slot Mesh ", slotMesh, typeof(SkinnedMeshRenderer), false) as SkinnedMeshRenderer; if (newslotMesh != slotMesh) { errmsg = ""; slotMesh = newslotMesh; } slotMaterial = EditorGUILayout.ObjectField("UMAMaterial ", slotMaterial, typeof(UMAMaterial), false) as UMAMaterial; slotFolder = EditorGUILayout.ObjectField("Slot Destination Folder", slotFolder, typeof(UnityEngine.Object), false) as UnityEngine.Object; EnforceFolder(ref slotFolder); // // For now, we will disable this option. // It doesn't work in most cases. // RootBone = EditorGUILayout.TextField("Root Bone (ex:'Global')", RootBone); // slotName = EditorGUILayout.TextField("Slot Name", slotName); binarySerialization = EditorGUILayout.Toggle(new GUIContent("Binary Serialization", "Forces the created Mesh object to be serialized as binary. Recommended for large meshes and blendshapes."), binarySerialization); GUILayout.BeginHorizontal(EditorStyles.toolbarButton); GUILayout.Space(10); showTags = EditorGUILayout.Foldout(showTags, "Tags"); GUILayout.EndHorizontal(); if (showTags) { GUIHelper.BeginVerticalPadded(10, new Color(0.75f, 0.875f, 1f)); // Draw the button area GUILayout.BeginHorizontal(); if (GUILayout.Button("Add Tag", GUILayout.Width(80))) { Tags.Add(""); Repaint(); } GUILayout.Label(Tags.Count + " Tags defined"); GUILayout.EndHorizontal(); if (Tags.Count == 0) { GUILayout.Label("No tags defined", EditorStyles.helpBox); } else { int del = -1; for (int i = 0; i < Tags.Count; i++) { GUILayout.BeginHorizontal(); Tags[i] = GUILayout.TextField(Tags[i]); if (GUILayout.Button("\u0078", EditorStyles.miniButton, GUILayout.ExpandWidth(false))) { del = i; } GUILayout.EndHorizontal(); } if (del >= 0) { Tags.RemoveAt(del); Repaint(); } } // Draw the tags (or "No tags defined"); GUIHelper.EndVerticalPadded(10); } EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); EditorGUILayout.BeginHorizontal(); createOverlay = EditorGUILayout.Toggle("Create Overlay", createOverlay); EditorGUILayout.LabelField(slotName + "_Overlay"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); createRecipe = EditorGUILayout.Toggle("Create Wardrobe Recipe ", createRecipe); EditorGUILayout.LabelField(slotName + "_Recipe"); EditorGUILayout.EndHorizontal(); addToGlobalLibrary = EditorGUILayout.Toggle("Add To Global Library", addToGlobalLibrary); if (GUILayout.Button("Verify Slot")) { if (slotMesh == null) { errmsg = "Slot is null."; } else { Vector2[] uv = slotMesh.sharedMesh.uv; foreach (Vector2 v in uv) { if (v.x > 1.0f || v.x < 0.0f || v.y > 1.0f || v.y < 0.0f) { errmsg = "UV Coordinates are out of range and will likely have issues with atlassed materials. Textures should not be tiled unless using non-atlassed materials."; break; } } if (string.IsNullOrEmpty(errmsg)) { errmsg = "No errors found"; } } } if (!string.IsNullOrEmpty(errmsg)) { EditorGUILayout.HelpBox(errmsg, MessageType.Warning); } if (GUILayout.Button("Create Slot")) { Debug.Log("Processing..."); SlotDataAsset sd = CreateSlot(); if (sd != null) { Debug.Log("Success."); string AssetPath = AssetDatabase.GetAssetPath(sd.GetInstanceID()); if (addToGlobalLibrary) { UMAAssetIndexer.Instance.EvilAddAsset(typeof(SlotDataAsset), sd); } OverlayDataAsset od = null; if (createOverlay) { od = CreateOverlay(AssetPath.Replace(sd.name, sd.slotName + "_Overlay"), sd); } if (createRecipe) { CreateRecipe(AssetPath.Replace(sd.name, sd.slotName + "_Recipe"), sd, od); } } } if (slotMesh != null) { if (slotMesh.localBounds.size.x > 10.0f || slotMesh.localBounds.size.y > 10.0f || slotMesh.localBounds.size.z > 10.0f) { EditorGUILayout.HelpBox("This slot's size is very large. It's import scale may be incorrect!", MessageType.Warning); } if (slotMesh.localBounds.size.x < 0.01f || slotMesh.localBounds.size.y < 0.01f || slotMesh.localBounds.size.z < 0.01f) { EditorGUILayout.HelpBox("This slot's size is very small. It's import scale may be incorrect!", MessageType.Warning); } if (slotName == null || slotName == "") { slotName = slotMesh.name; } if (RootBone == null || RootBone == "") { RootBone = "Global"; } } GUILayout.Label("", EditorStyles.boldLabel); Rect dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true)); GUI.Box(dropArea, "Drag meshes here"); GUILayout.Label("Automatic Drag and Drop processing", EditorStyles.boldLabel); relativeFolder = EditorGUILayout.ObjectField("Relative Folder", relativeFolder, typeof(UnityEngine.Object), false) as UnityEngine.Object; EnforceFolder(ref relativeFolder); DropAreaGUI(dropArea); }
private void AddSlotDataAsset(SlotDataAsset slotElement) { m_SlotDataAssetCount.intValue++; SetSlotDataAsset(m_SlotDataAssetCount.intValue - 1, slotElement); }
public static void CreateCustomSlotAssetMenuItem() { SlotDataAsset sde = CustomAssetUtility.CreateAsset <SlotDataAsset>("", true, "Custom"); }
public List <SlotOverlayItem> CreatData() { List <SlotOverlayItem> sos = new List <SlotOverlayItem>(); int submeshIndex = 0; bool first = false; string firstSlotPath = null; for (int i = 0; i < sharedMaterials.Count; i++) { SlotOverlayItem item = new SlotOverlayItem(); string materialName = sharedMaterials[i]; string name = baseName + "-" + i; if (!first) { #region slot SlotEditor so = new SlotEditor(slotMesh, name, slotFold, Mat); SlotDataAsset firstSlot = so.Creat(); item.slot = firstSlot; firstSlotPath = string.Format("{0}/{1}_{2}.asset", PathHelper.GetRelativeAssetPath(slotFold), name, UMAUtils.Slot); #endregion first = true; } else { #region slot string target = string.Format("{0}/{1}_{2}.asset", PathHelper.GetRelativeAssetPath(slotFold), name, UMAUtils.Slot); FileUtil.CopyFileOrDirectory(firstSlotPath, target); AssetDatabase.Refresh(); ObjectBase obj = new ObjectBase(target); SlotDataAsset slotSub = obj.Load <SlotDataAsset>(); slotSub.subMeshIndex = i; item.slot = slotSub; #endregion } #region overlay OverlayEditor oe = null; if (materialName.EndsWith(CharacterConst.Common)) { oe = new OverlayEditor(overlayFold, comTexture, name, Mat); } else { oe = new OverlayEditor(overlayFold, diff, name, Mat); } OverlayDataAsset overlay = oe.CreatOverlay(); item.overlay = overlay; #endregion #region index item.partIndex = wearpos * 10 + i; #endregion sos.Add(item); } return(sos); }
public override void OnInspectorGUI() { serializedObject.Update(); MeshHideAsset source = target as MeshHideAsset; bool beginSceneEditing = false; //DrawDefaultInspector(); SlotDataAsset obj = EditorGUILayout.ObjectField("SlotDataAsset", source.asset, typeof(SlotDataAsset), false) as SlotDataAsset; if (obj != source.asset) { source.asset = obj as SlotDataAsset; if (_autoInitialize) { UpdateSourceAsset(obj); } } EditorGUILayout.LabelField("Slot Name", source.AssetSlotName.ToString()); if (source.HasReference) { EditorGUILayout.HelpBox("Warning: This Mesh Hide Asset contains a reference. It should be freed so the referenced asset is not included in the build.", MessageType.Warning); if (GUILayout.Button("Free Reference")) { source.FreeReference(); EditorUtility.SetDirty(source); AssetDatabase.SaveAssets(); } } _autoInitialize = EditorGUILayout.Toggle(new GUIContent("AutoInitialize (recommended)", "Checking this will auto initialize the MeshHideAsset when a slot is added (recommended). " + "For users that are rebuilding slots that don't change the geometry, the slot reference will be lost but can be reset without losing the existing MeshHide information by unchecking this."), _autoInitialize); if (source.asset == null) { EditorGUILayout.HelpBox("No SlotDataAsset set! Begin by adding a SlotDataAsset to the object field above.", MessageType.Error); } //Race Selector here GUILayout.Space(20); selectedRaceIndex = EditorGUILayout.Popup("Select Base Slot by Race", selectedRaceIndex, foundRaceNames.ToArray()); if (selectedRaceIndex <= 0) { EditorGUILayout.HelpBox("Quick selection of base slots by race. This is not needed to create a mesh hide asset, any slot can be used.", MessageType.Info); } else { UMAData.UMARecipe baseRecipe = new UMAData.UMARecipe(); foundRaces[selectedRaceIndex].baseRaceRecipe.Load(baseRecipe, UMAContextBase.Instance); foreach (SlotData sd in baseRecipe.slotDataList) { if (sd != null && sd.asset != null) { if (GUILayout.Button(string.Format("{0} ({1})", sd.asset.name, sd.slotName))) { if (UpdateSourceAsset(sd.asset)) { selectedRaceIndex = 0; } } } } } GUILayout.Space(20); if (source.TriangleCount > 0) { EditorGUILayout.LabelField("Triangle Indices Count: " + source.TriangleCount); EditorGUILayout.LabelField("Submesh Count: " + source.SubmeshCount); EditorGUILayout.LabelField("Hidden Triangle Count: " + source.HiddenCount); } else { EditorGUILayout.LabelField("No triangle array found"); } GUILayout.Space(20); if (!GeometrySelectorWindow.IsOpen) { EditorGUI.BeginDisabledGroup(source.asset == null); if (GUILayout.Button("Begin Editing", GUILayout.MinHeight(50))) { if (source.asset != null) { beginSceneEditing = true; } } EditorGUI.EndDisabledGroup(); GUILayout.Space(20); GUILayout.Label("Editing will be done in an empty scene."); GUILayout.Label("You will be prompted to save the scene"); GUILayout.Label("if there are any unsaved changes."); } serializedObject.ApplyModifiedProperties(); if (beginSceneEditing) { // This has to happen outside the inspector EditorApplication.delayCall += CreateSceneEditObject; } }
public override void OnInspectorGUI() { m_Object.Update(); GUILayout.Label("slotElementList", EditorStyles.boldLabel); SlotDataAsset[] slotElementList = GetSlotDataAssetArray(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Order by Name")) { canUpdate = false; List <SlotDataAsset> SlotDataAssetTemp = slotElementList.ToList(); //Make sure there's no invalid data for (int i = 0; i < SlotDataAssetTemp.Count; i++) { if (SlotDataAssetTemp[i] == null) { SlotDataAssetTemp.RemoveAt(i); i--; } } SlotDataAssetTemp.Sort((x, y) => x.name.CompareTo(y.name)); for (int i = 0; i < SlotDataAssetTemp.Count; i++) { SetSlotDataAsset(i, SlotDataAssetTemp[i]); } } if (GUILayout.Button("Update List")) { isDirty = true; canUpdate = false; } if (GUILayout.Button("Remove Duplicates")) { HashSet <SlotDataAsset> Slots = new HashSet <SlotDataAsset>(); foreach (SlotDataAsset osa in slotElementList) { Slots.Add(osa); } m_SlotDataAssetCount.intValue = Slots.Count; for (int i = 0; i < Slots.Count; i++) { SetSlotDataAsset(i, Slots.ElementAt(i)); } isDirty = true; canUpdate = false; } GUILayout.EndHorizontal(); GUILayout.Space(20); Rect dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true)); GUI.Box(dropArea, "Drag Slots here"); GUILayout.Space(20); for (int i = 0; i < m_SlotDataAssetCount.intValue; i++) { GUILayout.BeginHorizontal(); SlotDataAsset result = EditorGUILayout.ObjectField(slotElementList[i], typeof(SlotDataAsset), true) as SlotDataAsset; if (GUI.changed && canUpdate) { SetSlotDataAsset(i, result); } if (GUILayout.Button("-", GUILayout.Width(20.0f))) { canUpdate = false; RemoveSlotDataAssetAtIndex(i); } GUILayout.EndHorizontal(); if (i == m_SlotDataAssetCount.intValue - 1) { canUpdate = true; if (isDirty) { slotLibrary.UpdateDictionary(); isDirty = false; } } } DropAreaGUI(dropArea); if (GUILayout.Button("Add SlotDataAsset")) { AddSlotDataAsset(null); } if (GUILayout.Button("Clear List")) { m_SlotDataAssetCount.intValue = 0; } if (GUILayout.Button("Remove Invalid Slot Data")) { RemoveInvalidSlotDataAsset(slotElementList); } m_Object.ApplyModifiedProperties(); }
static void InitializeUMA() {//Initialize UMA context // UMA GameObject uma = new GameObject(); uma.name = "UMA"; GameObject parent; if (parent = Selection.activeGameObject) { uma.transform.SetParent(parent.transform); } // Race Library GameObject races = new GameObject(); races.name = "RaceLibrary"; races.transform.SetParent(uma.transform); RaceLibrary raceLibrary = races.AddComponent <RaceLibrary>(); //null search in all assets folder, t means type, so we are searching Uma.RaceData string[] racesData = AssetDatabase.FindAssets("t: RaceData", null); foreach (string data in racesData) { //get the path string racePath = AssetDatabase.GUIDToAssetPath(data); RaceData raceAsset = AssetDatabase.LoadAssetAtPath <RaceData>(racePath); raceLibrary.AddRace(raceAsset); } // Slots GameObject slots = new GameObject(); slots.name = "SlotLibrary"; slots.transform.SetParent(uma.transform); SlotLibrary slotLibrary = slots.AddComponent <SlotLibrary>(); //null search in all assets folder, t means type, so we are searching Uma.RaceData string[] slotsData = AssetDatabase.FindAssets("t: SlotDataAsset", null); foreach (string data in slotsData) { //get the path string slotPath = AssetDatabase.GUIDToAssetPath(data); SlotDataAsset slotAsset = AssetDatabase.LoadAssetAtPath <SlotDataAsset>(slotPath); slotLibrary.AddSlotAsset(slotAsset); } // Overlays GameObject overlays = new GameObject(); overlays.name = "OverlayLibrary"; overlays.transform.SetParent(uma.transform); OverlayLibrary overlayLibrary = overlays.AddComponent <OverlayLibrary>(); //null search in all assets folder, t means type, so we are searching Uma.RaceData string[] overlaysData = AssetDatabase.FindAssets("t: OverlayDataAsset", null); foreach (string data in overlaysData) { //get the path string overlayPath = AssetDatabase.GUIDToAssetPath(data); OverlayDataAsset overlayAsset = AssetDatabase.LoadAssetAtPath <OverlayDataAsset>(overlayPath); overlayLibrary.AddOverlayAsset(overlayAsset); } // Context GameObject context = new GameObject(); context.name = "ContextLibrary"; context.transform.SetParent(uma.transform); UMAContext umaContext = context.AddComponent <UMAContext>(); umaContext.raceLibrary = raceLibrary; umaContext.slotLibrary = slotLibrary; umaContext.overlayLibrary = overlayLibrary; // Generators UMAGenerator generator = MonoBehaviour.Instantiate <UMAGenerator> (AssetDatabase.LoadAssetAtPath <UMAGenerator>(CommonNames.umaFolderGeneratorPrefabPath)); generator.name = "UMAGenerator"; generator.transform.SetParent(uma.transform); UMADefaultMeshCombiner meshCombiner = generator.gameObject.AddComponent <UMADefaultMeshCombiner>(); generator.meshCombiner = meshCombiner; //Mixers for random UMA creation //Male GameObject maleRecipeMixer = new GameObject(); maleRecipeMixer.name = "MaleRecipeMixer"; UMA.Examples.UMARecipeMixer maleRecipeMixerScript = maleRecipeMixer.AddComponent <UMA.Examples.UMARecipeMixer>(); maleRecipeMixerScript.raceData = raceLibrary.GetRace("HumanMale"); UMA.Examples.UMARecipeMixer.RecipeSection[] maleRecipeSection = new UMA.Examples.UMARecipeMixer.RecipeSection[3]; //Male Recipe Section : Body maleRecipeSection[0] = new UMA.Examples.UMARecipeMixer.RecipeSection(); maleRecipeSection[0].name = "Body"; maleRecipeSection[0].selectionRule = UMA.Examples.UMARecipeMixer.SelectionType.IncludeOne; maleRecipeSection[0].recipes = new UMARecipeBase[2]; string[] maleBodyRecipePath = AssetDatabase.FindAssets("MaleBase t: UMATextRecipe", null); maleRecipeSection[0].recipes[0] = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(maleBodyRecipePath[0])); string[] maleBody2RecipePath = AssetDatabase.FindAssets("MaleBase2 t: UMATextRecipe", null); maleRecipeSection[0].recipes[1] = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(maleBody2RecipePath[0])); //Male Recipe Section : Underwear maleRecipeSection[1] = new UMA.Examples.UMARecipeMixer.RecipeSection(); maleRecipeSection[1].name = "Clothing"; maleRecipeSection[1].selectionRule = UMA.Examples.UMARecipeMixer.SelectionType.IncludeOne; maleRecipeSection[1].recipes = new UMARecipeBase[1]; //string[] maleUnderwearRecipePath = AssetDatabase.FindAssets("MaleUnderwear t: UMATextRecipe", null); //maleRecipeSection[1].recipes[0] = AssetDatabase.LoadAssetAtPath<UMATextRecipe>(AssetDatabase.GUIDToAssetPath(maleUnderwearRecipePath[0])); string[] maleOutfit1RecipePath = AssetDatabase.FindAssets("MaleOutfit1 t: UMATextRecipe", null); foreach (string hairPath in maleOutfit1RecipePath) { UMATextRecipe umaTextRecipe = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(hairPath)); if (umaTextRecipe.name == "MaleOutfit1") { maleRecipeSection[1].recipes[0] = umaTextRecipe; } } //Male Recipe Section : Hair maleRecipeSection[2] = new UMA.Examples.UMARecipeMixer.RecipeSection(); maleRecipeSection[2].name = "Hair"; maleRecipeSection[2].selectionRule = UMA.Examples.UMARecipeMixer.SelectionType.IncludeSome; maleRecipeSection[2].recipes = new UMARecipeBase[2]; string[] maleBeardRecipePath = AssetDatabase.FindAssets("MaleBeard t: UMATextRecipe", null); foreach (string hairPath in maleBeardRecipePath) { UMATextRecipe umaTextRecipe = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(hairPath)); if (umaTextRecipe.name == "MaleBeard") { maleRecipeSection[2].recipes[0] = umaTextRecipe; } } string[] maleHairRecipePath = AssetDatabase.FindAssets("MaleHair t: UMATextRecipe", null); foreach (string hairPath in maleHairRecipePath) { UMATextRecipe umaTextRecipe = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(hairPath)); if (umaTextRecipe.name == "MaleHair") { maleRecipeSection[2].recipes[1] = umaTextRecipe; } } maleRecipeMixerScript.recipeSections = maleRecipeSection; maleRecipeMixer.GetComponent <Transform>().SetParent(uma.transform); //Female GameObject femaleRecipeMixer = new GameObject(); femaleRecipeMixer.name = "FemaleRecipeMixer"; UMA.Examples.UMARecipeMixer femaleRecipeMixerScript = femaleRecipeMixer.AddComponent <UMA.Examples.UMARecipeMixer>(); femaleRecipeMixerScript.raceData = raceLibrary.GetRace("HumanFemale"); UMA.Examples.UMARecipeMixer.RecipeSection[] femaleRecipeSection = new UMA.Examples.UMARecipeMixer.RecipeSection[3]; //Female Recipe Section : Body femaleRecipeSection[0] = new UMA.Examples.UMARecipeMixer.RecipeSection(); femaleRecipeSection[0].name = "Body"; femaleRecipeSection[0].selectionRule = UMA.Examples.UMARecipeMixer.SelectionType.IncludeOne; femaleRecipeSection[0].recipes = new UMARecipeBase[1]; string[] femaleBodyRecipePath = AssetDatabase.FindAssets("HumanFemale Base Recipe t: UMATextRecipe", null); femaleRecipeSection[0].recipes[0] = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(femaleBodyRecipePath[0])); //Female Recipe Section : Underwear femaleRecipeSection[1] = new UMA.Examples.UMARecipeMixer.RecipeSection(); femaleRecipeSection[1].name = "Clothing"; femaleRecipeSection[1].selectionRule = UMA.Examples.UMARecipeMixer.SelectionType.IncludeOne; femaleRecipeSection[1].recipes = new UMARecipeBase[2]; //string[] femaleUnderwearRecipePath = AssetDatabase.FindAssets("FemaleUnderwear t: UMATextRecipe", null); string[] femaleOutfit1RecipePath = AssetDatabase.FindAssets("FemaleOutfit1 t: UMATextRecipe", null); string[] femaleOutfit2RecipePath = AssetDatabase.FindAssets("FemaleOutfit2 t: UMATextRecipe", null); //femaleRecipeSection[1].recipes[0] = AssetDatabase.LoadAssetAtPath<UMATextRecipe>(AssetDatabase.GUIDToAssetPath(femaleUnderwearRecipePath[0])); femaleRecipeSection[1].recipes[0] = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(femaleOutfit1RecipePath[0])); femaleRecipeSection[1].recipes[1] = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(femaleOutfit2RecipePath[0])); //Female Recipe Section : Hair femaleRecipeSection[2] = new UMA.Examples.UMARecipeMixer.RecipeSection(); femaleRecipeSection[2].name = "Hair"; femaleRecipeSection[2].selectionRule = UMA.Examples.UMARecipeMixer.SelectionType.IncludeOne; femaleRecipeSection[2].recipes = new UMARecipeBase[3]; string[] femaleHairRecipePath = AssetDatabase.FindAssets("FemaleHair t: UMATextRecipe", null); string[] femaleHairLongRecipePath = AssetDatabase.FindAssets("FemaleHairLong t: UMATextRecipe", null); string[] femaleHairShortRecipePath = AssetDatabase.FindAssets("FemaleHairShort t: UMATextRecipe", null); foreach (string hairPath in femaleHairRecipePath) { UMATextRecipe umaTextRecipe = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(hairPath)); if (umaTextRecipe.name == "FemaleHair") { femaleRecipeSection[2].recipes[0] = umaTextRecipe; } } femaleRecipeSection[2].recipes[1] = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(femaleHairLongRecipePath[0])); femaleRecipeSection[2].recipes[2] = AssetDatabase.LoadAssetAtPath <UMATextRecipe>(AssetDatabase.GUIDToAssetPath(femaleHairShortRecipePath[0])); femaleRecipeMixerScript.recipeSections = femaleRecipeSection; femaleRecipeMixer.GetComponent <Transform>().SetParent(uma.transform); //Shared colors table GameObject recipeMixerController = new GameObject(); recipeMixerController.name = "RecipeMixerController"; RecipeMixerController recipeMixerControllerScript = recipeMixerController.AddComponent <RecipeMixerController>(); SharedColorTable[] sharedColorTable = recipeMixerControllerScript.sharedColors; string[][] sharedColorsPath = new string[5][]; sharedColorsPath[0] = AssetDatabase.FindAssets("HumanHairLinear", null); sharedColorsPath[1] = AssetDatabase.FindAssets("HumanSkinLinear", null); sharedColorsPath[2] = AssetDatabase.FindAssets("ClothingUnderwear", null); sharedColorsPath[3] = AssetDatabase.FindAssets("ClothingTops", null); sharedColorsPath[4] = AssetDatabase.FindAssets("ClothingBottoms", null); sharedColorTable[0] = AssetDatabase.LoadAssetAtPath <SharedColorTable>(AssetDatabase.GUIDToAssetPath(sharedColorsPath[0][0])); sharedColorTable[1] = AssetDatabase.LoadAssetAtPath <SharedColorTable>(AssetDatabase.GUIDToAssetPath(sharedColorsPath[1][0])); sharedColorTable[2] = AssetDatabase.LoadAssetAtPath <SharedColorTable>(AssetDatabase.GUIDToAssetPath(sharedColorsPath[2][0])); sharedColorTable[3] = AssetDatabase.LoadAssetAtPath <SharedColorTable>(AssetDatabase.GUIDToAssetPath(sharedColorsPath[3][0])); sharedColorTable[4] = AssetDatabase.LoadAssetAtPath <SharedColorTable>(AssetDatabase.GUIDToAssetPath(sharedColorsPath[4][0])); recipeMixerController.transform.SetParent(uma.transform); }
private void CreateRecipe(string path, SlotDataAsset sd, OverlayDataAsset od) { UMAEditorUtilities.CreateRecipe(path, sd, od, sd.name, addToGlobalLibrary); }
/// <summary> /// Updates an Existing SlotDataAsset. /// </summary> /// <param name="slot">The existing SlotDataAsset to be updated</param> /// <param name="mesh">Mesh.</param> /// <param name="material">Material.</param> /// <param name="prefabMesh">Prefab mesh.</param> /// <param name="rootBone">Root bone.</param> public static void UpdateSlotData(SlotDataAsset slot, SkinnedMeshRenderer mesh, UMAMaterial material, SkinnedMeshRenderer prefabMesh, string rootBone) { string path = UMAUtils.GetAssetFolder(AssetDatabase.GetAssetPath(slot)); string assetName = slot.slotName; if (path.Length <= 0) { Debug.LogWarning("CreateSlotData: Path to existing asset is empty!"); return; } GameObject tempGameObject = UnityEngine.Object.Instantiate(mesh.transform.parent.gameObject) as GameObject; var resultingSkinnedMeshes = tempGameObject.GetComponentsInChildren <SkinnedMeshRenderer>(); SkinnedMeshRenderer resultingSkinnedMesh = null; foreach (var skinnedMesh in resultingSkinnedMeshes) { if (skinnedMesh.name == mesh.name) { resultingSkinnedMesh = skinnedMesh; } } Mesh resultingMesh; if (prefabMesh != null) { resultingMesh = SeamRemoval.PerformSeamRemoval(resultingSkinnedMesh, prefabMesh, 0.0001f); resultingSkinnedMesh.sharedMesh = resultingMesh; SkinnedMeshAligner.AlignBindPose(prefabMesh, resultingSkinnedMesh); } else { resultingMesh = (Mesh)GameObject.Instantiate(resultingSkinnedMesh.sharedMesh); } //CountBoneweights(resultingMesh); var usedBonesDictionary = CompileUsedBonesDictionary(resultingMesh, new List <int>()); if (usedBonesDictionary.Count != resultingSkinnedMesh.bones.Length) { resultingMesh = BuildNewReduceBonesMesh(resultingMesh, usedBonesDictionary); } //CountBoneweights(resultingMesh); string meshAssetName = path + '/' + mesh.name + ".asset"; AssetDatabase.CreateAsset(resultingMesh, meshAssetName); tempGameObject.name = mesh.transform.parent.gameObject.name; Transform[] transformList = tempGameObject.GetComponentsInChildren <Transform>(); GameObject newObject = new GameObject(); for (int i = 0; i < transformList.Length; i++) { if (transformList[i].name == rootBone) { transformList[i].parent = newObject.transform; } else if (transformList[i].name == mesh.name) { transformList[i].parent = newObject.transform; } } GameObject.DestroyImmediate(tempGameObject); resultingSkinnedMesh = newObject.GetComponentInChildren <SkinnedMeshRenderer>(); if (resultingSkinnedMesh) { if (usedBonesDictionary.Count != resultingSkinnedMesh.bones.Length) { resultingSkinnedMesh.bones = BuildNewReducedBonesList(resultingSkinnedMesh.bones, usedBonesDictionary); } resultingSkinnedMesh.sharedMesh = resultingMesh; //CountBoneweights(resultingMesh); } string SkinnedName = path + '/' + assetName + "_Skinned.prefab"; #if UNITY_2018_3_OR_NEWER var skinnedResult = PrefabUtility.SaveAsPrefabAsset(newObject, SkinnedName); #else var skinnedResult = UnityEditor.PrefabUtility.CreatePrefab(SkinnedName, newObject); #endif GameObject.DestroyImmediate(newObject); var meshgo = skinnedResult.transform.Find(mesh.name); var finalMeshRenderer = meshgo.GetComponent <SkinnedMeshRenderer>(); slot.UpdateMeshData(finalMeshRenderer, rootBone); slot.meshData.SlotName = slot.slotName; var cloth = mesh.GetComponent <Cloth>(); if (cloth != null) { slot.meshData.RetrieveDataFromUnityCloth(cloth); } AssetDatabase.SaveAssets(); AssetDatabase.DeleteAsset(SkinnedName); AssetDatabase.DeleteAsset(meshAssetName); }
private void AddSlotDataAsset(SlotDataAsset added) { var slot = new SlotData(added); _recipe.MergeSlot(slot, false); }
/// <summary> /// Removes a list of downloadingAssetItems from the downloadingItems List. /// </summary> /// <param name="itemsToRemove"></param> public IEnumerator RemoveDownload(List <DownloadingAssetItem> itemsToRemove) { //Not used any more UMAs check the status of stuff they asked for themselves //Dictionary<UMAAvatarBase, List<string>> updatedUMAs = new Dictionary<UMAAvatarBase, List<string>>(); foreach (DownloadingAssetItem item in itemsToRemove) { item.isBeingRemoved = true; } foreach (DownloadingAssetItem item in itemsToRemove) { string error = ""; //we need to check everyitem in this batch belongs to an asset bundle that has actually been loaded LoadedAssetBundle loadedBundleTest = AssetBundleManager.GetLoadedAssetBundle(item.containingBundle, out error); AssetBundle loadedBundleABTest = loadedBundleTest.m_AssetBundle; if (loadedBundleABTest == null && (String.IsNullOrEmpty(error))) { while (loadedBundleTest.m_AssetBundle == null) { //could say we are unpacking here yield return(null); } } if (!String.IsNullOrEmpty(error)) { if (Debug.isDebugBuild) { Debug.LogError(error); } yield break; } } //Now every item in the batch should be in a loaded bundle that is ready to use. foreach (DownloadingAssetItem item in itemsToRemove) { if (item != null) { string error = ""; var loadedBundle = AssetBundleManager.GetLoadedAssetBundle(item.containingBundle, out error); var loadedBundleAB = loadedBundle.m_AssetBundle; if (!String.IsNullOrEmpty(error)) { if (Debug.isDebugBuild) { Debug.LogError(error); } yield break; } var assetType = item.tempAsset.GetType(); //deal with RuntimeAnimatorController funkiness //the actual type of an instantiated clone of a RuntimeAnimatorController in the editor is UnityEditor.Animations.AnimatorController if (assetType.ToString().IndexOf("AnimatorController") > -1) { assetType = typeof(RuntimeAnimatorController); } var itemFilename = AssetBundleManager.AssetBundleIndexObject.GetFilenameFromAssetName(item.containingBundle, item.requiredAssetName, assetType.ToString()); if (assetType == typeof(RaceData)) { RaceData actualRace = loadedBundleAB.LoadAsset <RaceData>(itemFilename); UMAContextBase.Instance.AddRace(actualRace); } else if (assetType == typeof(SlotDataAsset)) { SlotDataAsset thisSlot = null; thisSlot = loadedBundleAB.LoadAsset <SlotDataAsset>(itemFilename); if (thisSlot != null) { UMAContextBase.Instance.AddSlotAsset(thisSlot); } else { if (Debug.isDebugBuild) { Debug.LogWarning("[DynamicAssetLoader] could not add downloaded slot" + item.requiredAssetName); } } } else if (assetType == typeof(OverlayDataAsset)) { OverlayDataAsset thisOverlay = null; thisOverlay = loadedBundleAB.LoadAsset <OverlayDataAsset>(itemFilename); if (thisOverlay != null) { UMAContextBase.Instance.AddOverlayAsset(thisOverlay); } else { if (Debug.isDebugBuild) { Debug.LogWarning("[DynamicAssetLoader] could not add downloaded overlay" + item.requiredAssetName + " from assetbundle " + item.containingBundle); } } } else if (assetType == typeof(UMATextRecipe)) { UMATextRecipe downloadedRecipe = loadedBundleAB.LoadAsset <UMATextRecipe>(itemFilename); UMAContextBase.Instance.AddRecipe(downloadedRecipe); } else if (assetType == typeof(UMAWardrobeRecipe)) { UMAWardrobeRecipe downloadedRecipe = loadedBundleAB.LoadAsset <UMAWardrobeRecipe>(itemFilename); UMAContextBase.Instance.AddRecipe(downloadedRecipe); } else if (item.dynamicCallback.Count > 0) { //get the asset as whatever the type of the tempAsset is //send this as an array to the dynamicCallback var downloadedAsset = loadedBundleAB.LoadAsset(itemFilename, assetType); var downloadedAssetArray = Array.CreateInstance(assetType, 1); downloadedAssetArray.SetValue(downloadedAsset, 0); for (int i = 0; i < item.dynamicCallback.Count; i++) { item.dynamicCallback[i].DynamicInvoke(downloadedAssetArray); } } if (!String.IsNullOrEmpty(error)) { if (Debug.isDebugBuild) { Debug.LogError(error); } } } downloadingItems.Remove(item); } if (downloadingItems.Count == 0) { areDownloadedItemsReady = true; //AssetBundleManager.UnloadAllAssetBundles();//we cant do this yet } //yield break; }
private void SetSlotDataAsset(int index, SlotDataAsset slotElement) { m_Object.FindProperty(string.Format(kArrayData, index)).objectReferenceValue = slotElement; isDirty = true; }