- Home /
Simple AI random roaming
Hey everyone. I am working on a procedural 2d dungeon crawler and am currently trying to set up an AI random roaming mechanic for my enemy prefabs.
Currently the script basically picks a random number (random.range 0 - 4) and assigns a direction based on the number returned. it then does a raycasthit2d line cast to determine what is in the space it is moving into. once it determines it is ok to move into said space it then should move there however it will not currently complete the transform.position portion after determining the direction nor will it properly complete the yield return new after the random number generation so currently it calls the function on every frame. despite it calling on every frame however it still will not actually change the gameobject's transform.
Here is the script in full for the sake of testing:
using System.Collections;
using UnityEngine;
public class EnemyAI : MonoBehaviour {
RaycastHit2D hit;
RaycastHit2D player;
public LayerMask blockingLayer;
public LayerMask playerLayer;
public Vector2 start;
public Vector2 end;
public Vector2 moveDirection;
public int moveNumber;
public bool canMove;
void Start()
{
canMove = true;
}
void Move()
{
if (canMove == true)
{
StartCoroutine(Mover());
canMove = true;
}
}
IEnumerator Mover()
{
moveNumber = Random.Range(0, 4);
if (moveNumber == 0)//Up
{
moveDirection = new Vector2(transform.position.x, transform.position.y + 1);
start = transform.position;
end = (start + moveDirection);
this.GetComponent<BoxCollider2D>().enabled = false;
hit = Physics2D.Linecast(start, end, blockingLayer); //Stores the results of the RayCastHit2D between the start Vector2 and end Vector2 ie. did it hit anything on the attempted move path.
player = Physics2D.Linecast(start, end, playerLayer);
this.GetComponent<BoxCollider2D>().enabled = true;
if (hit.transform == null)
{
gameObject.transform.position = (start + moveDirection);
canMove = false;
yield return new WaitForSecondsRealtime(1f);
}
}
if (moveNumber == 1)//Down
{
moveDirection = new Vector2(transform.position.x, transform.position.y - 1);
start = transform.position;
end = (start + moveDirection);
this.GetComponent<BoxCollider2D>().enabled = false;
hit = Physics2D.Linecast(start, end, blockingLayer); //Stores the results of the RayCastHit2D between the start Vector2 and end Vector2 ie. did it hit anything on the attempted move path.
player = Physics2D.Linecast(start, end, playerLayer);
this.GetComponent<BoxCollider2D>().enabled = true;
if (hit.transform == null )
{
gameObject.transform.position = (start + moveDirection);
canMove = false;
yield return new WaitForSecondsRealtime(1f);
}
}
if (moveNumber == 2)//Right
{
moveDirection = new Vector2(transform.position.x + 1, transform.position.y);
start = transform.position;
end = (start + moveDirection);
this.GetComponent<BoxCollider2D>().enabled = false;
hit = Physics2D.Linecast(start, end, blockingLayer); //Stores the results of the RayCastHit2D between the start Vector2 and end Vector2 ie. did it hit anything on the attempted move path.
player = Physics2D.Linecast(start, end, playerLayer);
this.GetComponent<BoxCollider2D>().enabled = true;
if (hit.transform == null )
{
gameObject.transform.position = (start + moveDirection);
canMove = false;
yield return new WaitForSecondsRealtime(1f);
}
}
if (moveNumber == 3)//Left
{
moveDirection = new Vector2(transform.position.x - 1, transform.position.y);
start = transform.position;
end = (start + moveDirection);
this.GetComponent<BoxCollider2D>().enabled = false;
hit = Physics2D.Linecast(start, end, blockingLayer); //Stores the results of the RayCastHit2D between the start Vector2 and end Vector2 ie. did it hit anything on the attempted move path.
player = Physics2D.Linecast(start, end, playerLayer);
this.GetComponent<BoxCollider2D>().enabled = true;
if (hit.transform == null )
{
gameObject.transform.position = (start + moveDirection);
canMove = false;
yield return new WaitForSecondsRealtime(1f);
}
}
}
void Update()
{
Move();
}
}
What is the question? And have you tried debugging the issue? For example, using Debug.Log()
just before/after changing the position?
Also, the 4 directions only differ in moveDirection
, the rest of the code is the same, so you could factor out the part after assigning the moveDirection
(every time you copy-paste large parts of code, you can refactor). Something like this:
moveNumber = Random.Range(0, 4);
switch (moveNumber) { // this is the same as a lot of if-else-ifs
case 0: moveDirection = new Vector2(transform.position.x, transform.position.y + 1); break;
case 1: moveDirection = new Vector2(transform.position.x, transform.position.y - 1); break;
case 2: moveDirection = new Vector2(transform.position.x + 1, transform.position.y); break;
case 3: moveDirection = new Vector2(transform.position.x - 1, transform.position.y); break;
default: moveDirection = new Vector2(transform.position.x, transform.position.y); break; // do not move
}
start = transform.position;
end = (start + moveDirection);
this.GetComponent<BoxCollider2D>().enabled = false;
hit = Physics2D.Linecast(start, end, blockingLayer); //Stores the results of the RayCastHit2D between the start Vector2 and end Vector2 ie. did it hit anything on the attempted move path.
player = Physics2D.Linecast(start, end, playerLayer);
this.GetComponent<BoxCollider2D>().enabled = true;
if (hit.transform == null) {
gameObject.transform.position = (start + moveDirection);
can$$anonymous$$ove = false;
yield return new WaitForSecondsRealtime(1f);
}
Answer by KittenSnipes · May 16, 2018 at 10:16 AM
if (hit.transform == null )
I think maybe none of your movements are made because maybe the raycast hit the ground or some other object that is not actually in the way and therefore not null so maybe the if statement is never true. I am not absolutely sure but I suggest trying another way like:
if (hit.transform.tag == “ground” || hit.transform == null)
{
//Do stuff
}
Answer by unity_BGmJcdED5Dqjfw · May 16, 2018 at 09:15 PM
Turns out it was a combination of things. The RaycastHit was causing some trouble but also I was setting the transform incorrectly. After fixing the RaycastHit and making the transform just equal the moveDirection rather than the (start + moveDirection) the rest worked fine. Thanks though!
Your answer
Follow this Question
Related Questions
Trouble with Moving an Enemy back and forth 1 Answer
Fill an object's (probably mesh colliders) inside with smaller objects evenly 1 Answer
Help with 2d enemy ai 0 Answers
I am making a 2d game and I want to make it where to can pick up bricks with your mouse 3 Answers
object pauses at the each way points for a vary short time 1 Answer