/// <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); } } }
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); } } } }
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); } }