示例#1
0
        /// <summary>
        /// Applies force and damage to objects hit by attacks.
        /// </summary>
        protected virtual IEnumerator Attack()
        {
            m_NexAttackTime = Time.time + m_AttackRate;

            // Wait 0.1 seconds before applying damage/force.
            yield return(new WaitForSeconds(0.1f));

            Vector3 direction = m_CameraTransformReference.TransformDirection(Vector3.forward);
            Vector3 origin    = m_CameraTransformReference.transform.position;

            Ray ray = new Ray(origin, direction);

            if (Physics.Raycast(ray, out RaycastHit hitInfo, m_Range, m_AffectedLayers, QueryTriggerInteraction.Collide))
            {
                m_ArmsAnimator.Hit(hitInfo.point);

                // If hit a rigidbody applies force to push.
                Rigidbody rigidBody = hitInfo.collider.GetComponent <Rigidbody>();
                if (rigidBody)
                {
                    rigidBody.AddForce(direction * m_Force, ForceMode.Impulse);
                }

                if (hitInfo.transform.root != transform.root)
                {
                    IProjectileDamageable damageableTarget = hitInfo.collider.GetComponent <IProjectileDamageable>();
                    damageableTarget?.ProjectileDamage(UnityEngine.Random.Range(m_Damage.x, m_Damage.y), transform.root.position, hitInfo.point, 0);
                }
            }
        }
示例#2
0
        protected virtual void Penetrate(RaycastHit lastHitInfo, Vector3 direction, SurfaceIdentifier surf, float range, float damage)
        {
            Ray ray = new Ray(lastHitInfo.point + direction * 0.1f, direction);

            int affectedObjectID = lastHitInfo.collider.GetInstanceID();

            if (Physics.Raycast(ray, out RaycastHit hitInfo, range, m_GunData.AffectedLayers, QueryTriggerInteraction.Collide))
            {
                // Get the surface type of the object.
                SurfaceIdentifier newSurf = hitInfo.collider.GetSurface();

                // Exit hole
                Ray exitRay = new Ray(hitInfo.point, direction * -1);

                if (Physics.Raycast(exitRay, out RaycastHit exitInfo, range, m_GunData.AffectedLayers, QueryTriggerInteraction.Collide))
                {
                    float distanceTraveled = Vector3.Distance(lastHitInfo.point, exitInfo.point) * surf.Density(lastHitInfo.triangleIndex);

                    // Does the bullet gets through?
                    if (m_GunData.PenetrationPower > distanceTraveled)
                    {
                        if (newSurf)
                        {
                            BulletDecalsManager.Instance.CreateBulletDecal(newSurf, hitInfo);
                        }

                        if (affectedObjectID == exitInfo.collider.GetInstanceID())
                        {
                            BulletDecalsManager.Instance.CreateBulletDecal(surf, exitInfo);
                        }

                        // If hit a rigid body applies force to push.
                        Rigidbody rigidBody = hitInfo.collider.GetComponent <Rigidbody>();
                        if (rigidBody)
                        {
                            rigidBody.AddForce(direction * m_GunData.Force, ForceMode.Impulse);
                        }

                        if (hitInfo.transform.root != transform.root)
                        {
                            IProjectileDamageable damageableTarget = hitInfo.collider.GetComponent <IProjectileDamageable>();
                            damageableTarget?.ProjectileDamage(damage * (distanceTraveled / m_GunData.PenetrationPower), transform.root.position, exitInfo.point, m_GunData.PenetrationPower - distanceTraveled);
                        }
                    }
                }
            }
示例#3
0
        protected virtual void Shot()
        {
            Vector3 direction = m_CameraTransformReference.TransformDirection(m_NextShootDirection);
            Vector3 origin    = m_CameraTransformReference.transform.position;

            Ray ray = new Ray(origin, direction);

            float tracerDuration = m_GunEffects.TracerDuration;

            if (Physics.Raycast(ray, out RaycastHit hitInfo, m_GunData.Range, m_GunData.AffectedLayers, QueryTriggerInteraction.Collide))
            {
                SurfaceIdentifier surf   = hitInfo.collider.GetSurface();
                float             damage = m_GunData.DamageType == GunData.DamageMode.Constant ? m_GunData.Damage
                    : m_GunData.Damage * m_GunData.DamageFalloffCurve.Evaluate(hitInfo.distance / m_GunData.Range);

                if (surf)
                {
                    BulletDecalsManager.Instance.CreateBulletDecal(surf, hitInfo);

                    if (m_GunData.PenetrateObjects && surf.CanPenetrate(hitInfo.triangleIndex))
                    {
                        Penetrate(hitInfo, direction, surf, m_GunData.Range - hitInfo.distance, damage);
                    }
                }

                // If hit a rigid body applies force to push.
                Rigidbody rigidBody = hitInfo.collider.GetComponent <Rigidbody>();
                if (rigidBody)
                {
                    rigidBody.AddForce(direction * m_GunData.Force, ForceMode.Impulse);
                }

                if (hitInfo.transform.root != transform.root)
                {
                    IProjectileDamageable damageableTarget = hitInfo.collider.GetComponent <IProjectileDamageable>();
                    damageableTarget?.ProjectileDamage(damage, transform.root.position, hitInfo.point, m_GunData.PenetrationPower);
                }

                tracerDuration = hitInfo.distance / m_GunEffects.TracerSpeed;
            }

            if (tracerDuration > 0.05f)
            {
                m_GunEffects.CreateTracer(transform, direction, tracerDuration);
            }
        }