Reviewed-on: #16 Reviewed-by: EliaGingras1 <william-gin1@hotmail.com> Co-authored-by: Adam Salah <adam-hamid.salah-salah.1@ens.etsmtl.ca> Co-committed-by: Adam Salah <adam-hamid.salah-salah.1@ens.etsmtl.ca>
93 lines
3.2 KiB
C#
93 lines
3.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
public class MultiEyedOpponent : Opponent
|
|
{
|
|
[SerializeField]
|
|
private float _eyeMaxDistance = 2.0f;
|
|
[SerializeField]
|
|
private float _eyeSpeed = 3.0f;
|
|
[SerializeField]
|
|
private GameObject[] _eyes;
|
|
|
|
private int _eyeLossHpInterval;
|
|
private List<GameObject> _remainingEyes = new List<GameObject>();
|
|
|
|
// tuple: (eye instance, start position, distance to end of arc, point to stop mid arc, start angle, modulated speed)
|
|
private List<(GameObject eye ,float startX, float distance, float destination, float angle, float speed)> _dyingEyes =
|
|
new List<(GameObject eye, float startX, float distance, float destination, float angle, float speed)>();
|
|
|
|
public override void Start()
|
|
{
|
|
base.Start();
|
|
|
|
_remainingEyes.AddRange(_eyes);
|
|
_eyeLossHpInterval = Hp / _eyes.Length;
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
base.Update();
|
|
|
|
// Check if Hp threshold for eye loss is reached
|
|
if (_remainingEyes.Count > Hp / _eyeLossHpInterval)
|
|
{
|
|
int i = Random.Range(0, _remainingEyes.Count);
|
|
var removedEye = _remainingEyes[i];
|
|
|
|
var dyingEye = Instantiate(removedEye, transform);
|
|
|
|
// Render in front of units
|
|
var renderer = dyingEye.GetComponent<SpriteRenderer>();
|
|
renderer.sortingLayerName = "Unit";
|
|
renderer.sortingOrder = 100;
|
|
|
|
// Setup launch params
|
|
float startX = dyingEye.transform.position.x;
|
|
float distance = Mathf.Sign(Random.Range(-1.0f, 1.0f)) * Random.Range(_eyeMaxDistance / 5, _eyeMaxDistance);
|
|
float destination = Random.Range(distance / 2, distance);
|
|
float angle = Random.Range(30.0f, 80.0f);
|
|
float speed = Mathf.Sqrt(90 * 90 - angle * angle) / 90 * _eyeSpeed;
|
|
_dyingEyes.Add((dyingEye, startX, distance, destination, angle, speed));
|
|
|
|
// Remove from remaining eyes
|
|
_remainingEyes.RemoveAt(i);
|
|
removedEye.SetActive(false);
|
|
}
|
|
|
|
// Update dying eyes position
|
|
foreach (var entry in _dyingEyes)
|
|
{
|
|
var eye = entry.eye;
|
|
if (!eye) continue;
|
|
|
|
// Get tuple launch params
|
|
float startX = entry.startX;
|
|
float distance = entry.distance;
|
|
float destination = entry.destination;
|
|
float angle = entry.angle;
|
|
float speed = entry.speed;
|
|
|
|
// Arc function
|
|
float k = Mathf.Sign(distance) * Mathf.Tan(angle * Mathf.Deg2Rad);
|
|
float a = -1.0f / distance;
|
|
float x = (eye.transform.position.x - startX) + Mathf.Sign(distance) * speed * Time.deltaTime;
|
|
float y = k * (a * x * x + x);
|
|
|
|
// Check if reached destination
|
|
if (Mathf.Abs(x) > Mathf.Abs(destination))
|
|
{
|
|
eye.GetComponent<Animator>().SetTrigger("Destroy");
|
|
continue;
|
|
}
|
|
|
|
// Apply movement if not in destruction animation
|
|
Vector2 newPos = new Vector2(startX + x, transform.position.y + y);
|
|
eye.transform.position = newPos;
|
|
}
|
|
}
|
|
}
|