random range to pick from two specific numbers only.
Hello
I have a game object that turns right when collided with a blocking object. Instead I want the game object to randomly go either 90 degrees right or -90 degrees left.
Here is a portion of my code that communicates with a trigger script(checks for collisions). This code works but only turns 90 right.
// Turn if collided with wall
else if (frontTrigger.colliding){
yDir = 90;
StartCoroutine (Move ("turn"));
}
This is the code I tried to create for random range: //This code does not work
// Turn if collided with wall
int[] randomYDir = new int[2] { 90, -90 };
int yDir = randomYDir[Random.Range(0, randomYDir.Length)];
print(yDir);
rotatePos = "straight";
StartCoroutine (Move ("turn"));
}
When my game object collides nothing happens. 'print(yDir)' does correctly read as 90 or -90:
but by the time it gets to the print in my Coroutine below it does not have the correct value of 90 or -90.
case "turn":
thisTransform.Rotate(new Vector3(0,yDir,zDir));
print ("new Random value for yDIR =" + yDir);
break;
Why does my 'yDir' in my Coroutine not read asthe assigned value from my Random Range code?
I fixed the problem. The new random.range code is below:
else if (frontBorderTrigger.frontColliding && bottomTrigger.colliding){
int[] randomYDir = new int[2] { 90, -90 };
yDir = randomYDir[Random.Range(0, randomYDir.Length)];
print(yDir);
StartCoroutine ($$anonymous$$ove ("turn"));
}
How I fixed it: I deleted the 'int' in front of 'yDir' because I already declared it as 'internal int yDir; at the begining of my script.
Answer by GiyomuGames · Aug 06, 2015 at 04:57 AM
I think you got your problem sorted out, but just in case you could also use:
yDir = Random.Range(0, 2) == 0 ? -90 : 90;
I feel it's a bit simpler.
Thanks for the code. This works as well. I have not yet used a question mark in my code. Can you explain the '==?' so I can understand how this line of code works.
For anyone else viewing this, here is the code from Guidanel combined with what I have:
else if (frontBorderTrigger.frontColliding && bottomTrigger.colliding){
yDir = Random.Range(0, 2) == 0 ? -90 : 90;
print(yDir);
StartCoroutine ($$anonymous$$ove ("turn"));
}
Hey :) If(a) then b else c is equivalent to a ? b : c So it's convenient for some simple things like your case, but you should avoid it for too complicated if/else cases.
@r_chevalliar, I think you are not aware of ternary operator, It's a photocopy of 'if..else' statement. Don't make simple things harder. ! You can use simple if..else statement, ins$$anonymous$$d of ternary operator.
Btw for your reference, see this: ternary operator
Answer by agentperrys · Aug 06, 2015 at 03:30 AM
you could try something like this to choose if its -90 or 90 rotation(its in javascript):
//this picks a number between 1 and 2
var rand = random.Range(1,3);
if (rand == 1) {
randomYDir = 90;
else if (rand == 2) {
randomYDir = -90;
}
Thanks for your responce. This seems like it would work too. I am already using to many if and else if's though.
Answer by stepan-stulov · Aug 06, 2015 at 12:38 PM
If you want a more general solution to this problem, the topic of research will be biased/weighed randomization. The idea is assigning weights to the elements of a list and then picking an element from that list based on the probabilities proportional to those weights. In your case you'd have a list of turning angle values 90 and -90 with equal weights (1 and 1, or 50 and 50, up to your taste). But in this simple case it's an overkill of course.
Otherwise you can always do
float angle = Random.Range(0.0F, 1.0F) < 0.5F ? 90.0F : -90.0F;
Mathf.Random produces a uniform distribution of floats in the [0; 1] range, so comparing that value against the middle 0.5 in the long run will produce equal chances for both turns. In fact you can than vary the division points, set it to 0.3F for instance. Then your probabilities will be 30% for one turn and 70% for another. In fact this is a special case of biased/weighted randomizaiton, only the number of elements is strictly two.
Here is what I mean:
float leftTurnWeight = 30.0F;
float leftTurnAngle = -90.0F;
float rightTurnWeight = 70.0F;
float rightTurnAngle = 90.0F;
float probabilityMiddlePoint = leftTurnWeight / (leftTurnWeight + rightTurnWeight);
float turnAngle = Random.Range(0.0F, 1.0F) < probabilityMiddlePoint ? leftTurnAngle : rightTurnAngle;
No you're welcome to play with weights. Make sure weights are always greater than zero. I picked the weights be kind of like percents, but you can do anything, they don't have to sum up to 1.0F, or 100% or anything.
Your answer
Follow this Question
Related Questions
the floats wont be applied, Random.Range 1 Answer
C# Random Int: How to force Even or odd number 6 Answers
Hello, Need help with a problem 1 Answer