Search Unity

Question how can i control the max angle a player can move in, WITHOUT CHARACTER CONTROLLER

Discussion in 'Scripting' started by SpyderManToo, Jun 26, 2021.

  1. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    in my fps game, i have these rocks that have a steep incline but the player can still walk up them which leads to the player going super duper high, is there any way i can, through code, make a maximum angle that the player can walk up? i dont want to use character controller because i kinda don't like it and like rb.velocity more(thats what im using for the movement).
     
  2. Lekret

    Lekret

    Joined:
    Sep 10, 2020
    Posts:
    354
    I guess you already do some groundchecking. All Physics functions can return RaycastHit struct which contains normal property. Then you can simply check angle between Vector3.up and this normal. If angle is 0, then ground is flat, if 90, then it's wall. I would check if it's above 60, then player should fall down.
    You can also simply check normal.y, 1 -> pointing up, 0 -> it's wall. Will work too.
     
  3. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    You could cast a ray downwards. Get the normal of the hit mesh. Calculate the angle of that normal relative to Vector3.Up. Now you could prevent upwards movement if the angle is larger than X.

    It is a bit unusual to use a Rigidbody based movement for FPS games, since you usually want a responsive movement and dont need a lot of physics applied to the characters. Technically you can reach the same end result with both Rigidbodies and CharacterControllers, they just start at a different end of the spectrum (fluid/realistic vs perfect control), so it's a matter of deciding which path brings you to your goal, which will be somewhere in the middle with a bias towards one side, the fastest.
     
  4. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    the reason why i like using rigidbodies is probably just because i feel like its very simple, i feel like using character conttrollers is kinda cheap cuz you only need like 2 lines of code for movement
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    What on earth is THIS mindset?! I'd be happy if a character controller only required ONE line... or even ZERO lines... the cheaper the better. Do you like writing, debugging and maintaining unnecessary code or something?!

    A rigidbody and a character controller have extremely well-defined differences and purposes. Use whichever one is appropriate. Solve your problem, make your game, don't start tacking on weird false pseudo-economics like calling it "kinda cheap." That's just not helpful to anyone at all, and mostly destructive to yourself in fact.

    CC (or RB) either solves your problem or it does not. End of story. It's just engineering.
     
    SpyderManToo and Yoreki like this.
  6. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    lol ok so maybe "cheap" wasnt the right word. i just meant that i get to write more code with rb and i get to learn more things (such as the thing this thread is about) rather than having it prebuilt.
     
  7. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Learning is great. But learning to do things properly is better :)
    The thing is, you are either actually using the physics system, in which case you are making things unnecessarily hard on yourself, because for example to stop pinpoint on a location, youd need to cancel out your movement speed with counteracting forces and so on.
    Or... you are ignoring the entire underlying physics system and just set rb.velocity manually (or something similar), which is basically bad practice and not what the physics system is intended for. The physics calculations are still running, you are basically just throwing it all out of the window each frame and overwrite it.
    This is the case in which a CharacterController would be the better approach. You can pretty easily manage your own 'velocity' variable for movement as well. But of course i'm just making assumptions on how you are using the rigidbody, so i may be wrong.

    Just food for thought^^
     
  8. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    im having some trouble with some code that i have written
    here is the code for teh max angle stuff
    Code (CSharp):
    1. RaycastHit hit;
    2.         if(Physics.Raycast(transform.position, transform.up * -1, out hit, ground))
    3.         {
    4.             Vector3 dir = Vector3.up - hit.normal;
    5.             float angle = Vector3.Angle(transform.up, dir);
    6.             Debug.Log(angle.ToString());
    7.             if(angle > 50)
    8.             {
    9.                 PlayerController.instance.canWalk = false;
    10.                 Debug.Log("Cant walk");
    11.             }
    12.             else if(angle <= 50)
    13.             {
    14.                 PlayerController.instance.canWalk = true;
    15.                 Debug.Log("Can walk");
    16.             }
    17.         }
    it is debugging the angle as 50.02454 and debugging cant walk but i can still move...

    my movement code is surrounded so you can only move when you can walk
    Code (CSharp):
    1. if (canWalk)
    2.         {
    3.             float x = Input.GetAxis("Horizontal");
    4.             float y = Input.GetAxis("Vertical");
    5.  
    6.             if (Input.GetKey(KeyCode.LeftShift))
    7.             {
    8.                 x *= runSpeed;
    9.                 y *= runSpeed;
    10.             }
    11.             else
    12.             {
    13.                 x *= moveSpeed;
    14.                 y *= moveSpeed;
    15.             }
    16.  
    17.             Vector3 movePos = transform.right * x + transform.forward * y;
    18.             newMovePos = new Vector3(movePos.x, rb.velocity.y, movePos.z);
    19.  
    20.  
    21.  
    22.             rb.velocity = newMovePos;
    23.         }
    24.         else
    25.         {
    26.             return;
    27.         }
    so im kinda confused ;-;
     
  9. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Can you still move, or are you still moving? That's a difference. According to you the debug messages get displayed, so the code is getting executed properly. So if you put a debug message into the below code example, it should not display when canWalk is false.
    However, just because you dont set a new value to rb.velocity does not mean you wont move anymore. As i mentioned above, you are using fully fledged physics for your movement. So setting a velocity and then ignoring it is kinda like pushing a bowling ball and then expecting it to stop just because you stop pushing. The ball will still have momentum, and the physics system will make sure it keeps moving until stopped by some other force or collision.

    If you want it to just stop, make it stop if canWalk is false. However, you likely want to be able to still move. Just not further upwards. So you should account for that and only have canWalk influence the velocity.y. On that note, canWalk may not be the best name, and some other names may be chosen better as well (for example movePos implies being a position, which is then assigned to a velocity vector which is highly confusing).
     
  10. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    yea the movement code stuff is surrounded by an if statement, i think the problem is bc the ground check is in the middle, you can climb the wall for a little bit until the raycast finally hits the normal and then you slide back down...its kinda annoying, how can i fix this?

    edit: also im not entirely sure if my vector3 dir is calculated correctly