示例#1
0
        // Hit something without Raycast. Apply damage, apply FX, etc.
        public virtual void OnRaycastHit(RaycastHit hit)
        {
            ApplyParticleFX(hit.point, Quaternion.FromToRotation(Vector3.forward, hit.normal), hit.collider);

            // push object if rigidbody
            Rigidbody hitRigid = hit.collider.attachedRigidbody;

            if (hitRigid != null)
            {
                hitRigid.AddForceAtPosition(BulletImpactForce * MuzzlePointTransform.forward, hit.point);
            }

            // Damage if possible
            Damageable d = hit.collider.GetComponent <Damageable>();

            if (d)
            {
                d.DealDamage(Damage);

                if (onDealtDamageEvent != null)
                {
                    onDealtDamageEvent.Invoke(Damage);
                }
            }

            // Call event
            if (onRaycastHitEvent != null)
            {
                onRaycastHitEvent.Invoke(hit);
            }
        }
示例#2
0
        void DoHitFX(Vector3 pos, Quaternion rot, Collider col)
        {
            // Create FX at impact point / rotation
            if (HitFXPrefab)
            {
                GameObject impact = Instantiate(HitFXPrefab, pos, rot) as GameObject;
                BulletHole hole   = impact.GetComponent <BulletHole>();
                if (hole)
                {
                    hole.TryAttachTo(col);
                }
            }

            // push object if rigidbody
            Rigidbody hitRigid = col.attachedRigidbody;

            if (hitRigid != null)
            {
                hitRigid.AddForceAtPosition(transform.forward * AddRigidForce, pos, ForceMode.VelocityChange);
            }

            // Damage if possible
            Damageable d = col.GetComponent <Damageable>();

            if (d)
            {
                d.DealDamage(Damage);
            }
        }
示例#3
0
        public virtual void OnCollisionEvent(Collision collision)
        {
            // Ignore Triggers
            if (collision.collider.isTrigger)
            {
                return;
            }

            Rigidbody rb = GetComponent <Rigidbody>();

            if (rb && MinForceHit != 0)
            {
                float zVel = System.Math.Abs(transform.InverseTransformDirection(rb.velocity).z);

                // Minimum Force not achieved
                if (zVel < MinForceHit)
                {
                    return;
                }
            }

            Vector3    hitPosition = collision.contacts[0].point;
            Vector3    normal      = collision.contacts[0].normal;
            Quaternion hitNormal   = Quaternion.FromToRotation(Vector3.forward, normal);

            // FX - Particles, Decals, etc.
            DoHitFX(hitPosition, hitNormal, collision.collider);

            // Damage if possible
            Damageable d = collision.collider.GetComponent <Damageable>();

            if (d)
            {
                d.DealDamage(Damage, hitPosition, normal, true, gameObject, collision.collider.gameObject);

                if (onDealtDamageEvent != null)
                {
                    onDealtDamageEvent.Invoke();
                }
            }

            if (StickToObject)
            {
                // tryStickToObject
            }
            else
            {
                // Done with this projectile
                Destroy(this.gameObject);
            }
        }
示例#4
0
        IEnumerator explosionRoutine()
        {
            // Get all objects in explosion radius
            Collider[] colliders = Physics.OverlapSphere(transform.position, ExplosionRadius);

            // First Damage all of the items
            for (int x = 0; x < colliders.Length; x++)
            {
                Collider hit = colliders[x];

                // Apply Damage
                if (ExplosionDamage > 0)
                {
                    Damageable damageable = hit.GetComponent <Damageable>();
                    if (damageable)
                    {
                        if (hit.GetComponent <Explosive>() != null)
                        {
                            // Add slight delay do damaging explosives so everything doesn't go off at once
                            StartCoroutine(dealDelayedDamaged(damageable, 0.1f));
                        }
                        else
                        {
                            damageable.DealDamage(ExplosionDamage);
                        }
                    }
                }
            }


            // Wait a frame so physics can be applied after damaging the items
            yield return(new WaitForFixedUpdate());

            colliders = Physics.OverlapSphere(transform.position, ExplosionRadius);

            // Then Add Physics Force
            for (int x = 0; x < colliders.Length; x++)
            {
                Collider hit = colliders[x];

                Rigidbody rb = hit.GetComponent <Rigidbody>();

                // Add physics force
                if (rb != null)
                {
                    rb.AddExplosionForce(ExplosionForce, transform.position, ExplosionRadius, ExplosiveUpwardsModifier);
                }
            }

            yield return(null);
        }
示例#5
0
        public virtual void OnCollisionEvent(Collision collision)
        {
            LastDamageForce      = collision.impulse.magnitude;
            LastRelativeVelocity = collision.relativeVelocity.magnitude;

            if (LastDamageForce >= MinForce)
            {
                // Can we damage what we hit?
                Damageable d = collision.gameObject.GetComponent <Damageable>();
                if (d)
                {
                    d.DealDamage(Damage);
                }
                // Otherwise, can we take damage ourselves from this collision?
                else if (TakeCollisionDamage && thisDamageable != null)
                {
                    thisDamageable.DealDamage(CollisionDamage);
                }
            }
        }
示例#6
0
        private void OnCollisionEnter(Collision collision)
        {
            // Ignore parent collisions
            if (transform.parent != null && collision.transform == transform.parent)
            {
                return;
            }

            // Don't count collisions if being held
            if (grab != null && grab.BeingHeld)
            {
                return;
            }

            // Don't Count Triggers
            if (collision.collider.isTrigger)
            {
                return;
            }

            string colNameLower = collision.transform.name.ToLower();

            // Ignore other very close bows and arrows
            if (flightTime < 1 && (colNameLower.Contains("arrow") || colNameLower.Contains("bow")))
            {
                Physics.IgnoreCollision(collision.collider, ShaftCollider, true);
                return;
            }

            // ignore player collision if quick shot
            if (flightTime < 1 && collision.transform.name.ToLower().Contains("player"))
            {
                Physics.IgnoreCollision(collision.collider, ShaftCollider, true);
                return;
            }

            // Damage if possible
            float zVel    = System.Math.Abs(transform.InverseTransformDirection(rb.velocity).z);
            bool  doStick = true;

            if (zVel > 0.02f && !rb.isKinematic)
            {
                Damageable d = collision.gameObject.GetComponent <Damageable>();
                if (d)
                {
                    d.DealDamage(arrowDamage, collision.GetContact(0).point, collision.GetContact(0).normal, true, gameObject, collision.collider.gameObject);
                }

                // Don't stick to dead objects
                if (d != null && d.Health <= 0)
                {
                    doStick = false;
                }
            }

            // Check to stick to object
            if (!rb.isKinematic && Flying)
            {
                if (zVel > 0.02f)
                {
                    if (grab != null && grab.BeingHeld)
                    {
                        grab.DropItem(false, false);
                    }
                    if (doStick)
                    {
                        tryStickArrow(collision);
                    }

                    Flying = false;

                    playSoundInterval(2.462f, 2.68f);
                }
            }
        }
示例#7
0
        public virtual void Shoot()
        {
            // Has enough time passed between shots
            float shotInterval = Time.timeScale < 1 ? 0.3f : FiringRate;

            if (Time.time - lastShotTime < shotInterval)
            {
                return;
            }

            // Need to Chamber round into weapon
            if (!BulletInChamber && MustChamberRounds)
            {
                VRUtils.Instance.PlaySpatialClipAt(EmptySound, transform.position, 1f, 0.5f);
                return;
            }

            // Need to release slide
            if (ws != null && ws.LockedBack)
            {
                VRUtils.Instance.PlaySpatialClipAt(EmptySound, transform.position, 1f, 0.5f);
                return;
            }

            // Create our own spatial clip
            VRUtils.Instance.PlaySpatialClipAt(GunShotSound, transform.position, 1f);

            // Haptics
            if (thisGrabber != null)
            {
                input.VibrateController(0.1f, 0.2f, 0.1f, thisGrabber.HandSide);
            }

            // Use projectile if Time has been slowed
            bool useProjectile = Time.timeScale < 1;

            if (useProjectile)
            {
                GameObject projectile      = Instantiate(ProjectilePrefab, MuzzlePointTransform.position, MuzzlePointTransform.rotation) as GameObject;
                Rigidbody  projectileRigid = projectile.GetComponent <Rigidbody>();
                projectileRigid.AddForce(MuzzlePointTransform.forward * ShotForce, ForceMode.VelocityChange);
                Projectile proj = projectile.GetComponent <Projectile>();
                // Convert back to raycast if Time reverts
                if (proj)
                {
                    proj.MarkAsRaycastBullet();
                }

                // Make sure we clean up this projectile
                Destroy(projectile, 20);
            }
            else
            {
                // Raycast to hit
                RaycastHit hit;
                if (Physics.Raycast(MuzzlePointTransform.position, MuzzlePointTransform.forward, out hit, MaxRange, ValidLayers, QueryTriggerInteraction.Ignore))
                {
                    // Particle FX on impact
                    Quaternion decalRotation = Quaternion.FromToRotation(Vector3.forward, hit.normal);
                    GameObject impact        = Instantiate(HitFXPrefab, hit.point, decalRotation) as GameObject;

                    BulletHole hole = impact.GetComponent <BulletHole>();
                    if (hole)
                    {
                        hole.TryAttachTo(hit.collider);
                    }

                    // push object if rigidbody
                    Rigidbody hitRigid = hit.collider.attachedRigidbody;
                    if (hitRigid != null)
                    {
                        float bulletForce = 1000;
                        hitRigid.AddForceAtPosition(bulletForce * MuzzlePointTransform.forward, hit.point);
                    }

                    // Damage if possible
                    Damageable d = hit.collider.GetComponent <Damageable>();
                    if (d)
                    {
                        d.DealDamage(Damage);
                    }
                }
            }

            // Apply recoil
            if (weaponRigid != null && RecoilForce != Vector3.zero)
            {
                weaponRigid.AddForceAtPosition(RecoilForce, MuzzlePointTransform.position, ForceMode.VelocityChange);
            }

            // We just fired this bullet
            BulletInChamber = false;

            // Try to load a new bullet into chamber
            if (AutoChamberRounds)
            {
                chamberRound();
            }
            else
            {
                EmptyBulletInChamber = true;
            }

            // Unable to chamber bullet, force slide back
            if (!BulletInChamber)
            {
                // Do we need to force back the receiver?
                slideForcedBack = ForceSlideBackOnLastShot;

                if (slideForcedBack && ws != null)
                {
                    ws.LockBack();
                }
            }

            // Store our last shot time to be used for rate of fire
            lastShotTime = Time.time;

            // Stop previous routine
            if (shotRoutine != null)
            {
                MuzzleFlashObject.SetActive(false);
                StopCoroutine(shotRoutine);
            }

            if (AutoChamberRounds)
            {
                shotRoutine = animateSlideAndEject();
                StartCoroutine(shotRoutine);
            }
            else
            {
                shotRoutine = doMuzzleFlash();
                StartCoroutine(shotRoutine);
            }
        }
示例#8
0
        IEnumerator dealDelayedDamaged(Damageable damageable, float delayTime)
        {
            yield return(new WaitForSeconds(delayTime));

            damageable.DealDamage(ExplosionDamage);
        }