public void DrawPointMasses(JelloBody body, bool editable) { Handles.color = new Color(0.75f, 0.75f, 0.2f, 0.5f); for(int i = 0; i < body.Shape.EdgeVertexCount; i++) { Vector2 pos = body.transform.TransformPoint (body.Shape.EdgeVertices[i]); if(editable) { int hot = GUIUtility.hotControl; Handles.FreeMoveHandle(pos, Quaternion.identity, HandleUtility.GetHandleSize(pos) * 0.075f, Vector3.zero, Handles.DotCap); if(GUIUtility.hotControl != hot) { if(currentSubEditor == 1)//point mass editor! { subEditors[currentSubEditor].SetEditIndex(i); Repaint(); } } } else { Handles.color = new Color(0.5f, 0.5f, 0.5f, 0.5f); Handles.DotCap(3, pos, Quaternion.identity, HandleUtility.GetHandleSize(pos) * 0.075f); } } for(int i = 0; i < body.Shape.InternalVertexCount; i++) { Handles.color = new Color(0.75f, 0f, 0.75f, 0.5f); Vector2 pos = body.transform.TransformPoint (body.Shape.InternalVertices[i]); if(editable) { int hot = GUIUtility.hotControl; EditorGUI.BeginChangeCheck(); pos = Handles.FreeMoveHandle(pos, Quaternion.identity, HandleUtility.GetHandleSize(pos) * 0.075f, Vector3.zero, Handles.DotCap); if(EditorGUI.EndChangeCheck()) { if(!JelloShapeTools.Contains(body.Shape.EdgeVertices, body.transform.InverseTransformPoint(pos)) || JelloShapeTools.PointOnPerimeter(body.Shape.EdgeVertices, body.transform.InverseTransformPoint(pos))) { JelloClosedShape newShape = new JelloClosedShape(body.Shape.EdgeVertices, null, false); for(int a = 0; a < body.Shape.InternalVertexCount; a++) { //dont add this point if(a == i) continue; newShape.addInternalVertex(body.Shape.InternalVertices[a]); } newShape.finish(false); body.smartSetShape(newShape, JelloBody.ShapeSettingOptions.MovePointMasses, smartShapeSettingOptions); EditorUtility.SetDirty(body); GUIUtility.hotControl = 0; subEditors[currentSubEditor].SetEditIndex(-1); Repaint(); break; } body.Shape.changeInternalVertexPosition(i, body.transform.InverseTransformPoint(pos)); body.Shape.finish(false); EditorUtility.SetDirty(body); } if(GUIUtility.hotControl != hot && GUIUtility.hotControl != 0) { if(currentSubEditor == 1)//point mass editor! { subEditors[currentSubEditor].SetEditIndex(i + body.EdgePointMassCount); Repaint(); } } } else { Handles.color = new Color(0.5f, 0.5f, 0.5f, 0.5f); Handles.DotCap(3, pos, Quaternion.identity, HandleUtility.GetHandleSize(pos) * 0.075f); } } }
//todo add onenable and ondisable events to body. public virtual void DrawEditorGUI() { //check polycollider vs pointmasscount if(!Application.isPlaying) //TODO have this be handled by a class that extends the polycollider and recognises changes? { for(int b = 0; b < targets.Length; b++) { JelloBody body = (JelloBody)targets[b]; body.setComponentReferences(); body.polyCollider.points = JelloShapeTools.RemoveDuplicatePoints(body.polyCollider.points); JelloClosedShape shape = new JelloClosedShape(body.polyCollider.points, null, false); if(body.Shape != null) { for(int i = 0; i < body.Shape.InternalVertexCount; i++) shape.addInternalVertex(body.Shape.InternalVertices[i]); shape.finish(false); } if(shape.EdgeVertexCount != body.Shape.EdgeVertexCount || shape.InternalVertexCount != body.Shape.InternalVertexCount) body.smartSetShape(shape, JelloBody.ShapeSettingOptions.MovePointMasses, smartShapeSettingOptions); else body.setShape(shape, JelloBody.ShapeSettingOptions.MovePointMasses); //will i need to do this for constraints as well? for(int i = 0; i < body.AttachPointCount; i++) { body.GetAttachPoint(i).UpdateEditorMode(); } } } serializedObject.Update(); EditorGUI.showMixedValue = eMass.hasMultipleDifferentValues; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(eMass, massContent); if(EditorGUI.EndChangeCheck()) { for(int i = 0; i < serializedObject.targetObjects.Length; i++) { JelloBody b = (JelloBody)serializedObject.targetObjects[i]; b.Mass = eMass.floatValue; } serializedObject.UpdateIfDirtyOrScript(); } EditorGUI.showMixedValue = false; if(!tar.IsStatic) { EditorGUILayout.BeginHorizontal(); EditorGUI.showMixedValue = eAffectedByGravity.hasMultipleDifferentValues; EditorGUILayout.PropertyField(eAffectedByGravity, useGravContent); EditorGUI.showMixedValue = false; EditorGUILayout.EndHorizontal(); if(eAffectedByGravity.boolValue) { EditorGUI.indentLevel++; EditorGUI.showMixedValue = eOverrideGravity.hasMultipleDifferentValues; EditorGUILayout.PropertyField(eOverrideGravity, overrideGravContent); EditorGUI.showMixedValue = false; if(eOverrideGravity.boolValue) { EditorGUI.indentLevel++; EditorGUI.showMixedValue = eGravity.hasMultipleDifferentValues; EditorGUILayout.PropertyField(eGravity, customGravContent); EditorGUI.showMixedValue = false; EditorGUI.indentLevel--; } EditorGUI.indentLevel--; } EditorGUI.showMixedValue = eKinematic.hasMultipleDifferentValues; EditorGUILayout.PropertyField(eKinematic, kinematicContent); EditorGUI.showMixedValue = false; } EditorGUI.showMixedValue = eTrigger.hasMultipleDifferentValues; EditorGUILayout.PropertyField(eTrigger, triggerContent); EditorGUI.showMixedValue = false; EditorGUI.showMixedValue = eAwake.hasMultipleDifferentValues; EditorGUILayout.PropertyField(eAwake, awakeContent); EditorGUI.showMixedValue = false; if(tar.meshLink == null || tar.meshLink.canModifyPivotPoint) { EditorGUI.indentLevel++; EditorGUILayout.BeginHorizontal(); SerializedProperty ePivotOffset = serializedObject.FindProperty("pivotOffset"); GUIStyle pivotStyle = new GUIStyle(EditorStyles.foldout); if(ePivotOffset.prefabOverride) pivotStyle.fontStyle = FontStyle.Bold; showPivot = EditorGUILayout.Foldout(showPivot, pivotFoldoutContent, pivotStyle); if(GUILayout.Button(centerPivotContent, EditorStyles.miniButton)) { Undo.RecordObjects(serializedObject.targetObjects, "Center Pivot"); for(int i = 0; i < serializedObject.targetObjects.Length; i++) { JelloBody jb = (JelloBody)serializedObject.targetObjects[i]; Undo.RecordObject(jb.gameObject.transform, "Center Pivot transform"); if(jb.meshLink != null) { Undo.RecordObject(jb.meshLink, "Center Pivot mesh"); Undo.RecordObject(jb.polyCollider, "Center Pivot collider"); Undo.RecordObject(jb.GetComponent<Renderer>(), "Center Pivot renderer"); Undo.RecordObject(jb.meshLink.LinkedMeshFilter, "Center Pivot filter"); } } for(int i = 0; i < serializedObject.targetObjects.Length; i++) { JelloBody bod = (JelloBody)serializedObject.targetObjects[i]; CenterPivot(bod); EditorUtility.SetDirty(bod.gameObject); EditorUtility.SetDirty(bod.meshLink); //serializedObject.UpdateIfDirtyOrScript(); } SceneView.RepaintAll(); } EditorGUILayout.EndHorizontal(); if(showPivot) { if(!serializedObject.isEditingMultipleObjects) { pivot = EditorGUILayout.Vector2Field("Position", pivot); if(pivot != Vector2.zero) { EditorGUILayout.BeginHorizontal(); if(GUILayout.Button(applyPivotContent, EditorStyles.miniButton)) { JelloBody jb = (JelloBody)serializedObject.targetObject; Undo.RecordObject(jb, "Change Pivot"); Undo.RecordObject(jb.gameObject.transform, "Change Pivot transform"); if(jb.meshLink != null) { Undo.RecordObject(jb.meshLink, "Change Pivot mesh"); Undo.RecordObject(jb.polyCollider, "Change Pivot collider"); Undo.RecordObject(jb.GetComponent<Renderer>(), "Change Pivot renderer"); Undo.RecordObject(jb.meshLink.LinkedMeshFilter, "Change Pivot filter"); } ChangePivot(tar); EditorUtility.SetDirty(tar.gameObject); EditorUtility.SetDirty(tar.meshLink); // serializedObject.UpdateIfDirtyOrScript(); } if(GUILayout.Button(cancelPivotContent, EditorStyles.miniButton)) pivot = Vector2.zero; SceneView.RepaintAll(); EditorGUILayout.EndHorizontal(); } } else { EditorGUILayout.HelpBox("Pivot Points may only be centered when multiple Game Objects are selected", MessageType.Info); } } EditorGUI.indentLevel--; } serializedObject.ApplyModifiedProperties(); }
/// <summary> /// Add an internal JelloPointMass to this JelloBody. /// This will also add an internal vertex to JelloBody.Shape.InternalVertices. /// Smartly means that most edits made to the JelloBody will be retained and is done via the JelloBody.smartSetShape() method. /// </summary> /// <param name="pointMass">The new JelloPointMass to add.</param> /// <param name="recenterBaseShape">Whether to recenter JelloBody.Shape.</param> /// <param name="options">ShapeSettingOptions on how Subcomponents should be modified as the JelloPointMass and JelloClosedShape vertex is added .</param> /// <param name="smartOptions">SmartShapeSettingOptions options on how Subcomponents should be modified as the JelloPointMass and JelloClosedShape vertex is added.</param> public void smartAddInternalPointMass(JelloPointMass pointMass, bool recenterBaseShape, ShapeSettingOptions options = ShapeSettingOptions.None, SmartShapeSettingOptions smartOptions = SmartShapeSettingOptions.None) { if(mBaseShape == null) return; JelloClosedShape newShape = new JelloClosedShape(mBaseShape.EdgeVertices, mBaseShape.InternalVertices, false); if(!newShape.addInternalVertex(pointMass.LocalPosition)) return; newShape.finish(recenterBaseShape); smartSetShape(newShape, options, smartOptions); mInternalPointMasses[mInternalPointMasses.Length - 1] = pointMass; }