using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
public class ActionWander : FSMAction
{
[Header(“Config”)]
[SerializeField] private float enemyMovementSpeed;
[SerializeField] private Vector2 moveRange;
[SerializeField] private EnemyVisual enemyVisual;
[SerializeField] private LayerMask obstacles;
private Vector3 movePosition;
private Rigidbody2D rb;
private CircleCollider2D circleCollider;
private RaycastHit2D raycastDownXLeft;
private RaycastHit2D raycastUpXLeft;
private RaycastHit2D raycastDownXRight;
private RaycastHit2D raycastUpXRight;
private RaycastHit2D raycastLeftYDown;
private RaycastHit2D raycastRightYDown;
private RaycastHit2D raycastLeftYUp;
private RaycastHit2D raycastRightYUp;
private Vector3 movement;
private Vector3 moveDirection;
private float wanderTime;
Vector3 positionAfterCollision;
private float timer;
float randomX;
float randomY;
private bool directionLeft;
private bool collided;
private bool directionUp;
private bool isWalking;
void Awake()
{
collided = false;
rb = GetComponent();
circleCollider = GetComponent();
isWalking = false;
}
void Start()
{
GetNewDestination();
}
void Update()
{
}
//Reffers to Finite State Machine
public override void Act()
{
timer -= Time.deltaTime;
moveDirection = (movePosition - transform.position).normalized;
movement = moveDirection * (enemyMovementSpeed * Time.deltaTime);
if (Vector3.Distance(transform.position, movePosition) >= 0.2f)
{
isWalking = true;
rb.MovePosition(Vector3.MoveTowards(transform.position, movePosition, 0.1f));
}
else
{
isWalking = false;
}
if (timer <= 0f)
{
GetNewDestination();
timer = Random.Range(1f, 5f);
}
enemyVisual.SetWalkingAnimation(isWalking);
}
//Getting new random Dest, when the timer is 0
private void GetNewDestination()
{
randomX = Random.Range(-moveRange.x+0.5f, moveRange.x-0.5f);
if (randomX >= 0)
{
randomX += 0.5f;
}
else
{
randomX -= 0.5f;
}
randomY = Random.Range(-moveRange.y + 0.5f, moveRange.y - 0.5f);
if (randomY >= 0)
{
randomY += 0.5f;
}
else
{
randomY -= 0.5f;
}
//if the enemies are hitting the obstacles, they go away from the obcstacle
//2 raycast per side - because if it is cast just in the middle, sometimes the middle ray is not enough for “if fit in there”
raycastDownXLeft = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y - 0.3f), Vector2.left, 2f, obstacles);
raycastUpXLeft = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y + 0.3f), Vector2.left, 2f, obstacles);
raycastDownXRight = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y - 0.3f), Vector2.right, 2f, obstacles);
raycastUpXRight = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y + 0.3f), Vector2.right, 2f, obstacles);
raycastLeftYUp = Physics2D.Raycast(new Vector2(transform.position.x - 0.3f, transform.position.y), Vector2.up, 2f, obstacles);
raycastRightYUp = Physics2D.Raycast(new Vector2(transform.position.x + 0.3f, transform.position.y), Vector2.up, 2f, obstacles);
raycastLeftYDown = Physics2D.Raycast(new Vector2(transform.position.x - 0.3f, transform.position.y), Vector2.down, 2f, obstacles);
raycastRightYDown = Physics2D.Raycast(new Vector2(transform.position.x + 0.3f, transform.position.y), Vector2.down, 2f, obstacles);
bool hitDownXLeft = raycastDownXLeft;
bool hitUpXLeft = raycastUpXLeft;
if (hitUpXLeft || hitDownXLeft)
{
randomX = ChangeXPositionToRight();
Debug.Log(“HITUJE LEFT”);
}
bool hitDownXRight = raycastDownXRight;
bool hitUpXRight = raycastUpXRight;
if (hitDownXRight || hitUpXRight)
{
randomX = ChangeXPositionToleft();
Debug.Log(“HITUJE RIGHT”);
}
bool hitLeftYUp = raycastLeftYUp;
bool hitRightYUp = raycastRightYUp;
if (hitLeftYUp || hitRightYUp)
{
randomY = ChangeYPositionToDown();
Debug.Log(“HITUJE UP”);
}
bool hitLeftYDown = raycastLeftYDown;
bool hitRightYDown = raycastRightYDown;
if (hitLeftYDown || hitRightYDown)
{
randomY = ChangeYPositionToUp();
Debug.Log(“HITUJE DOWN”);
}
//if obstacle is on LEFT and RIGHT, just move only up and down
if (hitDownXLeft && hitDownXRight || hitUpXLeft && hitUpXRight)
{
randomX = 0;
}
//if obstacles is on UP and DOWN, just move only left and right
if (hitLeftYDown && hitLeftYUp || hitRightYDown && hitRightYUp)
{
randomY = 0;
}
movePosition = transform.position + new Vector3(randomX, randomY);
}
//if obstacles is on left, change to right
private float ChangeXPositionToRight()
{
// Debug.Log(“CHANGE TO RIGHT”);
directionLeft = false;
float changeXRightPosition = Random.Range(0.5f, moveRange.x);
return changeXRightPosition;
}
//if obstacles is on right, change to left
private float ChangeXPositionToleft()
{
// Debug.Log(“CHANGE TO LEFT”);
directionLeft = true;
float changeXLeftPosition = Random.Range(-moveRange.x, -0.5f);
return changeXLeftPosition;
}
//if obstacles is on up, change to down
private float ChangeYPositionToDown()
{
// Debug.Log(“CHANGE TO DOWN”);
directionUp = false;
float changeYDownPosition = Random.Range(-moveRange.y, -0.5f);
return changeYDownPosition;
}
//if obstacles is on down, change to up
private float ChangeYPositionToUp()
{
// Debug.Log(“CHANGE TO UP”);
directionUp = true;
float changeYUpPosition = Random.Range(0.5f, moveRange.y);
return changeYUpPosition;
}
private void OnDrawGizmosSelected()
{
if (moveRange != Vector2.zero)
{
Gizmos.color = Color.black;
Gizmos.DrawWireCube(transform.position, moveRange * 2f);
Gizmos.DrawLine(transform.position, movePosition);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
moveDirection = transform.position;
isWalking = false;
}
}
my answer is - How it could be in better, clean and more professional way?
Another thing, I am trying 2 day make enemy stop moving when they hit the obstacle, because now they are stucking and try to move into the obstacles…
I tried make rb.MovePosition, didnt work, I tried make if finalDestination is in obstacle, it doesnt run. But it would be soo hard because I have to make refenreces of every object? I can do the animation - isWalking true/false. and if they hit the obstacle, they change the animation… But I cant figure out how to stop moving. If I use collidersEnter, when the enemy hit the obstacle, it will always oncollided, so it never move again… Thank you:)