private static GameObject getMeshHolder(Sliceable s) { if(s.explicitlySelectedMeshHolder != null) { return s.explicitlySelectedMeshHolder; } else { MeshFilter[] allFilters = s.GetComponentsInChildren<MeshFilter>(true); if(allFilters.Length > 0) { return allFilters[0].gameObject; } else { return null; } } }
private static GameObject getMeshHolder(Sliceable s) { if (s.explicitlySelectedMeshHolder != null) { return(s.explicitlySelectedMeshHolder); } else { MeshFilter[] allFilters = s.GetComponentsInChildren <MeshFilter>(true); if (allFilters.Length > 0) { return(allFilters[0].gameObject); } else { return(null); } } }
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.explicitlySelectedMeshHolder.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")); EditorGUILayout.PropertyField(shreddableProperty, new GUIContent("Shreddable")); 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) { var mats = new List <Material>(); var preexistingInfillers = new List <InfillConfiguration>(); foreach (Object o in targets) { Sliceable s = o as Sliceable; Renderer renderer; if (s.explicitlySelectedMeshHolder != null) { renderer = s.explicitlySelectedMeshHolder.GetComponent <Renderer>(); } else { renderer = s.gameObject.GetComponent <Renderer>(); } if (renderer != null) { Material[] _mats = renderer.sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } } preexistingInfillers.AddRange(s.infillers); } InfillConfiguration[] infillers = new InfillConfiguration[mats.Count]; var forceDirty = false; for (int i = 0; i < mats.Count; i++) { Material mat = mats[i]; InfillConfiguration infiller = null; foreach (var _infiller in preexistingInfillers) { if (_infiller.material == mat) { infiller = _infiller; break; } } //If there is no infiller, than the UI will create one. However, the GUI will not be seen as changed, and //therefore if we do not set some flag, than the code lower down will not recognize that it ought to //set the item as 'dirty'. if (infiller == null) { infiller = new InfillConfiguration(); infiller.material = mat; infiller.regionForInfill = new Rect(0f, 0f, 1f, 1f); forceDirty = true; } infillers[i] = infiller; } foreach (var infiller in infillers) { EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material: " + infiller.material.name); infiller.regionForInfill = EditorGUILayout.RectField("Region for infill", infiller.regionForInfill); } if (GUI.changed || forceDirty) { foreach (Object o in targets) { Sliceable s = o as Sliceable; s.infillers = new InfillConfiguration[infillers.Length]; System.Array.Copy(infillers, s.infillers, infillers.Length); EditorUtility.SetDirty(o); } } } }
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() { 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 someTargetsHaveMultipleRenderers = false; var 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); someTargetsHaveMultipleRenderers |= allRenderersOnThisTarget.Length > 1; } EditorGUILayout.PropertyField(refreshCollidersProperty, new GUIContent("Refresh colliders")); EditorGUILayout.PropertyField(alternatePrefabProperty, new GUIContent("Alternate prefab")); EditorGUILayout.PropertyField(shreddableProperty, new GUIContent("Shreddable")); 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 (allRenderers.Count == 0) { EditorGUILayout.LabelField("No mesh renderers found!"); } serializedObject.ApplyModifiedProperties(); //Assuming we're all legit, let's multi-edit the infillers. var mats = new HashSet <Material>(); foreach (var r in allRenderers) { Material[] _mats = r.sharedMaterials; foreach (Material mat in _mats) { mats.Add(mat); } } if (mats.Count > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } var preexistingInfillers = new List <InfillConfiguration>(); foreach (Object o in targets) { Sliceable s = o as Sliceable; Renderer renderer; renderer = s.gameObject.GetComponent <Renderer>(); if (renderer != null) { Material[] _mats = renderer.sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } } preexistingInfillers.AddRange(s.infillers); } var infillersBuilder = new List <InfillConfiguration>(); var forceDirty = false; foreach (var mat in mats) { InfillConfiguration infiller = null; foreach (var _infiller in preexistingInfillers) { if (_infiller.material == mat) { infiller = _infiller; break; } } //If there is no infiller, than the UI will create one. However, the GUI will not be seen as changed, and //therefore if we do not set some flag, than the code lower down will not recognize that it ought to //set the item as 'dirty'. if (infiller == null) { infiller = new InfillConfiguration(); infiller.material = mat; infiller.regionForInfill = new Rect(0f, 0f, 1f, 1f); forceDirty = true; } infillersBuilder.Add(infiller); } foreach (var infiller in infillersBuilder) { EditorGUILayout.Separator(); var material = infiller.material; var materialName = material == null ? "Null" : material.name; EditorGUILayout.LabelField("Material: " + materialName); infiller.regionForInfill = EditorGUILayout.RectField("Region for infill", infiller.regionForInfill); } if (GUI.changed || forceDirty) { var infillersArray = infillersBuilder.ToArray(); foreach (Object o in targets) { Sliceable s = o as Sliceable; s.infillers = infillersArray; EditorUtility.SetDirty(o); } } }