Example #1
0
 private void Update()
 {
     if (preSoftenDestructible && destructibleObj != null && impactInfo != null)
     {
         destructibleObj.ApplyImpactDamage(impactInfo);
         impactInfo = null;
         destructibleObj = null;
         preSoftenDestructible = false;
     }
 }
Example #2
0
        public void ProcessBulletHit(RaycastHit hitInfo, Vector3 bulletDirection)
        {
            // Check if bullet struck dirt
            if (hitInfo.transform.GetComponent<Terrain>() != null)
            {
                ObjectPool.Instance.Spawn(Instance.strikeDirtPrefab, hitInfo.point, Quaternion.LookRotation(Vector3.up));
                return;
            }

            // Check if bullet struck wood, concrete, glass, etc. through use of the TagIt system (Note: You can swap this out with your own multi-tagging system)
            TagIt tagIt = hitInfo.collider.GetComponent<TagIt>();
            if (tagIt != null && tagIt.tags.Count > 0)
            {
                GameObject prefab;
                if (tagIt.tags.Contains(Tag.Wood))
                    prefab = Instance.strikeWoodPrefab;
                else if (tagIt.tags.Contains(Tag.Glass))
                    prefab = Instance.strikeGlassPrefab;
                else if (tagIt.tags.Contains(Tag.Metal))
                    prefab = Instance.strikeMetalPrefab;
                else if (tagIt.tags.Contains(Tag.Rubber))
                    prefab = Instance.strikeRubberPrefab;
                else if (tagIt.tags.Contains(Tag.Stuffing))
                    prefab = Instance.strikeStuffingPrefab;
                else // Default is concrete effect
                    prefab = Instance.strikeConcretePrefab;

                ObjectPool.Instance.Spawn(prefab, hitInfo.point, Quaternion.LookRotation(hitInfo.normal));
            }
            else // Default is concrete effect
                ObjectPool.Instance.Spawn(Instance.strikeConcretePrefab, hitInfo.point, Quaternion.LookRotation(hitInfo.normal));

            // Apply damage if object hit was Destructible
            Destructible destObj = hitInfo.collider.gameObject.GetComponentInParent<Destructible>();
            if (destObj != null)
            {
                ImpactInfo bulletImpact = new ImpactInfo() { Damage = Instance.bulletDamage, AdditionalForce = Instance.bulletForcePerSecond, AdditionalForcePosition = hitInfo.point, AdditionalForceRadius = .5f };
                destObj.ApplyImpactDamage(bulletImpact);
            }

            Vector3 force = bulletDirection * (Instance.bulletForcePerSecond / Instance.bulletForceFrequency);

            // Apply impact force to rigidbody hit
            Rigidbody rbody = hitInfo.collider.attachedRigidbody;
            if (rbody != null)
                rbody.AddForceAtPosition(force, hitInfo.point, ForceMode.Impulse);

            // Check for Chip-Away Debris
            ChipAwayDebris chipAwayDebris = hitInfo.collider.gameObject.GetComponent<ChipAwayDebris>();
            if (chipAwayDebris != null) 
                chipAwayDebris.BreakOff(force, hitInfo.point);
        }
Example #3
0
        private void DoMeleeDamage()
        {
            Collider[] objectsInRange = Physics.OverlapSphere(meleeDamageArea.position, .75f);
            
            // Apply force and damage to colliders and rigidbodies in range of the explosion
            foreach (Collider col in objectsInRange)
            {
                // Ignore terrain colliders
                if (col is TerrainCollider)
                    continue;

                // Check if weapon struck wood, concrete, glass, etc. through use of the TagIt system (Note: You can swap this out with your own multi-tagging system)
                TagIt tagIt = col.GetComponent<TagIt>();
                if (tagIt != null && tagIt.tags.Count > 0)
                {
                    GameObject prefab;
                    if (tagIt.tags.Contains(Tag.Wood))
                        prefab = Instance.strikeWoodPrefab;
                    else if (tagIt.tags.Contains(Tag.Glass))
                        prefab = Instance.strikeGlassPrefab;
                    else if (tagIt.tags.Contains(Tag.Metal))
                        prefab = Instance.strikeMetalPrefab;
                    else if (tagIt.tags.Contains(Tag.Rubber))
                        prefab = Instance.strikeRubberPrefab;
                    else if (tagIt.tags.Contains(Tag.Stuffing))
                        prefab = Instance.strikeStuffingPrefab;
                    else // Default is concrete effect
                        prefab = Instance.strikeConcretePrefab;

                    ObjectPool.Instance.Spawn(prefab, meleeDamageArea.position, Quaternion.LookRotation(meleeDamageArea.forward*-1));
                }
                else // Default is concrete effect
                    ObjectPool.Instance.Spawn(Instance.strikeConcretePrefab, meleeDamageArea.position, Quaternion.LookRotation(meleeDamageArea.forward*-1));

                // Apply impact force to rigidbody hit
                Rigidbody rbody = col.attachedRigidbody;
                if (rbody != null)
                    rbody.AddForceAtPosition(firstPersonController.forward*3f, firstPersonController.position, ForceMode.Impulse);

                // Apply damage if object hit was Destructible
                Destructible destObj = col.gameObject.GetComponentInParent<Destructible>();
                if (destObj != null)
                {
                    ImpactInfo meleeImpact = new ImpactInfo() { Damage = meleeDamage, AdditionalForce = 150f, AdditionalForcePosition = firstPersonController.position, AdditionalForceRadius = 2f };
                    destObj.ApplyImpactDamage(meleeImpact);
                }
            }
        }
Example #4
0
        //TODO: Combine these methods into one ApplyDamage overload, and make ExplosionInfo and ImpactInfo inherit from an interface or base class.
        public void ApplyImpactDamage(ImpactInfo impactInfo)
        {
            if (IsDestroyed || IsInvulnerable) return; // don't try to apply damage to an already-destroyed object.

            currentHitPoints -= impactInfo.Damage;

            CheckForObliterate(impactInfo.Damage);

            SetDamageLevel();
            if (currentHitPoints <= 0)
            {
                IsDestroyed = true;
                PlayDamageLevelEffects();
                // Advance to the next destructible object, passing in the leftover damage to apply to the next model and 
                // the projectile, which may have force added to it so it can punch through the final (destroyed) object.
                if (canBeDestroyed)
                    DestructionManager.Instance.ProcessDestruction(this, destroyedPrefab, impactInfo, IsObliterated);
            }
        }
Example #5
0
 /// <summary>Applies a generic amount of damage, with no special impact or explosive force./// </summary>
 public void ApplyDamage(int damageAmount)
 {
     //TODO: This method should call to ProcessDestruction with a general, non-specific DamageInfo.
     //HACK: Use ImpactInfo with no impact force for now.
     ImpactInfo generalDamage = new ImpactInfo() { Damage = damageAmount };
     ApplyImpactDamage(generalDamage);
 }
Example #6
0
 /// <summary>Reapply force to the impact object (if any) so it punches through the destroyed object.</summary>
 public static void ReapplyImpactForce(ImpactInfo info, float velocityReduction)
 {
     if (info.ImpactObject != null && !info.ImpactObject.isKinematic)
     {
         info.ImpactObject.velocity = Vector3.zero; //zero out the velocity
         info.ImpactObject.AddForce(info.ImpactObjectVelocityTo * velocityReduction, ForceMode.Impulse);
     }
 }
Example #7
0
        public static void ProcessDestructibleCollision(this Destructible destructibleObj, Collision collision, Rigidbody collidingRigidbody)
        {
            // Ignore collisions if collidingRigidbody is null
            if (collidingRigidbody == null) return;

            // Ignore collisions if this object is destroyed.
            if (destructibleObj.IsDestroyed) return;

            // Check that the impact is forceful enough to cause damage
            if (collision.relativeVelocity.magnitude < 2f) return;

            if (collision.contacts.Length == 0) return;

            float impactDamage;
            Rigidbody otherRbody = collision.contacts[0].otherCollider.attachedRigidbody;

            // If we've collided with another rigidbody, use the average mass of the two objects for impact damage.
            if (otherRbody != null)
            {
                float avgMass = (otherRbody.mass + collidingRigidbody.mass) / 2;
                impactDamage = Vector3.Dot(collision.contacts[0].normal, collision.relativeVelocity) * avgMass;
            }
            else // If we've collided with a static object (terrain, static collider, etc), use this object's attached rigidbody.
                impactDamage = Vector3.Dot(collision.contacts[0].normal, collision.relativeVelocity) * collidingRigidbody.mass;

            impactDamage = Mathf.Abs(impactDamage); // can't have negative damage

            if (impactDamage > 1f) // impact must do at least 1 damage to bother with.
            {
                //Debug.Log("Impact Damage: " + impactDamage);
                //Debug.DrawRay(otherRbody.transform.position, collision.relativeVelocity, Color.yellow, 10f); // yellow: where the impact force is heading
                ImpactInfo impactInfo = new ImpactInfo() { ImpactObject = otherRbody, Damage = (int)impactDamage, ImpactObjectVelocityFrom = collision.relativeVelocity * -1 };
                destructibleObj.ApplyImpactDamage(impactInfo);
            }
        }