Advertisement
Learning000001

Untitled

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