using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class Projectile : MonoBehaviour { [SerializeField] private Detection _detectionLinked; [SerializeField] private bool straightProjectile = false; private float _time = 0f; private float _duration = 1f; [SerializeField] private float _angle = 10f; //Default [SerializeField] private float _speed = 2f; //Default private Vector2 _vectorStart; private Vector2 _vectorEnd; private int _damage; private float _enemySpeed; private Entity _target; private Rigidbody2D _rigidbodyProjectile; private float _initialX; private float _initialY; private float _destinationX; private float _destinationY; private float _enemyPosY = 0f; private float _speedTime = 0f; private float _initialXDistance; private float _initialYDistance; private void Start() { _rigidbodyProjectile = GetComponent(); _initialX = transform.position.x; _initialY = transform.position.y; _destinationX = _vectorEnd.x - _initialX - _enemySpeed; _destinationY = _vectorEnd.y - _initialY; _detectionLinked.gameObject.GetComponent().EntityLinked = _target; _detectionLinked.gameObject.GetComponent().ProjectileDamage = _damage; _initialXDistance = Mathf.Abs(_initialX - _destinationX); _initialYDistance = Mathf.Abs(_initialY - _destinationY); } private void Update() { if (straightProjectile) { transform.position = Vector2.Lerp(new Vector2(_initialX, _initialY), new Vector2(_vectorEnd.x, _vectorEnd.y), _time / _duration); DetStraigthArrowAngle(); //TODO: Implementer cette methode pour mieux faire fonctionner le projectile lorsque possible. //transform.LookAt(VectorEnd, Vector3.forward); _time += Time.deltaTime; if (transform.position.x >= _vectorEnd.x) { ApplyEffects(); Destroy(this.gameObject); } return; } float x = _speedTime; float y = (_angle * -Mathf.Pow(x, 2) + _destinationX * x); transform.position = new Vector2(_initialX + x * _angle, _initialY + y); // Move projectile angle according to distance with target float lerpStep = (_destinationX - transform.position.x) / _initialXDistance; float angle = Mathf.Lerp(-100f, 45f, lerpStep); transform.eulerAngles = new Vector3(0, 0, angle); _speedTime += _speed * Time.deltaTime; if (y < 0) { Destroy(this.gameObject); } } protected virtual void DetStraigthArrowAngle() { if (_target != null) _enemyPosY = _target.Position.y; float angleX = (_destinationX) / _initialXDistance; float angleY = (_destinationY) / _initialYDistance; //Obtenir la difference entre la position Y du chateau et de l'ennemie. float diffY = transform.position.y - _enemyPosY; //D'abord,on regarde si l'ennemi et l'unite sont a la meme hauteur. //Si ce n'est pas le cas, on modifie l'angle de la fleche. Sinon, on ne change rien. if (diffY >= 0.1 || diffY <= -0.1) { float lerpStepS; //Ensuite, on regarde la position entre l'ennemi et l'unite. //Si cette distance est plus petite qu'un certain nombre, on utilise un calcul differents //pour determine l'angle que la fleche doit prendre. if (angleX > 0.23) lerpStepS = Mathf.Rad2Deg * Mathf.Atan(angleX / angleY); //Si la position est negative, on utilise un calcul different pour determiner l'angle. //(Il faudra tester si ca marche lorsque le chateau pourrait tirer en arriere). else if (angleX >= 0) lerpStepS = Mathf.Rad2Deg * Mathf.Atan(angleY / angleX); //Calcul utilise pour tenter de mieux faire fonctionner l'angle de la fleche lorsque l'ennemi est //proche de l'unite. else { lerpStepS = -Mathf.Rad2Deg * Mathf.Atan(angleY / angleX); } float angleS = Mathf.Lerp(lerpStepS, 0, 0); transform.eulerAngles = new Vector3(0, 0, angleS); } } // applies effects on hit protected virtual void ApplyEffects() { } //Getter and Setter public float EnemySpeed { get { return _enemySpeed; } set { _enemySpeed = value; } } public float Angle { get { return _angle; } set { _angle = value; } } public float Speed { get { return _speed; } set { _speed = value; } } public int Damage { get { return _damage; } set { _damage = value; } } public Vector2 VectorStart { get { return _vectorStart; } set { _vectorStart = value; } } public Vector2 VectorEnd { get { return _vectorEnd; } set { _vectorEnd = value; } } public Entity Target { get { return _target; } set { _target = value; } } }