public override void OnInspectorGUI() { Sliceable s = (Sliceable) target; Renderer[] renderers = s.GetComponentsInChildren<Renderer>(true); bool isAnimated = false; foreach(Renderer r in renderers) isAnimated |= r is SkinnedMeshRenderer; //TurboSlice.supportsSkinned is a const that is overridden by the presence of Ragdoll Slicer #pragma warning disable 0162 if(isAnimated && !TurboSlice.supportsSkinned) { EditorGUILayout.LabelField("Error!"); EditorGUILayout.LabelField("Skinned meshes are not supported."); return; } s.refreshColliders = EditorGUILayout.Toggle("Refresh colliders", s.refreshColliders); s.alternatePrefab = EditorGUILayout.ObjectField("Alternate prefab", (Object) s.alternatePrefab, typeof(GameObject), false); if(s.alternatePrefab != null) { s.alwaysCloneFromAlternate = EditorGUILayout.Toggle("Always clone from alternate", s.alwaysCloneFromAlternate); } s.currentlySliceable = EditorGUILayout.Toggle("Currently Sliceable", s.currentlySliceable); s.category = EditorGUILayout.TextField("Category", s.category); s.channelNormals = EditorGUILayout.Toggle("Process Normals", s.channelNormals); s.channelTangents = EditorGUILayout.Toggle("Process Tangents", s.channelTangents); s.channelUV2 = EditorGUILayout.Toggle("Process UV2", s.channelUV2); Renderer renderer = null; if(renderers.Length == 0) { EditorGUILayout.LabelField("No mesh renderers found in this object!"); } else if(renderers.Length > 1) { EditorGUILayout.LabelField("This object has multiple meshes. Specify the primary."); int selectedRenderer = 0; if(s.explicitlySelectedMeshHolder != null) { Renderer r = s.explicitlySelectedMeshHolder.GetComponent<Renderer>(); if(r != null) { selectedRenderer = System.Array.IndexOf<Renderer>(renderers, r); } } string[] displayedOptions = new string[renderers.Length]; for(int i = 0; i < displayedOptions.Length; i++) { displayedOptions[i] = renderers[i].name; } selectedRenderer = EditorGUILayout.Popup("Slice Mesh", selectedRenderer, displayedOptions); renderer = renderers[selectedRenderer]; s.explicitlySelectedMeshHolder = renderer.gameObject; } else if(renderers.Length == 1) { renderer = renderers[0]; s.explicitlySelectedMeshHolder = renderer.gameObject; } if(renderer != null) { List<TurboSlice.InfillConfiguration> newInfillers = new List<TurboSlice.InfillConfiguration>(); Material[] mats = renderer.sharedMaterials; if(mats.Length > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } foreach(Material mat in mats) { //Is this material represented in our array? EditorGUILayout.Separator(); if(s.infillers == null) s.infillers = new TurboSlice.InfillConfiguration[0]; TurboSlice.InfillConfiguration infiller = null; foreach(TurboSlice.InfillConfiguration ifc in s.infillers) { if(ifc.material == mat) { infiller = ifc; break; } } EditorGUILayout.LabelField("Material: " + mat.name); bool hasIt = EditorGUILayout.Toggle("Infill this material", infiller != null); if(hasIt && infiller == null) { infiller = new TurboSlice.InfillConfiguration(); infiller.material = mat; } else if(!hasIt) { infiller = null; } if(infiller != null) { newInfillers.Add(infiller); infiller.regionForInfill = EditorGUILayout.RectField(infiller.regionForInfill); } } s.infillers = newInfillers.ToArray(); } if (GUI.changed) { EditorUtility.SetDirty (target); } }
public override void OnInspectorGUI() { bool someTargetsAreUnvetted = false; bool someTargetsHaveMultipleRenderers = false; List <Renderer> relevantRenderers = new List <Renderer>(); List <Renderer> allRenderers = new List <Renderer>(); foreach (Object o in targets) { Sliceable s = (Sliceable)o; Component[] _allRenderersOnThisTarget = s.GetComponentsInChildren(typeof(Renderer), true); Renderer[] allRenderersOnThisTarget = new Renderer[_allRenderersOnThisTarget.Length]; for (int i = 0; i < _allRenderersOnThisTarget.Length; i++) { allRenderersOnThisTarget[i] = _allRenderersOnThisTarget[i] as Renderer; } allRenderers.AddRange(allRenderersOnThisTarget); if (allRenderersOnThisTarget.Length == 1) { relevantRenderers.Add(allRenderersOnThisTarget[0]); } else if (s.explicitlySelectedMeshHolder != null) { relevantRenderers.Add(s.meshHolder.GetComponent(typeof(Renderer)) as Renderer); } else { someTargetsAreUnvetted = true; } someTargetsHaveMultipleRenderers |= allRenderersOnThisTarget.Length > 1; } EditorGUILayout.PropertyField(refreshCollidersProperty, new GUIContent("Refresh colliders")); EditorGUILayout.PropertyField(alternatePrefabProperty, new GUIContent("Alternate prefab")); bool atLeastSomeHaveAlternatePrefab = alternatePrefabProperty.hasMultipleDifferentValues || alternatePrefabProperty.objectReferenceValue != null; if (atLeastSomeHaveAlternatePrefab) { EditorGUILayout.PropertyField(alwaysCloneFromAlternateProperty, new GUIContent("Always clone from alternate")); } EditorGUILayout.PropertyField(channelNormalsProperty, new GUIContent("Process Normals")); EditorGUILayout.PropertyField(channelTangentsProperty, new GUIContent("Process Tangents")); EditorGUILayout.PropertyField(channelUV2Property, new GUIContent("Process UV2")); EditorGUILayout.Separator(); //Ensure that all the targets are vetted and if they're not, we can only vet them one at a time //through the unity inspector. if (relevantRenderers.Count == 0) { EditorGUILayout.LabelField("No mesh renderers found!"); } else if (someTargetsAreUnvetted && (targets.Length > 1)) { EditorGUILayout.LabelField("Cannot multi-edit: Some objects have multiple"); EditorGUILayout.LabelField("meshes. Please vet them individually."); } else if (someTargetsHaveMultipleRenderers && (targets.Length == 1)) { EditorGUILayout.LabelField("This object has multiple meshes. Specify the primary."); int selectedRenderer = 0; GameObject explicitlySelectedMeshHolder = explicitlySelectedMeshHolderProperty.objectReferenceValue as GameObject; if (explicitlySelectedMeshHolder != null) { Renderer r = explicitlySelectedMeshHolder.GetComponent <Renderer>(); if (r != null) { selectedRenderer = allRenderers.IndexOf(r); } } string[] displayedOptions = new string[allRenderers.Count]; for (int i = 0; i < displayedOptions.Length; i++) { displayedOptions[i] = allRenderers[i].name; } selectedRenderer = EditorGUILayout.Popup("Slice Mesh", selectedRenderer, displayedOptions); Renderer renderer = allRenderers[selectedRenderer]; explicitlySelectedMeshHolderProperty.objectReferenceValue = renderer.gameObject; } serializedObject.ApplyModifiedProperties(); //Assuming we're all legit, let's multi-edit the infillers. if (!someTargetsAreUnvetted) { List <Material> mats = new List <Material>(); foreach (Renderer r in relevantRenderers) { Material[] _mats = r.sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } } if (mats.Count > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } } if (!someTargetsAreUnvetted) { List <Material> mats = new List <Material>(); List <TurboSlice.InfillConfiguration> preexistingInfillers = new List <TurboSlice.InfillConfiguration>(); foreach (Object o in targets) { Sliceable s = o as Sliceable; Material[] _mats = s.meshHolder.GetComponent <Renderer>().sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } preexistingInfillers.AddRange(s.infillers); } TurboSlice.InfillConfiguration[] infillers = new TurboSlice.InfillConfiguration[mats.Count]; for (int i = 0; i < mats.Count; i++) { Material mat = mats[i]; TurboSlice.InfillConfiguration infiller = null; foreach (TurboSlice.InfillConfiguration _infiller in preexistingInfillers) { if (_infiller.material == mat) { infiller = _infiller; break; } } if (infiller == null) { infiller = new TurboSlice.InfillConfiguration(); infiller.material = mat; infiller.regionForInfill = new Rect(0f, 0f, 1f, 1f); } infillers[i] = infiller; } foreach (TurboSlice.InfillConfiguration infiller in infillers) { EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material: " + infiller.material.name); infiller.regionForInfill = EditorGUILayout.RectField("Region for infill", infiller.regionForInfill); } if (GUI.changed) { foreach (Object o in targets) { Sliceable s = o as Sliceable; s.infillers = new TurboSlice.InfillConfiguration[infillers.Length]; System.Array.Copy(infillers, s.infillers, infillers.Length); EditorUtility.SetDirty(o); } } } /*if(!someTargetsAreUnvetted) * { * List<Material> mats = new List<Material>(); * * foreach(Renderer r in relevantRenderers) * { * Material[] _mats = r.sharedMaterials; * foreach(Material mat in _mats) * { * if(mats.Contains(mat) == false) mats.Add(mat); * } * } * * if(mats.Count > 0) * { * EditorGUILayout.LabelField("For each material, define what region is used for infill."); * } * * foreach(Material mat in mats) * { * //Is this material represented in our array? * * EditorGUILayout.Separator(); * * SerializedProperty infiller = null; * * for(int i = 0; i < infillersProperty.arraySize; i++) * { * SerializedProperty _infiller = infillersProperty.GetArrayElementAtIndex(i); * _infiller. * SerializedProperty _mat = _infiller.FindPropertyRelative("material"); * if(_mat != null) * { * Material thisMat = _mat.objectReferenceValue as Material; * if(thisMat == mat) * { * infiller = _infiller; * } * } * } * * if(infiller == null) * { * infillersProperty.InsertArrayElementAtIndex(0); * infiller = infillersProperty.GetArrayElementAtIndex(0); * * SerializedProperty _mat = infiller.FindPropertyRelative("material"); * _mat.objectReferenceValue = mat; * } * * EditorGUILayout.LabelField("Material: " + mat.name); * * SerializedProperty regionForInfillProperty = infiller.FindPropertyRelative("regionForInfill"); * * EditorGUILayout.PropertyField(regionForInfillProperty, new GUIContent("Region for infill")); * } * * { * List<Material> observedMats = new List<Material>(); * * for(int i = 0; i < infillersProperty.arraySize; i++) * { * SerializedProperty _infiller = infillersProperty.GetArrayElementAtIndex(i); * SerializedProperty _mat = _infiller.FindPropertyRelative("material"); * Material mat = _mat.objectReferenceValue as Material; * bool delete = mat == null || observedMats.Contains(mat); * if(delete) infillersProperty.DeleteArrayElementAtIndex(i--); * else observedMats.Add(mat); * } * } * }*/ }
public override void OnInspectorGUI() { bool someTargetsAreUnvetted = false; bool someTargetsHaveMultipleRenderers = false; List<Renderer> relevantRenderers = new List<Renderer>(); List<Renderer> allRenderers = new List<Renderer>(); foreach(Object o in targets) { Sliceable s = (Sliceable) o; Component[] _allRenderersOnThisTarget = s.GetComponentsInChildren(typeof(Renderer), true); Renderer[] allRenderersOnThisTarget = new Renderer[_allRenderersOnThisTarget.Length]; for(int i = 0; i < _allRenderersOnThisTarget.Length; i++) allRenderersOnThisTarget[i] = _allRenderersOnThisTarget[i] as Renderer; allRenderers.AddRange( allRenderersOnThisTarget ); if(allRenderersOnThisTarget.Length == 1) { relevantRenderers.Add( allRenderersOnThisTarget[0] ); } else if(s.explicitlySelectedMeshHolder != null) { relevantRenderers.Add( s.meshHolder.GetComponent(typeof(Renderer)) as Renderer); } else { someTargetsAreUnvetted = true; } someTargetsHaveMultipleRenderers |= allRenderersOnThisTarget.Length > 1; } EditorGUILayout.PropertyField(refreshCollidersProperty, new GUIContent("Refresh colliders")); EditorGUILayout.PropertyField(alternatePrefabProperty, new GUIContent("Alternate prefab")); bool atLeastSomeHaveAlternatePrefab = alternatePrefabProperty.hasMultipleDifferentValues || alternatePrefabProperty.objectReferenceValue != null; if(atLeastSomeHaveAlternatePrefab) EditorGUILayout.PropertyField(alwaysCloneFromAlternateProperty, new GUIContent("Always clone from alternate")); EditorGUILayout.PropertyField(channelNormalsProperty, new GUIContent("Process Normals")); EditorGUILayout.PropertyField(channelTangentsProperty, new GUIContent("Process Tangents")); EditorGUILayout.PropertyField(channelUV2Property, new GUIContent("Process UV2")); EditorGUILayout.PropertyField(shatterProperty, new GUIContent("Process shatter")); EditorGUILayout.Separator(); //Ensure that all the targets are vetted and if they're not, we can only vet them one at a time //through the unity inspector. if(relevantRenderers.Count == 0) { EditorGUILayout.LabelField("No mesh renderers found!"); } else if(someTargetsAreUnvetted && (targets.Length > 1)) { EditorGUILayout.LabelField("Cannot multi-edit: Some objects have multiple"); EditorGUILayout.LabelField("meshes. Please vet them individually."); } else if(someTargetsHaveMultipleRenderers && (targets.Length == 1)) { EditorGUILayout.LabelField("This object has multiple meshes. Specify the primary."); int selectedRenderer = 0; GameObject explicitlySelectedMeshHolder = explicitlySelectedMeshHolderProperty.objectReferenceValue as GameObject; if(explicitlySelectedMeshHolder != null) { Renderer r = explicitlySelectedMeshHolder.GetComponent<Renderer>(); if(r != null) { selectedRenderer = allRenderers.IndexOf(r); } } string[] displayedOptions = new string[allRenderers.Count]; for(int i = 0; i < displayedOptions.Length; i++) { displayedOptions[i] = allRenderers[i].name; } selectedRenderer = EditorGUILayout.Popup("Slice Mesh", selectedRenderer, displayedOptions); Renderer renderer = allRenderers[selectedRenderer]; explicitlySelectedMeshHolderProperty.objectReferenceValue = renderer.gameObject; } serializedObject.ApplyModifiedProperties(); //Assuming we're all legit, let's multi-edit the infillers. if(!someTargetsAreUnvetted) { List<Material> mats = new List<Material>(); foreach(Renderer r in relevantRenderers) { Material[] _mats = r.sharedMaterials; foreach(Material mat in _mats) { if(mats.Contains(mat) == false) mats.Add(mat); } } if(mats.Count > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } } if(!someTargetsAreUnvetted) { List<Material> mats = new List<Material>(); List<TurboSlice.InfillConfiguration> preexistingInfillers = new List<TurboSlice.InfillConfiguration>(); foreach(Object o in targets) { Sliceable s = o as Sliceable; Material[] _mats = s.meshHolder.GetComponent<Renderer>().sharedMaterials; foreach(Material mat in _mats) { if(mats.Contains(mat) == false) { mats.Add(mat); } } preexistingInfillers.AddRange(s.infillers); } TurboSlice.InfillConfiguration[] infillers = new TurboSlice.InfillConfiguration[ mats.Count ]; for(int i = 0; i < mats.Count; i++) { Material mat = mats[i]; TurboSlice.InfillConfiguration infiller = null; foreach(TurboSlice.InfillConfiguration _infiller in preexistingInfillers) { if(_infiller.material == mat) { infiller = _infiller; break; } } if(infiller == null) { infiller = new TurboSlice.InfillConfiguration(); infiller.material = mat; infiller.regionForInfill = new Rect(0f, 0f, 1f, 1f); } infillers[i] = infiller; } foreach(TurboSlice.InfillConfiguration infiller in infillers) { EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material: " + infiller.material.name); infiller.regionForInfill = EditorGUILayout.RectField("Region for infill", infiller.regionForInfill); } if(GUI.changed) { foreach(Object o in targets) { Sliceable s = o as Sliceable; s.infillers = new TurboSlice.InfillConfiguration[ infillers.Length ]; System.Array.Copy(infillers, s.infillers, infillers.Length); EditorUtility.SetDirty(o); } } } /*if(!someTargetsAreUnvetted) { List<Material> mats = new List<Material>(); foreach(Renderer r in relevantRenderers) { Material[] _mats = r.sharedMaterials; foreach(Material mat in _mats) { if(mats.Contains(mat) == false) mats.Add(mat); } } if(mats.Count > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } foreach(Material mat in mats) { //Is this material represented in our array? EditorGUILayout.Separator(); SerializedProperty infiller = null; for(int i = 0; i < infillersProperty.arraySize; i++) { SerializedProperty _infiller = infillersProperty.GetArrayElementAtIndex(i); _infiller. SerializedProperty _mat = _infiller.FindPropertyRelative("material"); if(_mat != null) { Material thisMat = _mat.objectReferenceValue as Material; if(thisMat == mat) { infiller = _infiller; } } } if(infiller == null) { infillersProperty.InsertArrayElementAtIndex(0); infiller = infillersProperty.GetArrayElementAtIndex(0); SerializedProperty _mat = infiller.FindPropertyRelative("material"); _mat.objectReferenceValue = mat; } EditorGUILayout.LabelField("Material: " + mat.name); SerializedProperty regionForInfillProperty = infiller.FindPropertyRelative("regionForInfill"); EditorGUILayout.PropertyField(regionForInfillProperty, new GUIContent("Region for infill")); } { List<Material> observedMats = new List<Material>(); for(int i = 0; i < infillersProperty.arraySize; i++) { SerializedProperty _infiller = infillersProperty.GetArrayElementAtIndex(i); SerializedProperty _mat = _infiller.FindPropertyRelative("material"); Material mat = _mat.objectReferenceValue as Material; bool delete = mat == null || observedMats.Contains(mat); if(delete) infillersProperty.DeleteArrayElementAtIndex(i--); else observedMats.Add(mat); } } }*/ }
public override void OnInspectorGUI() { Sliceable s = (Sliceable)target; Renderer[] renderers = s.GetComponentsInChildren <Renderer>(true); bool isAnimated = false; foreach (Renderer r in renderers) { isAnimated |= r is SkinnedMeshRenderer; } //TurboSlice.supportsSkinned is a const that is overridden by the presence of Ragdoll Slicer #pragma warning disable 0162 if (isAnimated && !TurboSlice.supportsSkinned) { EditorGUILayout.LabelField("Error!"); EditorGUILayout.LabelField("Skinned meshes are not supported."); return; } s.refreshColliders = EditorGUILayout.Toggle("Refresh colliders", s.refreshColliders); s.alternatePrefab = EditorGUILayout.ObjectField("Alternate prefab", (Object)s.alternatePrefab, typeof(GameObject), false); if (s.alternatePrefab != null) { s.alwaysCloneFromAlternate = EditorGUILayout.Toggle("Always clone from alternate", s.alwaysCloneFromAlternate); } s.currentlySliceable = EditorGUILayout.Toggle("Currently Sliceable", s.currentlySliceable); s.category = EditorGUILayout.TextField("Category", s.category); s.channelNormals = EditorGUILayout.Toggle("Process Normals", s.channelNormals); s.channelTangents = EditorGUILayout.Toggle("Process Tangents", s.channelTangents); s.channelUV2 = EditorGUILayout.Toggle("Process UV2", s.channelUV2); Renderer renderer = null; if (renderers.Length == 0) { EditorGUILayout.LabelField("No mesh renderers found in this object!"); } else if (renderers.Length > 1) { EditorGUILayout.LabelField("This object has multiple meshes. Specify the primary."); int selectedRenderer = 0; if (s.explicitlySelectedMeshHolder != null) { Renderer r = s.explicitlySelectedMeshHolder.GetComponent <Renderer>(); if (r != null) { selectedRenderer = System.Array.IndexOf <Renderer>(renderers, r); } } string[] displayedOptions = new string[renderers.Length]; for (int i = 0; i < displayedOptions.Length; i++) { displayedOptions[i] = renderers[i].name; } selectedRenderer = EditorGUILayout.Popup("Slice Mesh", selectedRenderer, displayedOptions); renderer = renderers[selectedRenderer]; s.explicitlySelectedMeshHolder = renderer.gameObject; } else if (renderers.Length == 1) { renderer = renderers[0]; s.explicitlySelectedMeshHolder = renderer.gameObject; } if (renderer != null) { List <TurboSlice.InfillConfiguration> newInfillers = new List <TurboSlice.InfillConfiguration>(); Material[] mats = renderer.sharedMaterials; if (mats.Length > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } foreach (Material mat in mats) { //Is this material represented in our array? EditorGUILayout.Separator(); if (s.infillers == null) { s.infillers = new TurboSlice.InfillConfiguration[0]; } TurboSlice.InfillConfiguration infiller = null; foreach (TurboSlice.InfillConfiguration ifc in s.infillers) { if (ifc.material == mat) { infiller = ifc; break; } } EditorGUILayout.LabelField("Material: " + mat.name); bool hasIt = EditorGUILayout.Toggle("Infill this material", infiller != null); if (hasIt && infiller == null) { infiller = new TurboSlice.InfillConfiguration(); infiller.material = mat; } else if (!hasIt) { infiller = null; } if (infiller != null) { newInfillers.Add(infiller); infiller.regionForInfill = EditorGUILayout.RectField(infiller.regionForInfill); } } s.infillers = newInfillers.ToArray(); } if (GUI.changed) { EditorUtility.SetDirty(target); } }