Fur-War/Assets/Scripts/EnemyController.cs
Gerard Gascón 3b4c6e0ec6 init
2025-04-24 17:29:51 +02:00

307 lines
12 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour {
[SerializeField, Range(0, 2)] int angryLevel = 0;
[SerializeField] float[] speedLevels = new float[3];
[SerializeField] SkinnedMeshRenderer meshRenderer = default;
[SerializeField] Animator enemyAnimator = default;
[Space]
[SerializeField] Material defaultMat = default;
[SerializeField] Material angryMat = default;
[SerializeField] Material reallyAngryMat = default;
[SerializeField] Material defaultAttackMat = default;
[SerializeField] Material angryAttackMat = default;
[SerializeField] Material reallyAngryAttackMat = default;
[Space]
[SerializeField] float speed = 5f;
[HideInInspector] public Vector3 directionLooking = Vector3.forward;
[SerializeField, Range(0, .2f)] float rotationTime = .1f;
[HideInInspector] public float targetAngle;
float rotationVelocity;
[SerializeField] LayerMask whatIsWall = -1;
Vector3 currentPosition;
List<Vector3> possiblePositions;
List<Vector3> availablePositions;
[HideInInspector] public Vector3 positionToGo;
Transform player;
bool dead;
[HideInInspector] public bool canMove;
GameController gameController;
void Awake(){
PlayerController playerController = FindObjectOfType<PlayerController>();
player = playerController.transform;
playerController.onDie.AddListener(() => OnPlayerDie());
gameController = FindObjectOfType<GameController>();
}
void Start(){
positionToGo = currentPosition = transform.position;
speed = speedLevels[angryLevel];
}
public void OnPlayerDie(){
positionToGo = currentPosition = transform.position;
switch (angryLevel){
case 0:
meshRenderer.material = defaultMat;
break;
case 1:
meshRenderer.material = angryMat;
break;
case 2:
meshRenderer.material = reallyAngryMat;
break;
}
}
public void EnterRespawn(){
switch (angryLevel){
case 0:
angryLevel = 1;
break;
case 1:
angryLevel = 2;
break;
}
switch (angryLevel){
case 0:
meshRenderer.material = defaultMat;
break;
case 1:
meshRenderer.material = angryMat;
break;
case 2:
meshRenderer.material = reallyAngryMat;
break;
}
}
public void Respawn(){
positionToGo = currentPosition = transform.position;
dead = false;
speed = speedLevels[angryLevel];
}
// Update is called once per frame
void Update(){
enemyAnimator.SetBool("Attacking", !dead && canMove);
if (!dead && canMove){
switch (angryLevel){
case 0:
meshRenderer.material = defaultAttackMat;
break;
case 1:
meshRenderer.material = angryAttackMat;
break;
case 2:
meshRenderer.material = reallyAngryAttackMat;
break;
}
if (transform.position == positionToGo){
CalculateDirection();
}
transform.position = Vector3.MoveTowards(transform.position, new Vector3(positionToGo.x, transform.position.y, positionToGo.z), speed * Time.deltaTime);
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref rotationVelocity, rotationTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
}
else{
}
}
void CalculateDirection(){
currentPosition = transform.position;
possiblePositions = new List<Vector3>();
Vector3 forward = Vector3.forward;
Vector3 back = Vector3.back;
Vector3 left = Vector3.left;
Vector3 right = Vector3.right;
if (forward == -directionLooking){
possiblePositions.Add(Vector3.back);
possiblePositions.Add(Vector3.left);
possiblePositions.Add(Vector3.right);
}else if (back == -directionLooking){
possiblePositions.Add(Vector3.forward);
possiblePositions.Add(Vector3.left);
possiblePositions.Add(Vector3.right);
}else if (left == -directionLooking){
possiblePositions.Add(Vector3.back);
possiblePositions.Add(Vector3.forward);
possiblePositions.Add(Vector3.right);
}else if (right == -directionLooking){
possiblePositions.Add(Vector3.back);
possiblePositions.Add(Vector3.left);
possiblePositions.Add(Vector3.forward);
}
availablePositions = new List<Vector3>();
foreach(Vector3 pos in possiblePositions){
if(directionLooking == Vector3.forward || directionLooking == Vector3.back){
if(pos == Vector3.right){
if(player.position.x > transform.position.x){
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}else{
if (!Physics.CheckSphere(transform.position + directionLooking, .3f, whatIsWall)){
availablePositions.Add(directionLooking);
}else{
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}
}
}else if(pos == Vector3.left){
if (player.position.x < transform.position.x){
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}else{
if (!Physics.CheckSphere(transform.position + directionLooking, .3f, whatIsWall)){
availablePositions.Add(directionLooking);
}else{
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}
}
}else{
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}
}else{
if (pos == Vector3.forward){
if (player.position.z > transform.position.z){
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}else{
if (!Physics.CheckSphere(transform.position + directionLooking, .3f, whatIsWall)){
availablePositions.Add(directionLooking);
}else{
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}
}
}else if (pos == Vector3.back){
if (player.position.z < transform.position.z){
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}else{
if (!Physics.CheckSphere(transform.position + directionLooking, .3f, whatIsWall)){
availablePositions.Add(directionLooking);
}else{
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}
}
}else{
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}
}
}
/*if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
availablePositions.Add(pos);
}*/
}
float nearestDist = float.MaxValue;
Vector3 nearestPos = new Vector3();
foreach (Vector3 v in availablePositions){
if (v != Vector3.zero){
float dist = Vector3.Distance(currentPosition + v, player.position);
if (dist < nearestDist){
nearestDist = dist;
nearestPos = currentPosition + v;
}
}
}
if(nearestPos - currentPosition == Vector3.left){
targetAngle = Mathf.Atan2(-1, 0) * Mathf.Rad2Deg;
}else if (nearestPos - currentPosition == Vector3.right){
targetAngle = Mathf.Atan2(1, 0) * Mathf.Rad2Deg;
}else if (nearestPos - currentPosition == Vector3.forward){
targetAngle = Mathf.Atan2(0, 1) * Mathf.Rad2Deg;
}else if (nearestPos - currentPosition == Vector3.back){
targetAngle = Mathf.Atan2(0, -1) * Mathf.Rad2Deg;
}
directionLooking = nearestPos - currentPosition;
positionToGo = nearestPos;
}
void OnDrawGizmos(){
Vector3 forward = Vector3.forward;
Vector3 back = Vector3.back;
Vector3 left = Vector3.left;
Vector3 right = Vector3.right;
if(forward == -directionLooking){
Gizmos.color = Color.blue;
Gizmos.DrawSphere(transform.position + Vector3.forward, .15f);
Gizmos.color = Color.red;
Gizmos.DrawSphere(transform.position + Vector3.back, .15f);
Gizmos.DrawSphere(transform.position + Vector3.left, .15f);
Gizmos.DrawSphere(transform.position + Vector3.right, .15f);
}else if(back == -directionLooking){
Gizmos.color = Color.blue;
Gizmos.DrawSphere(transform.position + Vector3.back, .15f);
Gizmos.color = Color.red;
Gizmos.DrawSphere(transform.position + Vector3.forward, .15f);
Gizmos.DrawSphere(transform.position + Vector3.left, .15f);
Gizmos.DrawSphere(transform.position + Vector3.right, .15f);
}else if (left == -directionLooking){
Gizmos.color = Color.blue;
Gizmos.DrawSphere(transform.position + Vector3.left, .15f);
Gizmos.color = Color.red;
Gizmos.DrawSphere(transform.position + Vector3.back, .15f);
Gizmos.DrawSphere(transform.position + Vector3.forward, .15f);
Gizmos.DrawSphere(transform.position + Vector3.right, .15f);
}else if (right == -directionLooking){
Gizmos.color = Color.blue;
Gizmos.DrawSphere(transform.position + Vector3.right, .15f);
Gizmos.color = Color.red;
Gizmos.DrawSphere(transform.position + Vector3.back, .15f);
Gizmos.DrawSphere(transform.position + Vector3.left, .15f);
Gizmos.DrawSphere(transform.position + Vector3.forward, .15f);
}
}
void OnTriggerEnter(Collider col){
if(col.gameObject.tag == "Explosion"){
AudioManager.instance.PlayOneShot("EnemyDeath");
GameOverCanvas.instance.enemiesKilled++;
dead = true;
canMove = false;
gameController.EnemyDeath(this);
}
}
}