コード例 #1
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);
                }
            }
        }
コード例 #2
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);
            }
        }
コード例 #3
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);
                }
            }
        }
コード例 #4
0
        IEnumerator dealDelayedDamaged(Damageable damageable, float delayTime)
        {
            yield return(new WaitForSeconds(delayTime));

            damageable.DealDamage(ExplosionDamage);
        }