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>();
                            }
                        }
                    }
                }
            }
        }
Example #4
0
    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);
 }
Example #7
0
 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;
                    }
                }
            }
        }