Skip to main content
Don't repeat tags in the title - describe the problem not just the vague topic area
Source Link
DMGregory
  • 136.3k
  • 22
  • 247
  • 373

Unity: Enemy movement, Platformer enemy with RayCast detectionraycast to detect obstacles keeps changing direction rapidly

I am making a 2D platform and implementing a character similar to a Mario Goomba. This character will move left or right, depending on whether or not a raycast determines that there is an object in front of it.

Currently there are 2 RayCasts, originating from the center of the sprite, on for left-side detection, and one for right. This script checks for a hit from either, and if a hit is detected it changes the moveDirection, and flips the sprite. The code works, however the character sprite will sporadically flip countless times, sometimes getting stuck. There seems to be no set trigger for it, as it appears to occur at random intervals. This leads me to believe that there is some issue with its layout in the code, however no combination of putting it in Update()Update(), LateUpdate()LateUpdate(), or FixedUpdate()FixedUpdate() really changes anything.

This is the script I created:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SimpleEnemyMovement : MonoBehaviour
{
private Rigidbody2D enemyRb;
private SpriteRenderer spriteRen;
[SerializeField] private float moveDirection;
[SerializeField] private bool turnAround;

[SerializeField] float movementSpeed;
[SerializeField] float rayLength;
[SerializeField] int layerMask;

// Start is called before the first frame update
void Start()
{
    enemyRb = GetComponent<Rigidbody2D>();   
    spriteRen = GetComponent<SpriteRenderer>();
    moveDirection = 1;
}

// Update is called once per frame
void Update()
{

    
    transform.position = transform.position + new Vector3(moveDirection * movementSpeed * Time.deltaTime, 0, 0);

    
}

private void FixedUpdate()
{
    PatrolLogicController();
}
    



private void PatrolLogicController()
{

    RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right, rayLength, layerMask);
    Debug.DrawRay(transform.position, Vector2.right * rayLength, Color.green);
    RaycastHit2D hit2 = Physics2D.Raycast(transform.position, Vector2.left, rayLength, layerMask);
    Debug.DrawRay(transform.position, Vector2.left * rayLength, Color.green);
    
    if(hit || hit2)
    {
        turnAround = !turnAround;
    }



    if (turnAround == false)
    {
        spriteRen.flipX = false;
        moveDirection = 1;
    }
    
    if (turnAround == true)
    {
        spriteRen.flipX = true;
        moveDirection = -1;
    }
}

}

This is the character, and a representation of it's rays in relation to its body and BoxCollider2D.

Unity: Enemy movement, with RayCast detection

I am making a 2D platform and implementing a character similar to a Mario Goomba. This character will move left or right, depending on whether or not a raycast determines that there is an object in front of it.

Currently there are 2 RayCasts, originating from the center of the sprite, on for left-side detection, and one for right. This script checks for a hit from either, and if a hit is detected it changes the moveDirection, and flips the sprite. The code works, however the character sprite will sporadically flip countless times, sometimes getting stuck. There seems to be no set trigger for it, as it appears to occur at random intervals. This leads me to believe that there is some issue with its layout in the code, however no combination of putting it in Update(), LateUpdate(), or FixedUpdate() really changes anything.

This is the script I created:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SimpleEnemyMovement : MonoBehaviour
{
private Rigidbody2D enemyRb;
private SpriteRenderer spriteRen;
[SerializeField] private float moveDirection;
[SerializeField] private bool turnAround;

[SerializeField] float movementSpeed;
[SerializeField] float rayLength;
[SerializeField] int layerMask;

// Start is called before the first frame update
void Start()
{
    enemyRb = GetComponent<Rigidbody2D>();   
    spriteRen = GetComponent<SpriteRenderer>();
    moveDirection = 1;
}

// Update is called once per frame
void Update()
{

    
    transform.position = transform.position + new Vector3(moveDirection * movementSpeed * Time.deltaTime, 0, 0);

    
}

private void FixedUpdate()
{
    PatrolLogicController();
}
    



private void PatrolLogicController()
{

    RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right, rayLength, layerMask);
    Debug.DrawRay(transform.position, Vector2.right * rayLength, Color.green);
    RaycastHit2D hit2 = Physics2D.Raycast(transform.position, Vector2.left, rayLength, layerMask);
    Debug.DrawRay(transform.position, Vector2.left * rayLength, Color.green);
    
    if(hit || hit2)
    {
        turnAround = !turnAround;
    }



    if (turnAround == false)
    {
        spriteRen.flipX = false;
        moveDirection = 1;
    }
    
    if (turnAround == true)
    {
        spriteRen.flipX = true;
        moveDirection = -1;
    }
}

}

This is the character, and a representation of it's rays in relation to its body and BoxCollider2D.

Platformer enemy with raycast to detect obstacles keeps changing direction rapidly

I am making a 2D platform and implementing a character similar to a Mario Goomba. This character will move left or right, depending on whether or not a raycast determines that there is an object in front of it.

Currently there are 2 RayCasts, originating from the center of the sprite, on for left-side detection, and one for right. This script checks for a hit from either, and if a hit is detected it changes the moveDirection, and flips the sprite. The code works, however the character sprite will sporadically flip countless times, sometimes getting stuck. There seems to be no set trigger for it, as it appears to occur at random intervals. This leads me to believe that there is some issue with its layout in the code, however no combination of putting it in Update(), LateUpdate(), or FixedUpdate() really changes anything.

This is the script I created:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SimpleEnemyMovement : MonoBehaviour
{
private Rigidbody2D enemyRb;
private SpriteRenderer spriteRen;
[SerializeField] private float moveDirection;
[SerializeField] private bool turnAround;

[SerializeField] float movementSpeed;
[SerializeField] float rayLength;
[SerializeField] int layerMask;

// Start is called before the first frame update
void Start()
{
    enemyRb = GetComponent<Rigidbody2D>();   
    spriteRen = GetComponent<SpriteRenderer>();
    moveDirection = 1;
}

// Update is called once per frame
void Update()
{

    
    transform.position = transform.position + new Vector3(moveDirection * movementSpeed * Time.deltaTime, 0, 0);

    
}

private void FixedUpdate()
{
    PatrolLogicController();
}
    



private void PatrolLogicController()
{

    RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right, rayLength, layerMask);
    Debug.DrawRay(transform.position, Vector2.right * rayLength, Color.green);
    RaycastHit2D hit2 = Physics2D.Raycast(transform.position, Vector2.left, rayLength, layerMask);
    Debug.DrawRay(transform.position, Vector2.left * rayLength, Color.green);
    
    if(hit || hit2)
    {
        turnAround = !turnAround;
    }



    if (turnAround == false)
    {
        spriteRen.flipX = false;
        moveDirection = 1;
    }
    
    if (turnAround == true)
    {
        spriteRen.flipX = true;
        moveDirection = -1;
    }
}

}

This is the character, and a representation of it's rays in relation to its body and BoxCollider2D.

Source Link
TBG
  • 25
  • 5

Unity: Enemy movement, with RayCast detection

I am making a 2D platform and implementing a character similar to a Mario Goomba. This character will move left or right, depending on whether or not a raycast determines that there is an object in front of it.

Currently there are 2 RayCasts, originating from the center of the sprite, on for left-side detection, and one for right. This script checks for a hit from either, and if a hit is detected it changes the moveDirection, and flips the sprite. The code works, however the character sprite will sporadically flip countless times, sometimes getting stuck. There seems to be no set trigger for it, as it appears to occur at random intervals. This leads me to believe that there is some issue with its layout in the code, however no combination of putting it in Update(), LateUpdate(), or FixedUpdate() really changes anything.

This is the script I created:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SimpleEnemyMovement : MonoBehaviour
{
private Rigidbody2D enemyRb;
private SpriteRenderer spriteRen;
[SerializeField] private float moveDirection;
[SerializeField] private bool turnAround;

[SerializeField] float movementSpeed;
[SerializeField] float rayLength;
[SerializeField] int layerMask;

// Start is called before the first frame update
void Start()
{
    enemyRb = GetComponent<Rigidbody2D>();   
    spriteRen = GetComponent<SpriteRenderer>();
    moveDirection = 1;
}

// Update is called once per frame
void Update()
{

    
    transform.position = transform.position + new Vector3(moveDirection * movementSpeed * Time.deltaTime, 0, 0);

    
}

private void FixedUpdate()
{
    PatrolLogicController();
}
    



private void PatrolLogicController()
{

    RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right, rayLength, layerMask);
    Debug.DrawRay(transform.position, Vector2.right * rayLength, Color.green);
    RaycastHit2D hit2 = Physics2D.Raycast(transform.position, Vector2.left, rayLength, layerMask);
    Debug.DrawRay(transform.position, Vector2.left * rayLength, Color.green);
    
    if(hit || hit2)
    {
        turnAround = !turnAround;
    }



    if (turnAround == false)
    {
        spriteRen.flipX = false;
        moveDirection = 1;
    }
    
    if (turnAround == true)
    {
        spriteRen.flipX = true;
        moveDirection = -1;
    }
}

}

This is the character, and a representation of it's rays in relation to its body and BoxCollider2D.