Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by MartyMcBye · Nov 26, 2019 at 09:32 AM · movementrandomdirection

Need player to walk in random direction

I'm currently working on a 2D project where I need the player to walk in a random direction (up, down, left or right). Whenever you press space, the direction is chosen at random, and the character then moves 10 units in that direction. I've been trying for several hours and with different solutions, but I just can't seem to wrap my head around how to make this work. I would really appreciate any help I can get!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by marcozakaria · Nov 26, 2019 at 10:24 AM

Random.value will get you a random number between 0 and 1 , then you can use this vector and multiple it by 10 then move character to new position

Vector2 randomDirection = new Vector2(Random.value, Random.value);

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by orionsyndrome · Feb 11, 2020 at 01:33 AM

You can think of directions in terms of unit "velocity".

Now bear with me. If I'm moving at 10 km/h, obviously my velocity is 10, and it appears that when I change my direction, my velocity doesn't change or reflect that. By that's a scalar representation of velocity, effectively just a numeric magnitude of it.

If you want to physically implement object velocity, you need to start thinking about it as a measure of positional change.

Now if my whole world is a number line, going at 10 km/h doesn't only capture how quickly my position is changing each hour, but also that I'm moving to the right. Why? Because if we start at the -50 km mark, we'll move to -40, -30, -20, each hour by +10 kms, and soon enough we'll start moving on the positive side of the number line.

Likewise, if you want to move to the left, you need to go at -10 km/h. (Here I'm just assuming that negative numbers go to the left and positive to the right, by common convention.)

Now, what's up with the "unit velocity", you might ask. Well, when we're talking about the direction we don't care that much about the magnitude of the velocity, we just care about the sign. A unit velocity is basically what you need to multiply your colloquial speed factor with, in order to get a working measure of positional change.

If you want to move to the left, your unit velocity is -1, and conversely, +1 for the right direction.

Now, because your problem is in two dimensions, you need two coordinates for your position, and that means that your direction also need two signs.

If you're moving to the top-right, your unit velocity is [+1, +1], and if you're moving to the bottom-left, it's [-1, -1]. Additionally, if you want to move along cardinal axes, you simply disregard a speed factor that would move you away from it. For example, moving to the right changes the X value, but not the Y, so the unit velocity is [+1, 0].

Now you can simply multiply these coordinates with any speed factor to get a proper directional velocity: 10 * [+1, 0] will get you [10, 0] and 25 * [-1, -1] will get you [-25, -25]

No let's consider also that I have simplified this greatly and that there is a problem with these 2D unit velocities -- namely, they aren't completely unit. Unit velocities need to be normalized to be called that, because what they represent should always have a magnitude of exactly 1.

Think of a square 1 m in width and height. If your unit velocity can be [-1, 0] that means you can draw an arrow starting from the center of this square, and pointing to the left. It has a magnitude of exactly 1. But if you have a velocity of [-1, -1], this arrow will point to the lower left corner of the square, and because it's a square diagonal its magnitude is slightly bigger (square-root-of-two bigger, or around +41.5%). In layman terms, you'd move ~41.5% faster diagonally even though your speed factor hasn't changed.

Thus, a unit velocity is always normalized. It's magnitude has to end up being exactly 1. Once you have this, you can multiply it with your speed factor, and you're ready to go. You can represent a 2D direction with a Vector2.

To come up with a random direction, you can simply randomize the two signs, or pick a random angle. Because Random.value returns a number between 0 and 1, you can multiply it by 2 and reduce by 1, to get it in the range -1 and +1. To snap the values to exactly -1 or +1, you can use Mathf.Sign function.

 float minusOrPlusOne() {
   return Mathf.Sign(Random.value * 2f - 1f);
 }

 float speedFactor = 10f;

 // if we use the normalized property, the resulting vector will be proportionally scaled
 // so that its magnitude is exactly 1, solving the requirement of what means to be a 'unit'
 Vector2 direction = new Vector2(minusOrPlusOne(), minusOrPlusOne()).normalized;

 // now it's just the matter of scaling up this vector by our scalar speed factor
 Vector2 finalVelocity = speedFactor * direction;

 // finally, we can apply this velocity to the object's world position
 // obviously, this needs to go in the Update method, because it should change every frame
 Vector2 newPosition = someObject.transform.position + finalVelocity * Time.deltaTime;
 someObject.transform.position = newPosition;

This is simple enough, however, this direction vector will also contain diagonals, which is undesirable.

If we remove the diagonals, there are only 4 remaining cardinal directions. We could get a random integer, and get a hardcoded direction that corresponds to this value.

 int choice = Random.Range(0, 4); // means we'll get 0, 1, 2, or 3 (4 is exclusive)
 float speedFactor = 10f;
 Vector2 direction = Vector2.zero;

 // here our directions are already normalized by hand, and thus 'unit'
 switch(choice) {
   case 1: direction = new Vector2(0f, 1f); break;
   case 2: direction = new Vector2(-1f, 0f); break;
   case 3: direction = new Vector2(0f, -1f); break;

   // switch clause needs a default case anyway, so let's make it our case 0
   default: direction = new Vector2(1f, 0f); break;
 }

 Vector2 finalVelocity = speedFactor * direction;

Here's also a generalized version of obtaining a completely random direction, for the reference

 Vector2 CalculateUnitDirection(float angleInDegrees) {
   // we need this conversion for the sine and cosine below to work properly
   float angleInRadians = angleInDegrees * Mathf.Deg2Rad;
   Vector2 direction = new Vector2(Mathf.Cos(angleInRadians), Mathf.Sin(angleInRadians));
   return direction.normalized;
 }

 float angle = Random.Range(0f, 360f); // this variant of Random.Range has inclusive maximum
 float speedFactor = 10f;
 Vector2 direction = CalculateUnitDirection(angle);
 Vector2 finalVelocity = speedFactor * direction;

Alternatively, we could also constrain this general form to get only cardinal directions

 float angle = Random.Range(0, 4) * 90f; // do you see what we did here?
 float speedFactor = 10f;
 Vector2 direction = CalculateUnitDirection(angle);
 Vector2 finalVelocity = speedFactor * direction;

I hope this helps you or anyone else starting out with these basic concepts.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image orionsyndrome · Feb 11, 2020 at 01:45 AM 0
Share

to understand more about the unit vectors and why I had to use trigonometry (and the subsequent relationship between the sine, the cosine, and the angle of direction), and how it all relates to Cartesian coordinates, google up 'unit circle'

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

180 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Random movement direction cycle. 2 Answers

random direction of enemy when collide whit wall 1 Answer

Tracking HTC Vive Controller Motion Direction? 1 Answer

Get which way the player is moving from character controller.move 2 Answers

How can I move an object to click point in 2D? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges