예제 #1
0
    private static IEnumerable <SusceptibleRigidbody2D> GetSusceptibleBodies(ForceKind kind)
    {
        // TODO: cache 'em, cache em all!
        var bodies = GameObject.FindObjectsOfType <Rigidbody2D> ();

        foreach (var body in bodies)
        {
            var   material  = ForceReceiver.GetMaterial(body.gameObject);
            float influence = material.GetInfluence(kind);

            if (influence == 0)
            {
                continue;
            }

            yield return(new SusceptibleRigidbody2D(body, influence, material));
        }
    }
예제 #2
0
    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.layer != LayerMask.NameToLayer("Destructable"))
        {
            return;
        }

        ForceReceiver receiver = collision.gameObject.GetComponent <ForceReceiver>();

        if (receiver != null)
        {
            receiver.OnHit(Velocity);
        }


//        print("Hit with force: " + Velocity + " magnitude: " + Velocity.magnitude);

//        Debug.

        //        foreach (ContactPoint contact in collision.contacts)
        //        {
        //            Debug.DrawRay(contact.point, contact.normal, Color.white, 1f);
        //        }
    }
예제 #3
0
    private void ApplyToBodies(float timeFactor)
    {
        var ignoreSelfCollisionPredicate = Spatial.IgnoreSelfCollisionPredicate(rigidbody2D);
        // TODO: consider using CircleCollider2D trigger. I don't know how much faster trigger will be.

        var contactsByBody = Spatial.GetCircleContactsByBody(
            Origin, Radius, 0, Radius,
            hit => hit.collider.attachedRigidbody == null || ignoreSelfCollisionPredicate(hit),
            NumSweepDirections,
            LayerMask
            );

#if UNITY_EDITOR
        lastFrameContacts = contactsByBody;
#endif

        foreach (var bodyAndContacts in contactsByBody)
        {
            var body         = bodyAndContacts.Key;
            var bodyContacts = bodyAndContacts.Value;

            float influence = ForceReceiver.GetInfluence(body.gameObject, Kind);

            if (influence == 0)
            {
                continue;
            }

            float forceAmount = PhysicsHelper.ConvertToNewtons(Amount, Mode, body.gameObject);
            forceAmount *= influence * timeFactor * AnimatedMultiplier;

            if (DecreaseWithDistance)
            {
                var   contactForceFactors = new ContactForceFactor [bodyContacts.Count];
                float maxDistanceFactor   = float.NegativeInfinity;
                float distanceFactorSum   = 0;

                for (int i = 0; i < bodyContacts.Count; i++)
                {
                    var   contact        = bodyContacts [i];
                    float distanceFactor = 1 - contact.Distance / Radius;

                    if (distanceFactor > maxDistanceFactor)
                    {
                        maxDistanceFactor = distanceFactor;
                    }

                    distanceFactorSum += distanceFactor;
                    var cff = new ContactForceFactor(contact, distanceFactor);
                    contactForceFactors [i] = cff;
                }

                forceAmount *= maxDistanceFactor;

                /* Sum of all contact factors multiplied
                * by following factorScale will be 1. */
                float factorScale = 1 / distanceFactorSum;

                foreach (var cff in contactForceFactors)
                {
                    var   contact            = cff.Contact;
                    float distanceFactor     = cff.Factor * factorScale;
                    float contactForceAmount = forceAmount * distanceFactor;
                    var   forceVector        = contact.Direction * contactForceAmount;

                    if (SendForceMessage(body.gameObject, forceVector, contact.Point))
                    {
                        body.AddForceAtPosition(forceVector, contact.Point);
                    }
                }
            }
            else
            {
                forceAmount /= bodyContacts.Count;

                foreach (var contact in bodyContacts)
                {
                    var forceVector = contact.Direction * forceAmount;

                    if (SendForceMessage(body.gameObject, forceVector, contact.Point))
                    {
                        body.AddForceAtPosition(forceVector, contact.Point);
                    }
                }
            }
        }
    }