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 possiblePositions; List availablePositions; [HideInInspector] public Vector3 positionToGo; Transform player; bool dead; [HideInInspector] public bool canMove; GameController gameController; void Awake(){ PlayerController playerController = FindObjectOfType(); player = playerController.transform; playerController.onDie.AddListener(() => OnPlayerDie()); gameController = FindObjectOfType(); } 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 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(); 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); } } }