private void OnFracture(OnFractureEventArgs args) { if (args.OriginalObject.gameObject == gameObject) { TransferOurJoint(args); RewriteOtherJoints(args); } }
private void OnFracture(OnFractureEventArgs fractureRoot) { Rigidbody body = GetComponent<Rigidbody>(); if (body != null) { body.isKinematic = false; // Need to turn off kinematic to get collision events _rigidBodyVelocity = body.velocity; _rigidBodyAngularVelocity = body.angularVelocity; _rigidBodyConstraints = body.constraints; body.constraints = RigidbodyConstraints.FreezeAll; _impactPoint = Vector3.zero; _impactVelocity = Vector3.zero; _impactMass = 0.0f; _fractureFrame = Time.frameCount; this.enabled = true; } }
private void RewriteOtherJoints(OnFractureEventArgs args) { Joint[] joints; if (IncomingJointsSearchRoot != null) { joints = IncomingJointsSearchRoot.GetComponentsInChildren<Joint>(); } else { joints = FindObjectsOfType<Joint>(); } if (joints != null) { for (int i = 0; i < joints.Length; i++) { if (joints[i] != null && joints[i].connectedBody == args.OriginalObject.GetComponent<Rigidbody>()) { Transform rootTrans = args.FracturePiecesRootObject.transform; for (int j = 0; j < rootTrans.childCount; j++) { Transform pieceTrans = rootTrans.GetChild(j); Vector3 worldPoint = joints[i].transform.localToWorldMatrix.MultiplyPoint(joints[i].anchor); Collider ourCollider = pieceTrans.GetComponent<Collider>(); Vector3 closestOnUs = (ourCollider != null) ? ourCollider.ClosestPointOnBounds(worldPoint) : transform.position; if ((worldPoint - pieceTrans.position).sqrMagnitude < (closestOnUs - pieceTrans.position).sqrMagnitude + DistanceTolerance * DistanceTolerance) { joints[i].connectedBody = pieceTrans.GetComponent<Rigidbody>(); } } } } } }
private void OnFracture(OnFractureEventArgs args) { if (args.OriginalObject.gameObject == gameObject) { float radiusSq = ForceFalloffRadius * ForceFalloffRadius; for (int i = 0; i < args.FracturePiecesRootObject.transform.childCount; i++) { Transform piece = args.FracturePiecesRootObject.transform.GetChild(i); piece.gameObject.tag = "Fragment"; Rigidbody rb = piece.GetComponent <Rigidbody>(); if (rb != null) { Vector3 force = _impactMass * _impactVelocity / (rb.mass + _impactMass); if (ForceFalloffRadius > 0.0f) { float distSq = (piece.position - _impactPoint).sqrMagnitude; force *= Mathf.Clamp01(1.0f - distSq / (radiusSq)); } rb.AddForceAtPosition(force * rb.mass, _impactPoint, ForceMode.Impulse); } } if (AdjustForKinematic) { // If the fractured body is kinematic, the collision for the colliding body will // be as if it hit an unmovable wall. Try to correct for that by adding the same // force to colliding body. Rigidbody thisBody = GetComponent <Rigidbody>(); if (thisBody != null && thisBody.isKinematic && _impactBody != null) { Vector3 force = thisBody.mass * _impactVelocity / (thisBody.mass + _impactMass); _impactBody.AddForceAtPosition(force * _impactMass, _impactPoint, ForceMode.Impulse); } } } }
private void OnFracture(OnFractureEventArgs args) { if (args.OriginalObject.gameObject == gameObject) { float radiusSq = ForceFalloffRadius * ForceFalloffRadius; for (int i = 0; i < args.FracturePiecesRootObject.transform.childCount; i++) { Transform piece = args.FracturePiecesRootObject.transform.GetChild(i); Rigidbody rb = piece.GetComponent<Rigidbody>(); if (rb != null) { Vector3 force = _impactMass * _impactVelocity / (rb.mass + _impactMass); if (ForceFalloffRadius > 0.0f) { float distSq = (piece.position - _impactPoint).sqrMagnitude; force *= Mathf.Clamp01(1.0f - distSq / (radiusSq)); } rb.AddForceAtPosition(force * rb.mass, _impactPoint, ForceMode.Impulse); } } if (AdjustForKinematic) { // If the fractured body is kinematic, the collision for the colliding body will // be as if it hit an unmovable wall. Try to correct for that by adding the same // force to colliding body. Rigidbody thisBody = GetComponent<Rigidbody>(); if (thisBody != null && thisBody.isKinematic && _impactBody != null) { Vector3 force = thisBody.mass * _impactVelocity / (thisBody.mass + _impactMass); _impactBody.AddForceAtPosition(force * _impactMass, _impactPoint, ForceMode.Impulse); } } } }
private void OnFracture(OnFractureEventArgs fractureRoot) { GetComponent<Renderer>().material.color = new Color(0.3f, 0.3f, 0.3f, 1.0f); }
private void OnFracture(OnFractureEventArgs fractureRoot) { GetComponent <Renderer>().material.color = new Color(0.3f, 0.3f, 0.3f, 1.0f); }
protected override AsyncFractureResult FractureInternal(Vector3 localPos) { if (gameObject.activeSelf) { if (GeneratedPieces == null) { GenerateFractureMeshes(localPos, null); EnableFracturePieces(); } else { EnableFracturePieces(); OnFractureEventArgs args = new OnFractureEventArgs(this, GeneratedPieces); // Notify scripts on this object _ignoreOnFractured = true; gameObject.SendMessage("OnFracture", args, SendMessageOptions.DontRequireReceiver); _ignoreOnFractured = false; // Notify each fracture piece Transform trans = GeneratedPieces.transform; for (int i = 0; i < trans.childCount; i++) { trans.GetChild(i).gameObject.SendMessage("OnFracture", args, SendMessageOptions.DontRequireReceiver); } } gameObject.SetActive(false); AsyncFractureResult result = new AsyncFractureResult(); result.SetResult(GeneratedPieces, EntireMeshBounds); return result; } else { AsyncFractureResult result = new AsyncFractureResult(); result.SetResult(null, new Bounds()); return result; } }
internal override void OnFracture(OnFractureEventArgs args) { if (!_ignoreOnFractured) { base.OnFracture(args); GeneratedPieces = args.FracturePiecesRootObject; GeneratedPieces.SetActive(false); } }
private void TransferOurJoint(OnFractureEventArgs args) { Joint origJoint = args.OriginalObject.GetComponent<Joint>(); if (origJoint != null) { Vector3 worldPoint = args.OriginalObject.transform.localToWorldMatrix.MultiplyPoint(origJoint.anchor); Transform rootTrans = args.FracturePiecesRootObject.transform; for (int i = 0; i < rootTrans.childCount; i++) { Transform pieceTrans = rootTrans.GetChild(i); Collider ourCollider = pieceTrans.GetComponent<Collider>(); Vector3 closestOnUs = (ourCollider != null) ? ourCollider.ClosestPointOnBounds(worldPoint) : transform.position; if ((worldPoint - pieceTrans.position).sqrMagnitude < (closestOnUs - pieceTrans.position).sqrMagnitude + DistanceTolerance * DistanceTolerance) { Joint ourJoint = (Joint)pieceTrans.gameObject.AddComponent(origJoint.GetType()); string ourName = ourJoint.name; // Copy the properties #if UNITY_METRO && !UNITY_EDITOR foreach ( PropertyInfo info in origJoint.GetType().GetRuntimeProperties()) { if (info.CanWrite && info.CanRead) { info.SetValue(ourJoint, info.GetValue(origJoint, null), null); } } #else foreach ( PropertyInfo info in origJoint.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (info.CanWrite && info.CanRead) { info.SetValue(ourJoint, info.GetValue(origJoint, null), null); } } foreach ( PropertyInfo info in origJoint.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)) { if (info.CanWrite && info.CanRead && info.GetCustomAttributes(typeof (SerializeField), true).Length != 0) { info.SetValue(ourJoint, info.GetValue(origJoint, null), null); } } #endif ourJoint.name = ourName; // Reanchor ourJoint.anchor = pieceTrans.worldToLocalMatrix.MultiplyPoint(worldPoint); Vector3 connectedAnchorWorldPoint = args.OriginalObject.transform.localToWorldMatrix.MultiplyPoint(origJoint.connectedAnchor); ourJoint.connectedAnchor = pieceTrans.worldToLocalMatrix.MultiplyPoint(connectedAnchorWorldPoint); Vector3 worldAxis = args.OriginalObject.transform.localToWorldMatrix.MultiplyVector(origJoint.axis); ourJoint.axis = pieceTrans.worldToLocalMatrix.MultiplyVector(worldAxis).normalized; } // Make sure each piece has one of these scripts attached if (pieceTrans.GetComponent<TransferJointsOnFracture>() == null) { TransferJointsOnFracture tjof = pieceTrans.gameObject.AddComponent<TransferJointsOnFracture>(); tjof.IncomingJointsSearchRoot = IncomingJointsSearchRoot; tjof.DistanceTolerance = DistanceTolerance; } } } }