Advertisement
Learning000001

Untitled

Jan 2nd, 2024
1,050
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.31 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3.  
  4. public class Bullet : MonoBehaviour
  5. {
  6.     private const int RAYCAST_MAX_DISTANCE = int.MaxValue;
  7.     private const float SPEED = 20f;
  8.  
  9.     [SerializeField] private int amountOfBounces;
  10.     [HideInInspector] public float aliveTime;
  11.     private float aliveTempTime;
  12.     private bool canDestroy;
  13.     public GameObject impactEffect;
  14.  
  15.     private GameObject previousCollisionObject;
  16.     private int maxBounces;
  17.     private Vector3 currentDirection;
  18.  
  19.     private void Start()
  20.     {
  21.         maxBounces = amountOfBounces;
  22.         aliveTempTime = aliveTime;
  23.         currentDirection = transform.up.normalized;
  24.     }
  25.  
  26.     private void Update()
  27.     {
  28.         HandleTimer();
  29.     }
  30.    
  31.     private void HandleTimer()
  32.     {
  33.         if (aliveTempTime < 0)
  34.         {
  35.             return;
  36.         }
  37.  
  38.         aliveTempTime -= Time.deltaTime;
  39.         if (aliveTempTime <= 0)
  40.         {
  41.             canDestroy = true;
  42.         }
  43.     }
  44.  
  45.     private void FixedUpdate()
  46.     {
  47.         MoveTowardsPathPoint();
  48.     }
  49.  
  50.     private void MoveTowardsPathPoint()
  51.     {
  52.         BulletPath _target = GetNextTarget(previousCollisionObject);
  53.  
  54.         if (_target == default)
  55.         {
  56.             Destroy(gameObject);
  57.             return;
  58.         }
  59.  
  60.         MoveTowardsTarget(_target);
  61.  
  62.         if (!DidReachTarget(_target))
  63.         {
  64.             return;
  65.         }
  66.  
  67.         HandleCollisionAndReflection(_target);
  68.         InstantiateImpactEffect();
  69.         CheckDestroyConditions();
  70.     }
  71.  
  72.     private void MoveTowardsTarget(BulletPath _target)
  73.     {
  74.         Transform _bulletTransform = transform;
  75.         _bulletTransform.position = Vector3.MoveTowards(_bulletTransform.position, _target.ImpactPoint, SPEED * Time.deltaTime);
  76.     }
  77.  
  78.     private bool DidReachTarget(BulletPath _target)
  79.     {
  80.         return Vector3.Distance(transform.position, _target.ImpactPoint) < 0.01f;
  81.     }
  82.  
  83.     private void HandleCollisionAndReflection(BulletPath _target)
  84.     {
  85.         Transform _bulletTransform = transform;
  86.         currentDirection = HandleRaycastHit(currentDirection, _target.RaycastHit2D);
  87.         _bulletTransform.up = currentDirection;
  88.         previousCollisionObject = _target.Collider;
  89.         amountOfBounces--;
  90.     }
  91.  
  92.     private void InstantiateImpactEffect()
  93.     {
  94.         if (impactEffect == null)
  95.         {
  96.             return;
  97.         }
  98.         GameObject _impact = Instantiate(impactEffect);
  99.         _impact.transform.position = transform.position;
  100.         Destroy(_impact, 1f);
  101.     }
  102.  
  103.     private void CheckDestroyConditions()
  104.     {
  105.         if (canDestroy || amountOfBounces == 0)
  106.         {
  107.             Destroy(gameObject);
  108.         }
  109.     }
  110.  
  111.     private BulletPath GetNextTarget(GameObject _ignoreObject)
  112.     {
  113.         var _bulletTransform = transform;
  114.         Vector2 _startingPosition = _bulletTransform.position;
  115.         Vector2 _direction = _bulletTransform.up.normalized;
  116.         List<BulletPath> _path = GetPath(_startingPosition, _direction, maxBounces, _ignoreObject);
  117.  
  118.         return _path != default && _path.Count > 0 ? _path[0] : default;
  119.     }
  120.  
  121.     public static List<BulletPath> GetPath(Vector2 _startingPosition, Vector2 _direction, int _bouncesLeft, GameObject _currentObject)
  122.     {
  123.         List<BulletPath> _path = new List<BulletPath>();
  124.         AddPoint(_startingPosition, _direction, _bouncesLeft, _currentObject, _path);
  125.         return _path;
  126.     }
  127.  
  128.     private static void AddPoint(Vector2 _startingPosition, Vector2 _direction, int _bouncesLeft, GameObject _currentObject, List<BulletPath> _path)
  129.     {
  130.         while (true)
  131.         {
  132.             RaycastHit2D _validHit = GetValidHit(_startingPosition, _direction, _currentObject);
  133.  
  134.             if (_validHit == default)
  135.             {
  136.                 return;
  137.             }
  138.  
  139.             Vector2 _newStartingPosition = _validHit.point;
  140.             Vector2 _newDirection = HandleRaycastHit(_direction, _validHit);
  141.             _bouncesLeft--;
  142.  
  143.             _path.Add(new BulletPath { ImpactPoint = _newStartingPosition, Collider = _validHit.transform.gameObject, RaycastHit2D = _validHit });
  144.  
  145.             if (_bouncesLeft <= 0)
  146.             {
  147.                 return;
  148.             }
  149.  
  150.             _startingPosition = _newStartingPosition;
  151.             _direction = _newDirection;
  152.             _currentObject = _validHit.transform.gameObject;
  153.         }
  154.     }
  155.  
  156.     private static RaycastHit2D GetValidHit(Vector2 _startingPosition, Vector2 _direction, GameObject _currentObject)
  157.     {
  158.         RaycastHit2D[] _hits = Physics2D.RaycastAll(_startingPosition, _direction, RAYCAST_MAX_DISTANCE);
  159.  
  160.         foreach (RaycastHit2D _hit in _hits)
  161.         {
  162.             GameObject _hitObject = _hit.transform.gameObject;
  163.  
  164.             if (!_hitObject.CompareTag("Wall") && !_hitObject.CompareTag("Ground"))
  165.             {
  166.                 continue;
  167.             }
  168.  
  169.             if (_hitObject == _currentObject)
  170.             {
  171.                 continue;
  172.             }
  173.  
  174.             return _hit;
  175.         }
  176.  
  177.         return default;
  178.     }
  179.  
  180.     private static Vector3 HandleRaycastHit(Vector3 _currentDirection, RaycastHit2D _hit)
  181.     {
  182.         Vector2 _wallNormal = _hit.normal;
  183.         return Vector2.Reflect(_currentDirection, _wallNormal).normalized;
  184.     }
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement