Moving an item in a random direction for a random amount of time

hi guys

I really thought i would be able to do this, but i been battling.

trying to get these two lines:

Vector2 randomDir = new Vector2(Random.Range(-1f, 1f), Random.Range(-1f, 1f));
rb.MovePosition(rb.position + randomDir * speed * Time.fixedDeltaTime);

to move my object in a random direction for a random time.

i know what has to happen.
choose a random direction, then keep going for x amount of time, rinse and repeat.

but no matter what im trying my object just doesnt move.

but i feel like im missing a process here on how to keep my object moving.

any help appreciated

here is my code so far:

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

public class RoundUFO : MonoBehaviour
{
    public Rigidbody2D rb;
    public Vector2 direction;
    public float speed;
    public Transform player;
    public GameObject roundUFOExplodes;
    public GameObject roundUFOTorpedo;
    public float shootingDelay; //time between shots in seconds
    public float lastTimeShot = 0;
    public float torpedoSpeed;
    public int shields = 10;
    private float randomDistance;
    private float dist;
    public GameObject laserHits;
    public int points;
    private bool followingPlayer = false;
    private float nextUpdateAt = -999f;
    private bool moveRandomly;
    private Vector2 randomDir;

    // Start is called before the first frame update
    void Start()
    {
        player = GameObject.FindWithTag ("Player").transform;
        randomDistance = Random.Range(5, 20);
    }

    // Update is called once per frame
    void Update()
    {
       
        Shooting();
       
    }
    
    private void FixedUpdate()
    {
        Vector2 randomDir = new Vector2(Random.Range(-1f, 1f), Random.Range(-1f, 1f));

        if (followingPlayer)
        {
            //Debug.Log("Follow");
            //figure out which way to move to approach the player
            direction = (player.position - transform.position).normalized;
            rb.MovePosition(rb.position + direction * speed * Time.fixedDeltaTime);
        }
            else
        {
            //Debug.Log("patrol");
            if (Time.time > nextUpdateAt)
            {
                nextUpdateAt = Time.time + Random.Range(1f, 5f);

                rb.MovePosition(rb.position + randomDir * speed * Time.fixedDeltaTime);
            }

           
           
        }
    }

    private void OnCollisionEnter2D(Collision2D collider)
    {
        if (collider.gameObject.tag == "Player")
        {
            DestroyRoundUFO();
        }
    }

    void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "LaserRed")
        {
            FindObjectOfType<AudioManager>().Play("LaserHit");
            Instantiate(laserHits, transform.position, transform.rotation);
            Destroy(collision.gameObject);
            shields--;
            if (shields <= 0)
            {
                DestroyRoundUFO();
            }
        }
    }

    public void DestroyRoundUFO()
    {
        player.SendMessage("ScorePoints", points);
        FindObjectOfType<AudioManager>().Play("PlayerShipExplodes");
        Instantiate(roundUFOExplodes, transform.position, transform.rotation);
        Destroy(gameObject);
    }

    public void Shooting()
    {
        dist = Vector3.Distance(player.transform.position, gameObject.transform.position);
        
        if (dist < randomDistance)
        {
            followingPlayer = true;
            if (Time.time > lastTimeShot + shootingDelay)
            {
                lastTimeShot = Time.time;
                float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg - 90f;
                Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
                GameObject newBullet = Instantiate(roundUFOTorpedo, transform.position, q);
                newBullet.GetComponent<Rigidbody2D>().AddRelativeForce(new Vector2(0f, torpedoSpeed));
                FindObjectOfType<AudioManager>().Play("RoundUFOTorpedo");
                lastTimeShot = Time.time;
                Destroy(newBullet, 5);
            }
        }
            else
        {
            followingPlayer = false;
        }
          
    }
}

LOL this is what i needed to do:

Vector2 thrust = new Vector2(Random.Range(-maxThrust, maxThrust), (Random.Range(-maxThrust, maxThrust)));
rb.velocity(thrust);

1 Like

So happy epoch then?

if not, another thing to check I thought of was, is your rigidbody “snagged” on a collider, or marked as isKinematic.

Yes its working great! my UFO is flying randomly around, then gives chase to the player at random distances.
what are you currently working on? By the way i downloaded your 2d game pack, the arcade one. Amazing stuff!! i cant imagine how long that took you.

1 Like

This is something that just doesn’t happen enough today. It has been days since I saw a UFO flying around randomly outside my house!

Still funning around with Jetpack Kurt… latest heavy turbulence video here, super dicey landings at the end:

https://www.youtube.com/watch?v=Y6KTDq7ZJnI

Cool! Thanks! If you’re talking about KurtMaster2D that actually has games I worked on in high school, back in 1984, still running intepreted on there. I managed to hang onto the original source code, plus all my MS-DOS and PalmOS games are in there too. I dig up and add more to that collection all the time.

Building back onto the original question of UFO movement, that type of move-then-do “AI” can really be written simply as coroutines, or sets of coroutines.

Basically each coroutine runs and when it finishes it goes into a function to see what’s next:

Let’s say 2 coroutines:

1 move a few units randomly for 1 second

2 fire at the player for 1 second

Easiest is to just alternate: move, fire, move, fire, move, fire

Next mix up timing: make 1 second be random(0.8f to 1.5f) seconds

Next might be: randomly choose move or fire, and it could be maybe 75% move, 25% fire

And very simply you can layer on elemental chunks of behavior and make pretty interesting stuff.

If you couple that decision point with extra logic like “when the player is close, really start blasting at him more rather than moving”, you can quickly end up with pretty interesting stuff for remarkably little effort.

1 Like