using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.VFX; using Random = UnityEngine.Random; public class ProjectileBase : MonoBehaviour { protected Rigidbody rb; private TrailRenderer bulletTracer; [SerializeField] private float thrust = 10f; protected const string DECAL_COUNT = "DecalCount"; protected const string WATER_IMPACT = "Water_Impact"; protected const string HIT_EFFECT = "HitEffect"; protected const string ENEMY_TAG = "Enemy"; protected const string WATER_SPLASH = "Bullet_Water_Splash"; private void Awake() { rb = GetComponent(); bulletTracer = GetComponent(); } private void Start() { if (bulletTracer != null) bulletTracer.Clear(); rb.collisionDetectionMode = CollisionDetectionMode.Continuous; rb.useGravity = false; } private void OnDisable() { transform.rotation = Quaternion.identity; transform.position = Vector3.zero; if (bulletTracer != null) bulletTracer.Clear(); if (rb) { rb.velocity = Vector3.zero; rb.angularVelocity = Vector3.zero; rb.Sleep(); } } public void ApplyForce(Vector3 direction) { rb.AddForce(direction * thrust, ForceMode.Impulse); transform.rotation = Quaternion.LookRotation(direction); OnForce(); } protected virtual void OnForce(){} protected virtual void OnHitEntity(Collision col) { //spawn hit effect only if we didnt hit enemy if (col.gameObject.layer != LayerMask.NameToLayer(ENEMY_TAG)) { Vector3 normal = col.GetContact(0).normal; Vector3 contactPosition = col.GetContact(0).point + normal * 0.25f; GameObject hitEffect = NetworkPooler.Instance.PooledPlayEffect(HIT_EFFECT, contactPosition, Quaternion.identity, 4.0f); hitEffect.transform.up = normal; HitEffectShadows(hitEffect); } PooledDestroy(); } protected void HitEffectShadows(GameObject hitEffect) { VisualEffect hitVFX = hitEffect.GetComponent(); hitVFX.SetInt(DECAL_COUNT, 1); if (hitEffect.transform.position.y <= Client.WATER_HEIGHT) { hitVFX.SetInt(DECAL_COUNT, 0); } } private void OnTriggerEnter(Collider other) { if (other.CompareTag("Water")) { float randPitch = Random.Range(0.85f, 1.5f); Vector3 closestPointToTrigger = other.ClosestPoint(transform.position); AudioManager.Instance.playSound3D(WATER_SPLASH, closestPointToTrigger, randPitch); NetworkPooler.Instance.PooledPlayEffect(WATER_IMPACT, closestPointToTrigger, Quaternion.identity, 2.5f); } } protected virtual void PooledDestroy() { string baseName = NetworkPooler.GetBaseName(transform.name); NetworkPooler.Instance.PooledDestroy(baseName, gameObject); } private void OnCollisionEnter(Collision col) => OnHitEntity(col); }