public virtual void Enabled() { eKinematic = serializedObject.FindProperty("mIsKinematic"); eGravity = serializedObject.FindProperty("gravity"); eOverrideGravity = serializedObject.FindProperty("overrideWorldGravity"); eTrigger = serializedObject.FindProperty("mIsTrigger"); eAffectedByGravity = serializedObject.FindProperty("affectedByGravity"); eMass = serializedObject.FindProperty("mMass"); eAwake = serializedObject.FindProperty("mIsAwake"); for(int i = 0; i < serializedObject.targetObjects.Length; i++) { tar = (JelloBody)serializedObject.targetObjects[i]; tar.setComponentReferences(); } tar = (JelloBody)serializedObject.targetObject; SetEnumToBodyType(tar); GetBodyMeshLinkType(tar); pivot = Vector2.zero; subEditors = new List<SubComponentEditor>(); subEditors.Add (new SubComponentEditor(this)); subEditors.Add (new PointMassSubComponentEditor(this)); subEditors.Add (new AttachPointSubComponentEditor(this)); subEditors.Add (new JointSubComponentEditor(this)); }
public void ChangeBodyType(JelloBody t, bool retainInfo) { switch (colliderType) { case ColliderType.Static: var b = Undo.AddComponent <JelloBody>(t.gameObject); if (retainInfo) { CopyToStaticBody(t, b); } break; case ColliderType.Pressure: var bo = Undo.AddComponent <JelloPressureBody>(t.gameObject); if (retainInfo) { CopyToPressureBody(t, bo); } break; case ColliderType.Spring: var bod = Undo.AddComponent <JelloSpringBody>(t.gameObject); if (retainInfo) { CopyToSpringBody(t, bod); } break; } }
public void ChangePivot(JelloBody t) { t.polyCollider.points = JelloShapeTools.RemoveDuplicatePoints(t.polyCollider.points); t.Shape.changeVertices(t.polyCollider.points, t.Shape.InternalVertices); Vector2 diff = pivot; diff = new Vector2(diff.x / t.Scale.x, diff.y / t.Scale.y); diff = JelloVectorTools.rotateVector(diff, -t.Angle); if (t.meshLink != null) { MonoBehaviour monoBehavior; if (t.meshLink.UpdatePivotPoint(diff, out monoBehavior)) { EditorUtility.SetDirty(monoBehavior); } } for (int i = 0; i < t.Shape.VertexCount; i++) { t.Shape.setVertex(i, t.Shape.getVertex(i) - diff); } t.polyCollider.points = t.Shape.EdgeVertices; t.transform.position += (Vector3)JelloVectorTools.rotateVector(new Vector2(diff.x * t.Scale.x, diff.y * t.Scale.y), t.Angle); if (t.transform.childCount > 0) { for (int i = 0; i < t.transform.childCount; i++) { t.transform.GetChild(i).position -= (Vector3)diff; } } if (t.JointCount > 0) { for (int i = 0; i < t.JointCount; i++) { t.GetJoint(i).localAnchorA -= diff; } } if (t.AttachPointCount > 0) { for (int i = 0; i < t.AttachPointCount; i++) { t.GetAttachPoint(i).point -= diff; } } t.updateGlobalShape(true); EditorUtility.SetDirty(t); pivot = Vector2.zero; }
public virtual void CopyToSpringBody(JelloBody oldBody, JelloSpringBody newBody) { newBody.affectedByGravity = oldBody.affectedByGravity; newBody.disabled = oldBody.disabled; newBody.gravity = oldBody.gravity; newBody.IsAwake = oldBody.IsAwake; newBody.IsKinematic = oldBody.IsKinematic; newBody.IsStatic = false; newBody.IsTrigger = oldBody.IsTrigger; newBody.overrideWorldGravity = oldBody.overrideWorldGravity; newBody.pivotOffset = oldBody.pivotOffset; newBody.setComponentReferences(); newBody.polyCollider = oldBody.polyCollider; if (oldBody.meshLink != null) { newBody.meshLink = oldBody.meshLink; newBody.meshLink.body = newBody; } if (oldBody.Shape != null) { newBody.setShape(oldBody.Shape, shapeSettingOptions); newBody.Mass = oldBody.Mass != Mathf.Infinity ? oldBody.Mass : 1f; } for (int i = 0; i < oldBody.EdgePointMassCount; i++) { newBody.setEdgePointMass(oldBody.getEdgePointMass(i), i); newBody.getEdgePointMass(i).body = newBody; if (oldBody.Mass == Mathf.Infinity) { newBody.getEdgePointMass(i).Mass = 1f; } } for (int i = 0; i < oldBody.InternalPointMassCount; i++) { newBody.setInternalPointMass(oldBody.getInternalPointMass(i), i); newBody.getInternalPointMass(i).body = newBody; if (oldBody.Mass == Mathf.Infinity) { newBody.getInternalPointMass(i).Mass = 1f; } } for (int i = 0; i < oldBody.AttachPointCount; i++) { newBody.AddAttachPoint(oldBody.GetAttachPoint(i)); newBody.GetAttachPoint(i).body = newBody; } for (int i = 0; i < oldBody.JointCount; i++) { newBody.AddJoint(oldBody.GetJoint(i)); newBody.GetJoint(i).bodyA = newBody; } EditorUtility.SetDirty(newBody); }
// Use this for initialization void Start() { //cache body body = GetComponent <JelloBody>(); //subscribe the body's collision events body.JelloCollisionEvent += ProcessCollisionEvent; }
public void CenterPivot(JelloBody t) { Vector2 center = new Vector2(); t.polyCollider.points = JelloShapeTools.RemoveDuplicatePoints(t.polyCollider.points); t.Shape.changeVertices(t.polyCollider.points, t.Shape.InternalVertices); center = JelloShapeTools.FindCenter(t.Shape.EdgeVertices); //using vertices instead of collider.points because need of assigning entire array at once if (t.meshLink != null) { MonoBehaviour monoBehavior; if (t.meshLink.UpdatePivotPoint(center, out monoBehavior)) { EditorUtility.SetDirty(monoBehavior); } } for (int i = 0; i < t.Shape.VertexCount; i++) { t.Shape.setVertex(i, t.Shape.getVertex(i) - center); } t.polyCollider.points = t.Shape.EdgeVertices; t.transform.position += (Vector3)JelloVectorTools.rotateVector(new Vector2(center.x * t.Scale.x, center.y * t.Scale.y), t.Angle); if (t.transform.childCount > 0) { for (int i = 0; i < t.transform.childCount; i++) { t.transform.GetChild(i).position -= (Vector3)center; } } if (t.JointCount > 0) { for (int i = 0; i < t.JointCount; i++) { t.GetJoint(i).localAnchorA -= center; } } if (t.AttachPointCount > 0) { for (int i = 0; i < t.AttachPointCount; i++) { t.GetAttachPoint(i).point -= center; } } t.updateGlobalShape(true); EditorUtility.SetDirty(t); pivot = Vector2.zero; }
/// <summary> /// Initialize the MeshLink. /// </summary> /// <param name="forceUpdate">Whether to force an update to the MeshLink and MeshLink.LinkedMeshFilter.sharedMesh.</param> public virtual void Initialize(bool forceUpdate = false) { body = GetComponent <JelloBody>(); if (LinkedMeshFilter.sharedMesh == null) { LinkedMeshFilter.sharedMesh = new Mesh(); } }
public void SetEnumToBodyType(JelloBody t) { if(t.GetComponent<JelloBody>().GetType().ToString() == "JelloBody") colliderType = ColliderType.Static; if(t.GetComponent<JelloBody>().GetType().ToString() == "JelloSpringBody") colliderType = ColliderType.Spring; if(t.GetComponent<JelloBody>().GetType().ToString() == "JelloPressureBody") colliderType = ColliderType.Pressure; }
/// <summary> /// Initializes a new instance of the JelloPointMass class. /// </summary> /// <param name="mass">The mass of the JelloPointMass.</param> /// <param name="position">The position of the JelloPointMass.</param> /// <param name="b">The JelloBody that this JelloPointMass belongs to.</param> /// <param name="local">Whether the given position is local to the Given JelloBody.</param> /// /// <dl class="example"><dt>Example</dt></dl> /// ~~~{.c} /// //create a new JelloPointMass /// JelloBody body; /// /// JelloPointMass pm = new JelloPointMass(1f, Vector2.Zero, body, true); /// ~~~ public JelloPointMass(float mass, Vector2 position, JelloBody b, bool local) { body = b; Mass = mass; if(local) LocalPosition = position; else Position = position; }
public bool CompareEnumStateWithType(JelloBody t) { if(colliderType == ColliderType.Static && t.GetComponent<JelloBody>().GetType().ToString() == "JelloBody") return false; if(colliderType == ColliderType.Spring && t.GetComponent<JelloBody>().GetType().ToString() == "JelloSpringBody") return false; if(colliderType == ColliderType.Pressure && t.GetComponent<JelloBody>().GetType().ToString() == "JelloPressureBody") return false; return true; }
public void CopyToStaticBody(JelloBody oldBody, JelloBody newBody) //TODO make sure these all are up to date with any new variables that need assigning { newBody.affectedByGravity = oldBody.affectedByGravity; newBody.disabled = oldBody.disabled; newBody.gravity = oldBody.gravity; newBody.IsAwake = oldBody.IsAwake; newBody.IsKinematic = oldBody.IsKinematic; newBody.IsStatic = tar.IsStatic; newBody.IsStatic = true; newBody.IsTrigger = oldBody.IsTrigger; newBody.overrideWorldGravity = oldBody.overrideWorldGravity; newBody.pivotOffset = oldBody.pivotOffset; newBody.setComponentReferences(); newBody.polyCollider = oldBody.polyCollider; if(oldBody.meshLink != null) { newBody.meshLink = oldBody.meshLink; newBody.meshLink.body = newBody; } if(oldBody.Shape != null) { newBody.setShape(oldBody.Shape, shapeSettingOptions); newBody.Mass = Mathf.Infinity; } for(int i = 0; i < oldBody.EdgePointMassCount; i++) { newBody.setEdgePointMass(oldBody.getEdgePointMass(i), i); newBody.getEdgePointMass(i).Mass = Mathf.Infinity; newBody.getEdgePointMass(i).body = newBody; } for(int i = 0; i < oldBody.InternalPointMassCount; i++) { newBody.setInternalPointMass(oldBody.getInternalPointMass(i), i); newBody.getInternalPointMass(i).Mass = Mathf.Infinity; newBody.getInternalPointMass(i).body = newBody; } for(int i = 0; i < oldBody.AttachPointCount; i++) { newBody.AddAttachPoint(oldBody.GetAttachPoint(i)); newBody.GetAttachPoint(i).body = newBody; } for(int i = 0; i < oldBody.JointCount; i++) { newBody.AddJoint(oldBody.GetJoint(i)); newBody.GetJoint(i).bodyA = newBody; } EditorUtility.SetDirty(newBody); }
public static void HalveCollider() { JelloBody body = Selection.activeGameObject.GetComponent<JelloBody>(); if(body != null && body.polyCollider.points.Length > 5) { List<Vector2> points = new List<Vector2>(); bool add = true; for(int i = 0; i < body.polyCollider.points.Length; i++) { if(add) points.Add (body.polyCollider.points[i]); add = !add; } body.polyCollider.points = points.ToArray(); } }
public void GetBodyMeshLinkType(JelloBody t) { if(t.meshLink == null) t.meshLink = t.GetComponent<MeshLink>(); if(t.meshLink == null) return; foreach(MeshLink.MeshLinkType mltype in (MeshLink.MeshLinkType[])Enum.GetValues(typeof(MeshLink.MeshLinkType))) { if(t.meshLink.GetType().ToString() == mltype.ToString()) { t.meshLink.meshLinkType = mltype; break; } } meshLinkType = t.meshLink.meshLinkType; }
public void ChangeMeshLink(JelloBody t) { if (meshLinkType != MeshLink.MeshLinkType.None && typeof(MeshLink).Assembly.GetType(meshLinkType.ToString()) == null) { GetBodyMeshLinkType(t); Debug.LogWarning("The selected MeshLink type does not exist." + "\nIf you are attempting to use the RageSplineMeshLink or tk2dToolKitMeshLink, decompress the MeshLink.zip archive in the JelloPhysics folder" + "\nIf you are implementing your own MeshLink, ensure that it derives from MeshLink and its class name and the name listed in the MeshLink.MeshLinkType enum match."); return; } MeshLink[] links = t.gameObject.GetComponents <MeshLink>(); if (links.Length > 0) { if (links[0].meshLinkType == meshLinkType) { return; } for (int i = 0; i < links.Length; i++) { Undo.DestroyObjectImmediate(links[i]); } } if (meshLinkType == MeshLink.MeshLinkType.None) { t.meshLink = null; } else { Undo.RecordObject(t.gameObject, "Add Mesh Link"); t.meshLink = (MeshLink)UnityEngineInternal.APIUpdaterRuntimeServices.AddComponent(t.gameObject, "Assets/Jello-Physics-master/Editor/Bodies/JelloBodyEditor.cs (742,27)", meshLinkType.ToString()); t.meshLink.Initialize(); EditorUtility.SetDirty(t.meshLink); EditorUtility.SetDirty(t.gameObject); } EditorUtility.SetDirty(t); }
//TODO find a better way to handle this //extend the transform editor? public virtual void HandleBodyMovedInEditor(JelloBody tar) { // if(Application.isPlaying) // return; // // for(int a = 0; a < serializedObject.targetObjects.Length; a++) // { // JelloBody t = (JelloBody)serializedObject.targetObjects[a]; // if(t.EdgePointMassCount == 0) // continue; // // Vector2[] points = new Vector2[t.EdgePointMassCount]; // // points = t.Shape.transformVertices(t.Position, t.Angle, t.Scale); // // for(int i = 0; i < t.EdgePointMassCount; i++) // t.getEdgePointMass(i).Position = points[i]; // // EditorUtility.SetDirty(t); // } }
public override void CopyToSpringBody (JelloBody oldBody, JelloSpringBody newBody) { base.CopyToSpringBody (oldBody, newBody); JelloPressureBody old = (JelloPressureBody)oldBody; newBody.ShapeMatching = old.ShapeMatching; newBody.DefaultEdgeSpringStiffness = old.DefaultEdgeSpringStiffness; newBody.DefaultEdgeSpringDamping = old.DefaultEdgeSpringDamping; newBody.DefaultCustomSpringDamping = old.DefaultCustomSpringDamping; newBody.DefaultCustomSpringStiffness = old.DefaultCustomSpringStiffness; newBody.DefaultInternalSpringDamping = old.DefaultInternalSpringDamping; newBody.DefaultInternalSpringStiffness = old.DefaultInternalSpringStiffness; newBody.ShapeSpringDamping = old.ShapeSpringDamping; newBody.ShapeSpringStiffness = old.ShapeSpringStiffness; newBody.setInternalSprings(old.getInternalSprings()); for(int i = 0; i < old.CustomSpringCount; i++) { newBody.addCustomSpring(old.getCustomSpring(i)); } }
public override void CopyToPressureBody(JelloBody oldBody, JelloPressureBody newBody) { base.CopyToPressureBody (oldBody, newBody); JelloSpringBody old = (JelloSpringBody)oldBody; newBody.ShapeMatching = old.ShapeMatching; newBody.DefaultEdgeSpringStiffness = old.DefaultEdgeSpringStiffness; newBody.DefaultEdgeSpringDamping = old.DefaultEdgeSpringDamping; newBody.DefaultCustomSpringDamping = old.DefaultCustomSpringDamping; newBody.DefaultCustomSpringStiffness = old.DefaultCustomSpringStiffness; newBody.DefaultInternalSpringDamping = old.DefaultInternalSpringDamping; newBody.DefaultInternalSpringStiffness = old.DefaultInternalSpringStiffness; newBody.ShapeSpringDamping = old.ShapeSpringDamping; newBody.ShapeSpringStiffness = old.ShapeSpringStiffness; newBody.setInternalSprings(old.getInternalSprings()); for(int i = 0; i < old.CustomSpringCount; i++) { newBody.addCustomSpring(old.getCustomSpring(i)); } }
public SubComponentEditor(Editor editor) { mainEditor = (JelloBodyEditor)editor; body = (JelloBody)editor.target; }
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); } } }
/// <summary> /// Constructor. /// Will default to 2 using 2 JelloPointMAss objects as "Legs" if the indices array is erroneous or null. /// </summary> /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param> /// <param name="jelloBody">The JelloBody to to be attached to.</param> /// <param name="indeces">The JelloPointMass Indices. Should have a length of 1, 2, or 3.</param> /// <param name="useBaseShape">Whether to use the JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param> public JelloAttachPoint(Vector2 attachPoint, JelloBody jelloBody, int[] indeces, bool useBaseShape = true) { Rebuild(attachPoint, jelloBody, indeces, useBaseShape); }
/// <summary> /// Add a JelloBody to the JelloWorld. /// </summary> /// <param name="body">The JelloBody to be added.</param> public void addBody(JelloBody body) { //exit if this body is already here if (mBodies.Contains(body)) return; //if the body shares a gameobject with one of the bodies already in this world, remove the body that is already there for(int i = 0; i < mBodies.Count; i++) if(mBodies[i].gameObject == body.gameObject) removeBody(mBodies[i]); if(!body.overrideWorldGravity) body.gravity = Physics2D.gravity; mBodies.Add(body); }
/// <summary> /// Clear the JelloContact. /// </summary> public void Clear() { bodyA = bodyB = null; bodyApm = bodyBpmA = bodyBpmB = -1; hitPoint = R2 = R = mNormal = mTanget = Vector2.zero; scalarAB = penetration = 0f; colliderA = colliderB = null; rigidbodyA = rigidbodyB = null; transformA = transformB = null; }
public void ChangeMeshLink(JelloBody t) { if(meshLinkType != MeshLink.MeshLinkType.None && typeof(MeshLink).Assembly.GetType(meshLinkType.ToString()) == null) { GetBodyMeshLinkType(t); Debug.LogWarning("The selected MeshLink type does not exist." + "\nIf you are attempting to use the RageSplineMeshLink or tk2dToolKitMeshLink, decompress the MeshLink.zip archive in the JelloPhysics folder" + "\nIf you are implementing your own MeshLink, ensure that it derives from MeshLink and its class name and the name listed in the MeshLink.MeshLinkType enum match."); return; } MeshLink[] links = t.gameObject.GetComponents<MeshLink>(); if(links.Length > 0) { if(links[0].meshLinkType == meshLinkType) return; for(int i = 0; i < links.Length; i++) Undo.DestroyObjectImmediate(links[i]); } if(meshLinkType == MeshLink.MeshLinkType.None) { t.meshLink = null; } else { Undo.RecordObject(t.gameObject, "Add Mesh Link"); t.meshLink = (MeshLink)UnityEngineInternal.APIUpdaterRuntimeServices.AddComponent(t.gameObject, "Assets/Scripts/Jello-Physics-master/Editor/Bodies/JelloBodyEditor.cs (742,27)", meshLinkType.ToString()); t.meshLink.Initialize(); EditorUtility.SetDirty(t.meshLink); EditorUtility.SetDirty(t.gameObject); } EditorUtility.SetDirty(t); }
public void ChangePivot(JelloBody t) { t.polyCollider.points = JelloShapeTools.RemoveDuplicatePoints(t.polyCollider.points); t.Shape.changeVertices(t.polyCollider.points, t.Shape.InternalVertices); Vector2 diff = pivot; diff = new Vector2(diff.x / t.Scale.x, diff.y / t.Scale.y); diff = JelloVectorTools.rotateVector( diff, -t.Angle); if(t.meshLink != null) { MonoBehaviour monoBehavior; if(t.meshLink.UpdatePivotPoint(diff, out monoBehavior)) EditorUtility.SetDirty(monoBehavior); } for(int i = 0; i < t.Shape.VertexCount; i++) t.Shape.setVertex(i, t.Shape.getVertex(i) - diff); t.polyCollider.points = t.Shape.EdgeVertices; t.transform.position += (Vector3)JelloVectorTools.rotateVector(new Vector2(diff.x * t.Scale.x, diff.y * t.Scale.y), t.Angle); if(t.transform.childCount > 0) for(int i = 0; i < t.transform.childCount; i++) t.transform.GetChild(i).position -= (Vector3)diff; if(t.JointCount > 0) for(int i = 0; i < t.JointCount; i++) t.GetJoint (i).localAnchorA -= diff; if(t.AttachPointCount > 0) for(int i = 0; i < t.AttachPointCount; i++) t.GetAttachPoint(i).point -= diff; t.updateGlobalShape(true); EditorUtility.SetDirty(t); pivot = Vector2.zero; }
public virtual void DrawEditorGUITwo() { serializedObject.Update(); if(tar.GetComponent<MeshLink>() != null) hasMeshLink = true; else hasMeshLink = false; EditorGUILayout.BeginHorizontal(); SerializedProperty eMeshLink = serializedObject.FindProperty("meshLink"); GUIStyle meshStyle = new GUIStyle(EditorStyles.popup); if(eMeshLink.prefabOverride) meshStyle.fontStyle = FontStyle.Bold; meshLinkType = (MeshLink.MeshLinkType)EditorGUILayout.EnumPopup(meshLinkTypeContent, meshLinkType, meshStyle); bool showChangeButton = false; if(hasMeshLink) { if(tar.GetComponent<MeshLink>().meshLinkType != meshLinkType) showChangeButton = true; } else if(meshLinkType != MeshLink.MeshLinkType.None) { showChangeButton = true; } if(showChangeButton) { if(GUILayout.Button(changeTypeContent, EditorStyles.miniButton)) { for(int i = 0; i < serializedObject.targetObjects.Length; i++) ChangeMeshLink((JelloBody)serializedObject.targetObjects[i]); } } EditorGUILayout.EndHorizontal(); colliderType = (ColliderType)EditorGUILayout.EnumPopup(bodyTypeContent, colliderType, EditorStyles.miniButton); EditorGUILayout.BeginHorizontal(); if(CompareEnumStateWithType(tar)) { EditorGUI.indentLevel++; if(GUILayout.Button(new GUIContent(changeTypeContent), EditorStyles.miniButton )) //todo make this change all targets { JelloBody[] oldTargets = new JelloBody[targets.Length]; for(int i = 0; i < serializedObject.targetObjects.Length; i++) { JelloBody t = (JelloBody)serializedObject.targetObjects[i]; ChangeBodyType(t, retainBodyInformation); oldTargets[i] = t; } for(int i = 0; i < oldTargets.Length; i++) { Undo.DestroyObjectImmediate (oldTargets[i]); } return; } retainBodyInformation = EditorGUILayout.Toggle(keepInfoContent, retainBodyInformation); EditorGUI.indentLevel--; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); string[] options = new string[subEditors.Count]; for(int i = 0; i < options.Length; i++) options[i] = subEditors[i].name; currentSubEditor = EditorGUILayout.Popup("SubComponent", currentSubEditor, options); EditorGUILayout.EndHorizontal(); subEditors[currentSubEditor].DrawEditorGUI(); serializedObject.ApplyModifiedProperties(); }
// public Vector2[] largestVelocities; // public float[] queuedAngularVelocities; /// <summary> /// Constructor. /// </summary> /// <param name="collider2D">The Collider2D to fill out information about.</param> /// <param name="jelloBody">The Jellobody assosiated with the Collider2D.</param> public SupplementaryColliderInfo(Collider2D collider2D, JelloBody jelloBody = null) { collider = collider2D; body = jelloBody; transform = collider2D.transform; rigidbody = collider2D.rigidbody2D; Update(); }
/// <summary> /// Rebuild this JelloAttachPoint. /// </summary> /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param> /// <param name="jelloBody">The JelloBody to to be attached to.</param> /// <param name="indices">The JelloPointMass Indices. Should have a length of 1, 2, or 3.</param> /// <param name="useBaseShape">Whether to use the JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param> public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, int[] indices, bool useBaseShape = true) { body = jelloBody; transform = body.transform; if (indices == null) { if (affectedIndices == null) { Rebuild(attachPoint, jelloBody, useBaseShape); return; } else { indices = affectedIndices; } } else if (indices.Length > 4) { affectedIndices = new int[3]; for (int i = 0; i < 3; i++) { affectedIndices[i] = indices[i]; } } else { affectedIndices = indices; } Vector2[] verts = new Vector2[3]; if (useBaseShape) { for (int i = 0; i < affectedIndices.Length; i++) { verts[i] = body.Shape.getVertex(affectedIndices[i]); } } else { attachPoint = transform.TransformPoint(attachPoint); for (int i = 0; i < affectedIndices.Length; i++) { verts[i] = body.getPointMass(affectedIndices[i]).Position; } } if (affectedIndices.Length == 1) { scalars = new float[1]; scalars[0] = 1f; } else if (affectedIndices.Length == 2) { Vector2 hit; scalars = new float[2]; JelloVectorTools.getClosestPointOnSegmentSquared(attachPoint, verts[0], verts[1], out hit, out scalars[1]); scalars[0] = 1 - scalars[1]; } else if (affectedIndices.Length == 3) { scalars = JelloShapeTools.GetBarycentricCoords(attachPoint, verts); } //throw into for loop... point = Vector2.zero; for (int i = 0; i < affectedIndices.Length; i++) { point += scalars[i] * verts[i]; } if (!useBaseShape) { point = transform.InverseTransformPoint(point); } if (mAttachedTransform != null) { Vector3 newPos = transform.TransformPoint(point); newPos.z = mAttachedTransform.position.z; mAttachedTransform.position = newPos; } }
/// <summary> /// Get the other JelloBody, given a JelloBody. /// </summary> /// <param name="body">The given JelloBody.</param> /// <returns>The other JelloBody. Null if given JelloBody does not belong to this JelloContact.</returns> public JelloBody GetOtherBody(JelloBody body) { if(body == bodyA) return bodyB; else if(body == bodyB) return bodyA; else return null; }
//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> /// Initialize the MeshLink. /// </summary> /// <param name="forceUpdate">Whether to force an update to the MeshLink and MeshLink.LinkedMeshFilter.sharedMesh.</param> public virtual void Initialize(bool forceUpdate = false) { body = GetComponent<JelloBody>(); if (LinkedMeshFilter.sharedMesh == null) LinkedMeshFilter.sharedMesh = new Mesh(); }
/// <summary> /// Constructor. /// Will default to 2 using 2 JelloPointMAss objects as "Legs" if the indices array is erroneous or null. /// </summary> /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param> /// <param name="jelloBody">The JelloBody to to be attached to.</param> /// <param name="indeces">The JelloPointMass Indices. Should have a length of 1, 2, or 3.</param> /// <param name="useBaseShape">Whether to use the JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param> public JelloAttachPoint(Vector2 attachPoint, JelloBody jelloBody, int[] indeces, bool useBaseShape = true) { Rebuild (attachPoint, jelloBody, indeces, useBaseShape); }
public void ChangeBodyType(JelloBody t, bool retainInfo) { switch (colliderType) { case ColliderType.Static : var b = Undo.AddComponent<JelloBody>(t.gameObject); if(retainInfo) CopyToStaticBody(t, b); break; case ColliderType.Pressure : var bo = Undo.AddComponent<JelloPressureBody>(t.gameObject); if(retainInfo) CopyToPressureBody(t, bo); break; case ColliderType.Spring : var bod = Undo.AddComponent<JelloSpringBody>(t.gameObject); if(retainInfo) CopyToSpringBody(t, bod); break; } }
/// <summary> /// Rebuild this JelloAttachPoint. /// </summary> /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param> /// <param name="jelloBody">The JelloBody to to be attached to.</param> /// <param name="useBaseShape">Whether to use the JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param> /// <param name="numLegs">Number of JelloPointMass objects to use as "legs" (use 1, 2, or 3).</param> public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, bool useBaseShape = true, int numLegs = 0) { body = jelloBody; transform = body.transform; if (numLegs != 0) { if (numLegs < 0) { numLegs = 1; } if (numLegs > 3) { numLegs = 3; } affectedIndices = new int[numLegs]; } else if (affectedIndices == null || affectedIndices.Length == 0 || affectedIndices.Length > 3) { affectedIndices = new int[2]; //default to 3? } Vector2[] shape = new Vector2[body.Shape.VertexCount]; if (useBaseShape) { for (int i = 0; i < shape.Length; i++) { shape[i] = body.Shape.getVertex(i); } } else { attachPoint = transform.TransformPoint(attachPoint); for (int i = 0; i < shape.Length; i++) { shape[i] = body.getPointMass(i).Position; } } if (affectedIndices.Length == 1) { affectedIndices = JelloShapeTools.GetClosestIndices(attachPoint, shape, 1); scalars = new float[1]; scalars[0] = 1f; } else if (affectedIndices.Length == 2) { Vector2 hit; affectedIndices = JelloShapeTools.FindClosestEdgeOnShape(attachPoint, shape); scalars = new float[2]; JelloVectorTools.getClosestPointOnSegmentSquared(attachPoint, shape[affectedIndices[0]], shape[affectedIndices[1]], out hit, out scalars[1]); scalars[0] = 1 - scalars[1]; } else if (affectedIndices.Length == 3) { Vector2[] shapePerimeter = new Vector2[body.EdgePointMassCount]; if (useBaseShape) { shapePerimeter = body.Shape.EdgeVertices; } else { for (int i = 0; i < shapePerimeter.Length; i++) { shapePerimeter[i] = body.getEdgePointMass(i).Position; } } affectedIndices = JelloShapeTools.FindContainingTriangle(attachPoint, shape, shapePerimeter, body.Shape.Triangles, out scalars); } point = Vector2.zero; for (int i = 0; i < affectedIndices.Length; i++) { point += shape[affectedIndices[i]] * scalars[i]; } if (!useBaseShape) { point = transform.InverseTransformPoint(point); } if (mAttachedTransform != null) { Vector3 newPos = transform.TransformPoint(point); newPos.z = mAttachedTransform.position.z; mAttachedTransform.position = newPos; } }
public void CenterPivot(JelloBody t) { Vector2 center = new Vector2(); t.polyCollider.points = JelloShapeTools.RemoveDuplicatePoints(t.polyCollider.points); t.Shape.changeVertices(t.polyCollider.points, t.Shape.InternalVertices); center = JelloShapeTools.FindCenter(t.Shape.EdgeVertices);//using vertices instead of collider.points because need of assigning entire array at once if(t.meshLink != null) { MonoBehaviour monoBehavior; if(t.meshLink.UpdatePivotPoint(center, out monoBehavior)) EditorUtility.SetDirty(monoBehavior); } for(int i = 0; i < t.Shape.VertexCount; i++) t.Shape.setVertex(i, t.Shape.getVertex(i) - center); t.polyCollider.points = t.Shape.EdgeVertices; t.transform.position += (Vector3)JelloVectorTools.rotateVector(new Vector2(center.x * t.Scale.x, center.y * t.Scale.y), t.Angle); if(t.transform.childCount > 0) for(int i = 0; i < t.transform.childCount; i++) t.transform.GetChild(i).position -= (Vector3)center; if(t.JointCount > 0) for(int i = 0; i < t.JointCount; i++) t.GetJoint (i).localAnchorA -= center; if(t.AttachPointCount > 0) for(int i = 0; i < t.AttachPointCount; i++) t.GetAttachPoint(i).point -= center; t.updateGlobalShape(true); EditorUtility.SetDirty(t); pivot = Vector2.zero; }
/// <summary> /// Remove a JelloBody from the JelloWorld. /// </summary> /// <param name="body">The JelloBody to remove.</param> public void removeBody(JelloBody body) { if (mBodies.Contains(body)) mBodies.Remove(body); }
/// <summary> /// Rebuild this JelloAttachPoint. /// </summary> /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param> /// <param name="jelloBody">The JelloBody to to be attached to.</param> /// <param name="indices">The JelloPointMass Indices. Should have a length of 1, 2, or 3.</param> /// <param name="useBaseShape">Whether to use the JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param> public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, int[] indices, bool useBaseShape = true) { body = jelloBody; transform = body.transform; if(indices == null) { if(affectedIndices == null) { Rebuild(attachPoint, jelloBody, useBaseShape); return; } else { indices = affectedIndices; } } else if(indices.Length > 4) { affectedIndices = new int[3]; for(int i = 0; i < 3; i++) affectedIndices[i] = indices[i]; } else { affectedIndices = indices; } Vector2[] verts = new Vector2[3]; if(useBaseShape) { for(int i = 0; i < affectedIndices.Length; i++) verts[i] = body.Shape.getVertex(affectedIndices[i]); } else { attachPoint = transform.TransformPoint(attachPoint); for(int i = 0; i < affectedIndices.Length; i++) verts[i] = body.getPointMass(affectedIndices[i]).Position; } if(affectedIndices.Length == 1) { scalars = new float[1]; scalars[0] = 1f; } else if(affectedIndices.Length == 2) { Vector2 hit; scalars = new float[2]; JelloVectorTools.getClosestPointOnSegmentSquared (attachPoint, verts[0], verts[1], out hit, out scalars[1]); scalars[0] = 1 - scalars[1]; } else if (affectedIndices.Length == 3) { scalars = JelloShapeTools.GetBarycentricCoords(attachPoint, verts); } //throw into for loop... point = Vector2.zero; for(int i = 0; i < affectedIndices.Length; i++) point += scalars[i] * verts[i]; if(!useBaseShape) point = transform.InverseTransformPoint(point); if(mAttachedTransform != null) { Vector3 newPos = transform.TransformPoint(point); newPos.z = mAttachedTransform.position.z; mAttachedTransform.position = newPos; } }
/// <summary> /// Start tracking the Collider2D. /// Adds it to the JelloWorld.trackedColliders list and JelloWorld.TrackedColliderDictionary. /// </summary> /// <param name="collider">The Collider2D to start tracking.</param> /// <param name="jelloBody">The JelloBody, if any, the Collider2D belongs to.</param> public void StartTrackingCollider(Collider2D collider, JelloBody jelloBody = null) { if(trackedColliders.Contains(collider)) return; trackedColliders.Add (collider); TrackedColliderDictionary.Add (collider.GetInstanceID(), new SupplementaryColliderInfo(collider, jelloBody)); }
/// <summary> /// Start tracking the Collider2D. /// Adds it to the JelloWorld.trackedColliders list and JelloWorld.TrackedColliderDictionary. /// </summary> /// <param name="collider">The Collider2D to start tracking.</param> /// <param name="colliderInfo">The SupplementaryColliderInfo that describes the now tracked Collider2D.</param> /// <param name="jelloBody">The JelloBody, if any, the Collider2D belongs to.</param> /// <returns>Whether the collider is already being tracked. True if already being tracked, false if not.</returns> public bool StartTrackingCollider(Collider2D collider, out SupplementaryColliderInfo colliderInfo, JelloBody jelloBody = null) { if(trackedColliders.Contains(collider)) { colliderInfo = World.TrackedColliderDictionary[collider.GetInstanceID()]; return true; } trackedColliders.Add (collider); colliderInfo = new SupplementaryColliderInfo(collider, jelloBody); TrackedColliderDictionary.Add (collider.GetInstanceID(), colliderInfo); return false; }
/// <summary> /// Rebuild this JelloAttachPoint. /// </summary> /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param> /// <param name="jelloBody">The JelloBody to to be attached to.</param> /// <param name="useBaseShape">Whether to use the JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param> /// <param name="numLegs">Number of JelloPointMass objects to use as "legs" (use 1, 2, or 3).</param> public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, bool useBaseShape = true, int numLegs = 0) { body = jelloBody; transform = body.transform; if(numLegs != 0) { if(numLegs < 0) numLegs = 1; if(numLegs > 3) numLegs = 3; affectedIndices = new int[numLegs]; } else if(affectedIndices == null || affectedIndices.Length == 0 || affectedIndices.Length > 3) affectedIndices = new int[2];//default to 3? Vector2[] shape = new Vector2[body.Shape.VertexCount]; if(useBaseShape) { for(int i = 0; i < shape.Length; i++) shape[i] = body.Shape.getVertex(i); } else { attachPoint = transform.TransformPoint(attachPoint); for(int i = 0; i < shape.Length; i++) shape[i] = body.getPointMass(i).Position; } if(affectedIndices.Length == 1) { affectedIndices = JelloShapeTools.GetClosestIndices(attachPoint, shape, 1); scalars = new float[1]; scalars[0] = 1f; } else if(affectedIndices.Length == 2) { Vector2 hit; affectedIndices = JelloShapeTools.FindClosestEdgeOnShape(attachPoint, shape); scalars = new float[2]; JelloVectorTools.getClosestPointOnSegmentSquared (attachPoint, shape[affectedIndices[0]], shape[affectedIndices[1]], out hit, out scalars[1]); scalars[0] = 1 - scalars[1]; } else if(affectedIndices.Length == 3) { Vector2[] shapePerimeter = new Vector2[body.EdgePointMassCount]; if(useBaseShape) { shapePerimeter = body.Shape.EdgeVertices; } else { for(int i = 0; i < shapePerimeter.Length; i++) shapePerimeter[i] = body.getEdgePointMass(i).Position; } affectedIndices = JelloShapeTools.FindContainingTriangle(attachPoint, shape, shapePerimeter, body.Shape.Triangles, out scalars); } point = Vector2.zero; for(int i = 0; i < affectedIndices.Length; i++) point += shape[affectedIndices[i]] * scalars[i]; if(!useBaseShape) point = transform.InverseTransformPoint(point); if(mAttachedTransform != null) { Vector3 newPos = transform.TransformPoint(point); newPos.z = mAttachedTransform.position.z; mAttachedTransform.position = newPos; } }
/// <summary> /// Get the other JelloBody, given a JelloBody. /// Samples the first entry in JelloCollision.contacts. /// </summary> /// <param name="body">The given JelloBody.</param> /// <returns>The other JelloBody. Null if the given JelloBody does not belong to this JelloCollision or if JelloCollision.contacts is null.</returns> public JelloBody GetOtherBody(JelloBody body) { if(contacts == null) return null; if(body == contacts[0].bodyA) return contacts[0].bodyB; else if(body == contacts[0].bodyB) return contacts[0].bodyA; else return null; }
// Use this for initialization void Start() { //cache body body = GetComponent<JelloBody>(); //subscribe the body's collision events body.JelloCollisionEvent += ProcessCollisionEvent; }
//TODO make sure these all are up to date with any new variables that need assigning public void CopyToStaticBody(JelloBody oldBody, JelloBody newBody) { newBody.affectedByGravity = oldBody.affectedByGravity; newBody.disabled = oldBody.disabled; newBody.gravity = oldBody.gravity; newBody.IsAwake = oldBody.IsAwake; newBody.IsKinematic = oldBody.IsKinematic; newBody.IsStatic = tar.IsStatic; newBody.IsStatic = true; newBody.IsTrigger = oldBody.IsTrigger; newBody.overrideWorldGravity = oldBody.overrideWorldGravity; newBody.pivotOffset = oldBody.pivotOffset; newBody.setComponentReferences(); newBody.polyCollider = oldBody.polyCollider; if(oldBody.meshLink != null) { newBody.meshLink = oldBody.meshLink; newBody.meshLink.body = newBody; } if(oldBody.Shape != null) { newBody.setShape(oldBody.Shape, shapeSettingOptions); newBody.Mass = Mathf.Infinity; } for(int i = 0; i < oldBody.EdgePointMassCount; i++) { newBody.setEdgePointMass(oldBody.getEdgePointMass(i), i); newBody.getEdgePointMass(i).Mass = Mathf.Infinity; newBody.getEdgePointMass(i).body = newBody; } for(int i = 0; i < oldBody.InternalPointMassCount; i++) { newBody.setInternalPointMass(oldBody.getInternalPointMass(i), i); newBody.getInternalPointMass(i).Mass = Mathf.Infinity; newBody.getInternalPointMass(i).body = newBody; } for(int i = 0; i < oldBody.AttachPointCount; i++) { newBody.AddAttachPoint(oldBody.GetAttachPoint(i)); newBody.GetAttachPoint(i).body = newBody; } for(int i = 0; i < oldBody.JointCount; i++) { newBody.AddJoint(oldBody.GetJoint(i)); newBody.GetJoint(i).bodyA = newBody; } EditorUtility.SetDirty(newBody); }