// Calculating the impulse magnitude from a collision
    private float GetImpulse(MuscleCollision m, ref float layerThreshold)
    {
        float i = m.collision.impulse.sqrMagnitude;

        i /= puppetMaster.muscles [m.muscleIndex].rigidbody.mass;
        i *= 0.3f;                 // Coeficient for evening out for pre-0.3 versions

        // Collision resistance multipliers
        foreach (CollisionResistanceMultiplier crm in collisionResistanceMultipliers)
        {
            if (LayerMaskExtensions.Contains(crm.layers, m.collision.collider.gameObject.layer))
            {
                if (crm.multiplier <= 0f)
                {
                    i = Mathf.Infinity;
                }
                else
                {
                    i /= crm.multiplier;
                }

                layerThreshold = crm.collisionThreshold;

                break;
            }
        }

        return(i);
    }
        void OnCollisionImpulse(MuscleCollision m, float impulse)
        {
            if (m.collision.contacts.Length == 0)
            {
                return;
            }
            if (impulse < minCollisionImpulse)
            {
                return;
            }

            // Do not emit blood from prop contacts with static objects
            if (puppet.puppetMaster.muscles[m.muscleIndex].props.group == Muscle.Group.Prop && (m.collision.collider.attachedRigidbody == null || m.collision.collider.attachedRigidbody.isKinematic))
            {
                return;
            }

#if UNITY_2018_3_OR_NEWER
            transform.position = m.collision.GetContact(0).point; // Non-GC-allocating way of getting the contact.
#else
            transform.position = m.collision.contacts[0].point;
#endif
            transform.rotation = Quaternion.LookRotation(m.collision.contacts[0].normal);

            particles.Emit(Mathf.Min(emission + (int)(emissionImpulseAdd * impulse), maxEmission));
        }
        void OnCollisionImpulse(MuscleCollision m, float impulse)
        {
            if (m.collision.contacts.Length == 0)
            {
                return;
            }
            if (impulse < minCollisionImpulse)
            {
                return;
            }

            transform.position = m.collision.contacts[0].point;
            transform.rotation = Quaternion.LookRotation(m.collision.contacts[0].normal);

            particles.Emit(Mathf.Min(emission + (int)(emissionImpulseAdd * impulse), maxEmission));
        }
Exemple #4
0
    public void Damage(MuscleCollision mc, float impluse)
    {
        Muscle m = am.puppet.muscles[mc.muscleIndex];

        //目前击中 武器的话 不应该对自身造成伤害
        if (m.props.group == Muscle.Group.Prop)
        {
            return;
        }

        StateController.GroupProp gp = am.state.GetBaseProps(am.actorParts.GetMuscleGroup(mc.muscleIndex));

        //TODO 细化伤害公式
        //CollisionResistance 的考虑
        float damage = impluse * (1 - gp.curProp.Toughness);

        am.state.TryDoDamage(damage);
    }
        // When a muscle collides with something (called by the MuscleCollisionBroadcaster component on the muscle).
        protected override void OnMuscleCollisionBehaviour(MuscleCollision m)
        {
            // All the conditions for ignoring this
            if (!enabled) return;
            if (state == State.Unpinned) return;
            if (collisions > maxCollisions) return;
            if (!LayerMaskExtensions.Contains(collisionLayers, m.collision.gameObject.layer)) return;
            if (masterProps.normalMode == NormalMode.Kinematic && !puppetMaster.isActive && !masterProps.activateOnStaticCollisions && m.collision.gameObject.isStatic) return;

            // Get the collision impulse on the muscle
            float impulse = GetImpulse(m);
            if (impulse <= 0f) return;
            collisions ++;

            // Try to find out if it collided with another puppet's muscle
            if (m.collision.collider.attachedRigidbody != null) {
                broadcaster = m.collision.collider.attachedRigidbody.GetComponent<MuscleCollisionBroadcaster>();
                if (broadcaster != null) {
                    if (broadcaster.muscleIndex < broadcaster.puppetMaster.muscles.Length) {
                        // Multiply impulse (if the other muscle has been boosted)
                        impulse *= broadcaster.puppetMaster.muscles[broadcaster.muscleIndex].state.impulseMlp;

                        float stayF = m.isStay? 0.05f: 0.1f;
                        broadcaster.puppetMaster.muscles[broadcaster.muscleIndex].offset -= m.collision.impulse * Time.deltaTime * stayF;

                        /*
                        float velocityF = puppetMaster.muscles[m.muscleIndex].rigidbody.velocity.sqrMagnitude / broadcaster.puppetMaster.muscles[broadcaster.muscleIndex].rigidbody.velocity.sqrMagnitude;
                        velocityF = Mathf.Clamp(velocityF, 0.5f, 2f);
                        //velocityF = 1f + (velocityF - 1f) * 0.5f;
                        impulse /= velocityF;
                        */
                    }
                }
            }

            // Should we activate the puppet?
            if (Activate(m.collision, impulse)) puppetMaster.mode = PuppetMaster.Mode.Active;

            // Let other scripts know about the collision
            if (OnCollisionImpulse != null) OnCollisionImpulse(m, impulse);

            // Unpin the muscle (and other muscles)
            UnPin(m.muscleIndex, impulse);
        }
 protected virtual void OnMuscleCollisionExitBehaviour(MuscleCollision collision)
 {
 }
        public void OnMuscleCollisionExit(MuscleCollision collision)
        {
            if (!initiated) return;
            if (OnPreMuscleCollisionExit != null) OnPreMuscleCollisionExit(collision);

            OnMuscleCollisionExitBehaviour(collision);

            if (OnPostMuscleCollisionExit != null) OnPostMuscleCollisionExit(collision);
        }
 private void OnPreMuscleCollisionExit(MuscleCollision c)
 {
     if (!LayerMaskExtensions.Contains(groundLayers, c.collision.gameObject.layer)) return;
     groundContacts[c.muscleIndex] = false;
     groundContactPoints[c.muscleIndex] = Vector3.zero;
 }
        private void OnPreMuscleCollision(MuscleCollision c)
        {
            if (!LayerMaskExtensions.Contains(groundLayers, c.collision.gameObject.layer)) return;
            if (c.collision.contacts.Length == 0) return;
            lastGroundedTime = Time.time;

            groundContacts[c.muscleIndex] = true;
            if (mode == Mode.CenterOfPressure) groundContactPoints[c.muscleIndex] = GetCollisionCOP(c.collision);
        }
    // When a muscle collides with something (called by the MuscleCollisionBroadcaster component on the muscle).
    protected override void OnMuscleCollisionBehaviour(MuscleCollision m)
    {
        if (OnCollision != null)
        {
            OnCollision(m);
        }

        // All the conditions for ignoring this
        if (!enabled)
        {
            return;
        }
        if (state == State.Unpinned)
        {
            return;
        }
        if (collisions > maxCollisions)
        {
            return;
        }
        if (!LayerMaskExtensions.Contains(collisionLayers, m.collision.gameObject.layer))
        {
            return;
        }
        if (masterProps.normalMode == NormalMode.Kinematic && !puppetMaster.isActive && !masterProps.activateOnStaticCollisions && m.collision.gameObject.isStatic)
        {
            return;
        }

        // Get the collision impulse on the muscle
        float cT      = collisionThreshold;
        float impulse = GetImpulse(m, ref cT);

        float minImpulseMlp = PuppetMasterSettings.instance != null? (1f + PuppetMasterSettings.instance.currentlyActivePuppets * PuppetMasterSettings.instance.activePuppetCollisionThresholdMlp): 1f;
        float minImpulse    = cT * minImpulseMlp;

        if (impulse <= minImpulse)
        {
            return;
        }
        collisions++;

        // Try to find out if it collided with another puppet's muscle
        if (m.collision.collider.attachedRigidbody != null)
        {
            broadcaster = m.collision.collider.attachedRigidbody.GetComponent <MuscleCollisionBroadcaster>();
            if (broadcaster != null)
            {
                if (broadcaster.muscleIndex < broadcaster.puppetMaster.muscles.Length)
                {
                    // Multiply impulse (if the other muscle has been boosted)
                    impulse *= broadcaster.puppetMaster.muscles[broadcaster.muscleIndex].state.impulseMlp;

                    //float stayF = m.isStay? 0.05f: 0.1f;
                    //broadcaster.puppetMaster.muscles[broadcaster.muscleIndex].offset -= m.collision.impulse * Time.deltaTime * stayF;
                }
            }
        }

        // DO not move this up, the impulse value will be wrong.
        // Let other scripts know about the collision (even the ones below collision threshold)
        if (OnCollisionImpulse != null)
        {
            OnCollisionImpulse(m, impulse);
        }

        // Should we activate the puppet?
        if (Activate(m.collision, impulse))
        {
            puppetMaster.mode = PuppetMaster.Mode.Active;
        }

        // Unpin the muscle (and other muscles)
        UnPin(m.muscleIndex, impulse);
    }
        // Calculating the impulse magnitude from a collision
        private float GetImpulse(MuscleCollision m)
        {
            float i = m.collision.impulse.sqrMagnitude;

            // Collision threshold
            if (collisionThreshold > 0f) {
                float mlp = PuppetMasterSettings.instance != null? (1f + PuppetMasterSettings.instance.currentlyActivePuppets * PuppetMasterSettings.instance.activePuppetCollisionThresholdMlp): 1f;
                if (i < collisionThreshold * mlp) return 0f;
            }

            i *= 0.04f; // Coeficient for evening out for pre-0.3 versions

            // Collision resistance multipliers
            foreach (CollisionResistanceMultiplier crm in collisionResistanceMultipliers) {
                if (LayerMaskExtensions.Contains(crm.layers, m.collision.collider.gameObject.layer)) {
                    if (crm.multiplier <= 0f) i = Mathf.Infinity;
                    else i /= crm.multiplier;
                    break;
                }
            }
            /*
            // MuscleProps collision resistance multipliers
            BehaviourPuppet.MuscleProps props = GetProps(puppetMaster.muscles[m.muscleIndex].props.group);
            foreach (CollisionResistanceMultiplier crm in props.collisionResistanceMultipliers) {
                if (LayerMaskExtensions.Contains(crm.layers, m.collision.collider.gameObject.layer)) {
                    Debug.Log("Here");
                    if (crm.multiplier <= 0f) i = Mathf.Infinity;
                    else i /= crm.multiplier;
                    break;
                }
            }
            */

            return i;
        }