- Home /
Raycast direction problem
Hi!
I am trying to get mye raycast to change its direction.
Vector 3 direction = transform.forward;
direction.x += (Random.value - 0.5f) * spread;
direction.y += (Random.value - 0.5f) * spread;
direction.z += (Random.value - 0.5f) * spread;
The problem is that when the transform is looking at an axis, it adds the spread to 0 (if its pointing at the Y axis, Y is zero so it will do 0 += (Random.value - 0.5f) * spread;), so it will raycast in a straight line, instead of all directions.
Does anyone know how I can fix this?
EDIT
bulletDirection = barrelEnd.forward;
bulletDirection.x += (Random.value - 0.5f) * shotSpread;
bulletDirection.y += (Random.value - 0.5f) * shotSpread;
bulletDirection.z += 0f;
shotSpread += spreadAmt;
Is the code for the bulletDirection and this is how I cast the ray:
Physics.Raycast (Camera.main.transform.position, bulletDirection, out info, Mathf.Infinity, shootmask)
What happens:
Looking downwards (staright at an axis)
Looking at an angle
What I am trying to make happen:
For the bulletDirection to change so that I can get bullet spread like a real gun (like in image 2), just independant from looking at an axis or not.
$$anonymous$$ight help if you described what you want to happen. For example, do you want to raycast the way something is facing, but with a small random change (like ai$$anonymous$$g from a bumpy ride)?
You may be using direction incorrectly. For example, direction ignores distance, so spread
doesn't do anything. Rolling (1,0,2) and (4,0,8) are the same. They both look north-north-east.
I have edited my question with more info.
No not like a shotgun, but just like a normal gun :)
Answer by robertbu · Jul 26, 2013 at 02:20 PM
If you are looking to make a spread like for a shotgun, here is one link:
http://answers.unity3d.com/questions/492916/shotgun-bullet-spread.html
No, not a shotgun, but like a normal gun:
Shotgun or normal gun, what you want to do is introduce some variance so that two shots pointed in the same direction don't go to exactly the same place. Here is the code from the post I directed you to:
function Spread(aim : Vector3, distance: float, variance : float) : Vector3 {
aim.Normalize();
var v3 : Vector3;
do {
v3 = Random.insideUnitSphere;
} while (v3 == aim || v3 == -aim);
v3 = Vector3.Cross(aim, v3);
v3 = v3 * Random.Range(0.0, variance);
return aim * distance + v3;
}
Your 'aim' is your barrelEnd.forward, fill your distance and variance with how much change you want at a specified distance. That is, at the specified distance the vector will point at a position that is no more than variance from a perfect shot. And it does not matter what direction you are facing.
Oh! Thank you so much! Don't know why I didn't look at your link before. I translated it to C# and now it is working perfectly. Thanks again!
Answer by Owen-Reynolds · Jul 26, 2013 at 06:22 PM
To sum up your idea, the "perfect" shot flies along the blue "forward" line coming out of the barrel. To get some spread, move the tip of that line a little bit left/right and up/down. That method does work, and is nice since it's very easy to visualize.
The trick is moving the barrel's left/right (the formal term is Local Coords.) Changing x will move left/right only if you're facing north. If you're facing East, then changing x just moves it closer/further.
The standard Unity way to move left/right is transform.right
(which is your red/x arrow.) Very common, handy trick for lots of things. Using it looks like:
bulletDir = barrelEnd.forward; // note that this is length 1
bulletDir += spread * (Random.value-0.5f) * barrelEnd.right;
bulletDir += spread * (Random.value-0.5f) * barrelEnd.up;
Note how you don't use dot-x. It's like you're saying "add part of my red arrow to my blue, and just work out the proper x/y/z for yourself."
Now, moving forwards 1 and left by 0.3 is longer than a straight-ahead shot. If you were just setting speed, that would be a problem (badly aimed bullets would go too fast.) But ray casting doesn't care how long the direction is, so it's fine.
I like it. $$anonymous$$uch simpler than my solution. Produces an randomly spaced square distribution which may or may not be what is wanted. In answer to a spread question a few weeks ago, I searched Unity Answers for the "common" solution. The first half dozen UA answers listed by Google were either wrong, or had flaws.
And it can be modified to do a circular spread:
bulletDir = barrelEnd.forward; // note that this is length 1
var v3 = Random.insideUnitCircle * spread;
bulletDir += v3.x * barrelEnd.right;
bulletDir += v3.y * barrelEnd.up;
The distribution is then the issue. InsideUnitCircle might give a completely uniform spread (or might not -- I've never tested it, and the desc doesn't say.) A random 360 angle&distance 0-spread will give more near results than far (which might be more realistic.) I think you cross-product method gives the same "more near" spread.
Yes, it gives a more near spread. I commented on that on the original post. I just ran a quick test. Random.insideUnitCircle seems uniform.
Answer by DaveA · Jul 26, 2013 at 04:24 PM
Looks like gimble-lock to me. Quaternions would probably help you here, do your offset with them or axis/angle functions. Or, detect that you are looking along Y (up or down) and special-case that to use alternate code.
How would I got about using Quaternions here? I am a bit new to Unity...
Your answer
Follow this Question
Related Questions
How can I raycast the direction my 2D character is facing? 1 Answer
Weird GetAxis behavior 0 Answers
Getting Height of boxes 0 Answers
Jumping with force in forward direction 2 Answers