- Home /
raycast in direction of movement key down
Hey all,
I'm working on the fundamentals of a Third Person Cover Shooter similar to GoW. Currently my script shoots two raycasts 5m in front of the character (one for low cover, the other for high cover) in order to detect the height of the cover in front. This works like a charm.
However, moving forward i would like to rewrite this essentially so the raycasts shoot 5m out in the direction of the movement keys. For example, if the player is holding "W" and "D", the raycast would point in a 45 degree angle to the right. Therefore players could have greater control over where they would like to snap to cover.
Any insight would be greatly appreciated!
Answer by lbryan212 · Oct 03, 2018 at 04:54 AM
Update:
So I was able to work out what I was trying to achieve by writing a more complex version of my CoverDetect Script.
Here's what I did:
void Update () {
var forward = transform.forward;
var backward = transform.forward * -1;
var right = transform.right;
var left = transform.right * -1;
var forwardleft = transform.right * -1 + transform.forward;
var backright = transform.forward * -1 + transform.right;
var backleft = transform.right * -1 + transform.forward * -1;
var forwardright = transform.right + transform.forward;
var x = Input.GetAxisRaw("Horizontal");
var y = Input.GetAxisRaw("Vertical");
Then in order to get the raycast pointing in the direction the player was pressing input I wrote the following:
if (x < 0 && y > 0)
{
Debug.DrawRay(HighCoverOrigin.transform.position, forwardleft * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, forwardleft * 5, Color.green);
}
if (x < 0 && y == 0)
{
Debug.DrawRay(HighCoverOrigin.transform.position, left * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, left * 5, Color.green);
}
if (x > 0 && y > 0)
{
Debug.DrawRay(HighCoverOrigin.transform.position, forwardright * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, forwardright * 5, Color.green);
}
else if (x > 0 && y < 0)
{
Debug.DrawRay(HighCoverOrigin.transform.position, backright * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, backright * 5, Color.green);
}
else if (x == 0 && y < 0)
{
Debug.DrawRay(HighCoverOrigin.transform.position, backward * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, backward * 5, Color.green);
}
else if (x == 0 && y > 0)
{
Debug.DrawRay(HighCoverOrigin.transform.position, forward * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, forward * 5, Color.green);
}
else if (x < 0 && y < 0)
{
Debug.DrawRay(HighCoverOrigin.transform.position, backleft * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, backleft * 5, Color.green);
}
else if (x > 0 && y == 0)
{
Debug.DrawRay(HighCoverOrigin.transform.position, right * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, right * 5, Color.green);
}
Your code seems to be a better version of the monstrosity i developed but hey it's all apart of the learning process i suppose!
Feel free to comment on my code and things I could do to improve, I wont get offended.
Thank you @LCStark
Hey, no problem! Don't worry about your code - if that code helps you learn it better, then it is the better version.
After your first two
if
statements you're not using
else if
like you do further down the line. It doesn't break anything, but it makes the program evaluate all of those
if
statements values, even if the first one was already found to be correct.
You could also use a new variable to remember which vector you need to use. That would get rid of those multiple
Debug.DrawRay
's in the code:
Vector3 direction;
if (x < 0 && y > 0) direction = forwardLeft; else if (x < 0 && y == 0) direction = left; ...
Debug.DrawRay(HighCoverOrigin.transform.position, direction * 5, Color.green); Debug.DrawRay(LowCoverOrigin.transform.position, direction * 5, Color.green);
As you can see yourself, precalculating all 8 directions and checking for proper values of x and y causes the code to look way more cluttered than it needs to be. When you calculate the directions you're simply adding the values of
transform.forward
and
transform.right
, sometimes multiplied by
-1
to get the inverse direction. Think about calculating the horizontal and vertical directions separately, then adding the results:
Vector3 horizontal;
Vector3 vertical;
if (x < 0) horizontal = transform.right * -1;
elseif (x > 0) horizontal = transform.right;
else horizontal = Vector3.zero;
if (y < 0) vertical = transform.forward * -1;
elseif (y > 0) vertical = transform.forward;
else vertical = Vector3.zero;
Vector3 direction = horizontal + vertical;
Debug.DrawRay(HighCoverOrigin.transform.position, direction * 5, Color.green);
Debug.DrawRay(LowCoverOrigin.transform.position, direction * 5, Color.green);
That's a way better solution, I'm definitely going to take you up your code and implement this when I find some time today. Thanks a lot I'd definitely change the answer from $$anonymous$$e to yours if I knew how lol. I appreciate the time you took to steer me in the right direction!
Answer by LCStark · Oct 01, 2018 at 08:23 PM
Perhaps using transform.forward
instead of transform.TransformDirection(Vector3.forward)
would help.
Thank you for the insight! Could you explain the difference for a newb? I'm assu$$anonymous$$g the way I had it was redundant?
From what I'm reading in the documentation (Transform.TransformDirection), the only difference is that transform.forward
is already calculated in the Transform
class at all times, so there is no need to use TransformDirection
.
Perhaps I should have asked a different question - what problem do you currently have with rotating the cover detection? From what I gather from your code, it should work alright. I am assu$$anonymous$$g that this CoverDetect
script is attached to your character, so the transform rotates with your character when you press A / D?
Yes this script is attached to my player game inject. Today I will be throwing a simple character controller script in order to start implementing the feature I need.
Having the raycasts destination = player input keydowns is my true goal. I'm simply asking if anyone would have some advanced tricks I could use to do such. I'd imagine I could use some Vector3 math to take the player input and know which direction he's currently trying to move. The goal is, if a player is holding D moving sideways and there's cover to his left... pressing the cover key would snap him to the surface as long as the raycasts detects cover.
Your answer
Follow this Question
Related Questions
RaycastHit always returns 0 1 Answer
nav mesh agent stop ScreenPointToRay after a while 0 Answers
How to make an object rotate to raycast hit from mouse? Unity 3D 1 Answer
Raycast not hitting the collider properly it always has a weird offset 0 Answers
Orientation of character controller relative to ground normal? 0 Answers