0
\$\begingroup\$

I'm very new to C# scripting.

I want to use a random velocity for my Enemies using Vector2. Here's the code that I have done at the moment:

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

public class Enemy1 : MonoBehaviour
{
    [SerializeField]
    Rigidbody2D rb2d;

    [SerializeField]
    Vector2 vectorEnemysVelocity;

    [SerializeField]
    gameManager gameManager;

    [SerializeField]
    AudioSource source;

    [SerializeField]
    AudioClip deathSound;


    private void Awake()
    {
        gameManager = FindObjectOfType<gameManager>();
    }

    void Start()
    {
        MoveEnemy();
    }      

    void MoveEnemy()
    {
        rb2d.velocity = vectorEnemysVelocity;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.layer == 8)
        {
            gameManager.GenerateGameOver();
            source.PlayOneShot(deathSound, 1f);
        }
        
        if (collision.gameObject.layer == 9)
        {
            Destroy(gameObject);
        }
    }
}

With this I can choose the velocity but as I said earlier I want it to be random. How can I do this?

\$\endgroup\$
4
2
\$\begingroup\$

There is always more than one way on how to do it.

https://docs.unity3d.com/ScriptReference/Random.Range.html

This gives you a random value between your given min and max value. Gives you a lot of control and is easy to understand.

float minValue = 0f;
float maxValue = 10f;
Vector2 randomVector = new Vector2(Random.Range(minValue, maxValue), Random.Range(minValue, maxValue));

Another method (credit to DMGregory) is https://docs.unity3d.com/ScriptReference/Random-insideUnitCircle.html which gives you directly a Vector2.

float maxValue = 10f;
Vector2 randomVector = Random.insideUnitCircle * maxValue;
Debug.Log(randomVector);
\$\endgroup\$
1
  • \$\begingroup\$ Note that the first method gives you a vector inside a square, and the second gives you a vector inside a disc. With the second option, you control the maximum length of the vector (speed) directly, and it's the same in all directions. With the first method, diagonal vectors are allowed to be √2 times longer (faster) than the max value you input, so you can go different speeds in different directions. The first method with the numbers given also never generates velocities pointing down or to the left. \$\endgroup\$
    – DMGregory
    Jan 2 at 12:49
0
\$\begingroup\$

Another approach is generate a random vector in polar coordinates, and convert it to cartesian coordinates:

public Vector2 InCircle(float radius) 
{
    // Generate random vector in polar coordinates
    var radius = Random.Range(0f, radius);
    var angle = Random.Range(0f, 2f * Mathf.PI);

    // Convert to cartesian coordinates
    var x = radius * Mathf.Cos(angle);
    var y = radius * Mathf.Sin(angle);

    return new Vector2(x, y);
}

I have a Unity library with UPM support called Eflatun.RandomUtils that has a bunch of useful RNG utility methods, and one of them covers your case, called InCircle:

// using Eflatun.RandomUtils;

var rng = new BetterRandom();
var result = rng.Vector2.InCircle(radius);
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Note that the polar version you've shown here is biased toward choosing vectors near the center of the circle. That may be desirable for some circumstances (eg. having an equal probability of any speed in the range), but I wanted to mention it because it may not be obvious from the code alone for folks unfamiliar with random sampling. The version in the external link corrects for this by adding a square root to the radius. \$\endgroup\$
    – DMGregory
    Jan 3 at 14:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.