Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question fixed

Discussion in 'Physics' started by Sekudo, Dec 24, 2022.

Thread Status:
Not open for further replies.
  1. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36
    so im a new unity creator and im wondering how i can fix this. i combined brackeys' 3d cinemachine-relative movement with a video i found about jumping. my game is a 3d platformer, with the same movement system as roblox when you're in shift lock mode. (moves forward to direction of the camera, strafing, moving backward, and jumping) but when i jump and i press w at the very top of a wall, i go inside it. the walls have just a box collider, and the "ground" tag. the player has a rigidbody, box collider, char controller, and the script below. here is my code. if anyone could help it would mean the world to me.


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerMovement : MonoBehaviour
    6. {
    7.     public CharacterController controller;
    8.     public Transform cam;
    9.  
    10.     public float speed = 6f;
    11.     public float gravity = -9.81f;
    12.     public float jumpHeight = 3f;
    13.  
    14.     public Transform groundCheck;
    15.     public float groundDistance = 0.4f;
    16.     public LayerMask groundMask;
    17.  
    18.     Vector3 velocity;
    19.     bool isGrounded;
    20.  
    21.     public float turnSmoothTime = 0.1f;
    22.     float turnSmoothVelocity;
    23.  
    24.     private void Start()
    25.     {
    26.  
    27.     }
    28.  
    29.     // Update is called once per frame
    30.     void Update()
    31.     {
    32.  
    33.         isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
    34.  
    35.         if (isGrounded && velocity.y < 0)
    36.         {
    37.             velocity.y = -2f;
    38.         }
    39.  
    40.         float horizontal = Input.GetAxisRaw("Horizontal");
    41.         float vertical = Input.GetAxisRaw("Vertical");
    42.         Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
    43.  
    44.         velocity.y += gravity * Time.deltaTime;
    45.  
    46.         controller.Move(velocity * Time.deltaTime);
    47.  
    48.         if (Input.GetButtonDown("Jump") && isGrounded)
    49.         {
    50.             velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
    51.         }
    52.  
    53.         if (direction.magnitude >= 0.1f)
    54.         {
    55.             float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
    56.             float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
    57.             transform.rotation = Quaternion.Euler(0f, angle, 0f);
    58.  
    59.  
    60.  
    61.             Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
    62.             controller.Move(moveDir.normalized * speed * Time.deltaTime);
    63.         }
    64.     }
    65. }
     

    Attached Files:

  2. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    Hello Sekudo,

    the pyhsics system is separate from Update. You basically move your object into the Wall and then the physics system pushes it out again. Either put you whole stuff in FixedUpdate (where the the physics step happens) or buffer your movement and apply it in FixedUpdate
     
  3. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36

    ty for your response! i changed the Update() function to FixedUpdate(). i'm guessing thats not what i was supposed to do since i fell through the floor when i launched the game, so can you please specify?
     
  4. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    Depends. FixedUpdate is running in most cases in a slower rate than Update. If your system depends on Input which has to be in Update (bc you feel the lag otherwise, also FixedUpdate somehow misses the input data sometimes), then you have to buffer your input at least. So yeah, you have to use both Update and FixedUpdate, my bad.
    some thing like:
    Code (CSharp):
    1. float speed;
    2. void Update(){
    3.     speed = Input.something;
    4. }
    5. voud FixedUpdate(){
    6.      rb.AddForce(speed * transform.forward * Time.FixedDeltaTime, ForceMode.velocity);
    7. }
     
  5. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    same reason again: you push it through the floor, and the Physics cant react on time. I know a guy at my University who has a Master's Degree in Games, works on his PhD and spent 6 months on making a good and stable Character Controller. The thing you try to achieve is far away from simple.
    Gravity is an acceleration, so use AddForce(gravity * Time.FixedDeltaTime, ForceMode.acceleration) in FixedUpdate to do it.
    Or you use raycasts in Update to check for the distance every frame and put in place.
     
  6. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36

    sorry i made you reply twice, i realized that i should just try it anyway, and didn't refresh my unity forums until you already responded. i'm having trouble identifying where i should put this, since it uses a y variable for gravity (looking back i have no idea why i added a rigidbody in the first place) are you able to copy and paste the line(s) i should replace it with?
     
  7. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    Code (CSharp):
    1. float horizontal;
    2. float vertical;
    3. Vector3 direction;
    4. bool jump;
    5. void Update{
    6. isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
    7.  
    8.        
    9.  if(Input.GetButtonDown("Jump"))
    10. jump = true;
    11.         horizontal = Input.GetAxisRaw("Horizontal");
    12.         vertical = Input.GetAxisRaw("Vertical");
    13.         direction = new Vector3(horizontal, 0f, vertical).normalized;
    14.  
    15.        
    16.         }
    17. void FixedUpdate(){
    18. Vector3 ve =rb.velocity
    19. ve.y += gravity * Time.deltaTime;
    20. rb.velocity  = ve;
    21.  
    22.         rb.velocity += velocity * Time.deltaTime;
    23.  
    24.         if ( jump&& isGrounded)
    25.         {
    26. jump = false;
    27. //against change velocity with tmp Vector
    28.             velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
    29.         }
    30.  
    31.         if (direction.magnitude >= 0.1f)
    32.         {
    33.             float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
    34.             float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
    35.             rb.Rotate (Quaternion.Euler(0f, angle, 0f))
    36.  
    37.  
    38.  
    39.             Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
    40.             rb.Move(moveDir.normalized * speed * Time.deltaTime);
    41. }
    something like this. I hope my pseudo broken code helps you to understnad the principles; update input in update, use it in FixedUpdate to change the Rigidbody. I you dont want to use Rigidbodies, you will have a hard time basically implementing physics again that fits your needs (expert stuff, so use Physics out of the box)
     
  8. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36
    really sorry, but i was able to understand the first part, but its a bit more difficult after the fixedupdate. if your able to, i will really appreciate it if you can simplify it a bit more so i can understand it. i tried pasting it in but it didn't work. if youre not able to, dont worry ill try to figure it out.
     
  9. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36

    also tried to edit it enough to figure it out but it says rigidbody isnt capable of moving at the 40th line you made
     
  10. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    rb.Move(moveDir.normalized * speed * Time.deltaTime transform.position); should fix that problem
     
  11. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36
    it says syntax error, ',' expected, was i supposed to put some sort of operation between it?
     
  12. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    rb.Move(moveDir.normalized * speed * Time.deltaTime + transform.position);
     
  13. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36
    still doesnt work, i'll put my code here so you can check to make sure everything things right, thats probably the issue (this is the new code, after you showed me a rough draft of the code i should have)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerMovement : MonoBehaviour
    6. {
    7.     public CharacterController controller;
    8.     public Transform cam;
    9.  
    10.     public float speed = 6f;
    11.     public float gravity = -9.81f;
    12.     public float jumpHeight = 3f;
    13.  
    14.     public Transform groundCheck;
    15.     public float groundDistance = 0.4f;
    16.     public LayerMask groundMask;
    17.  
    18.     public Rigidbody rb;
    19.  
    20.     Vector3 velocity;
    21.     bool isGrounded;
    22.  
    23.     public float turnSmoothTime = 0.1f;
    24.     float turnSmoothVelocity;
    25.  
    26.     private void Start()
    27.     {
    28.         rb = GetComponent<Rigidbody>();
    29.     }
    30.  
    31.     // Update is called once per frame
    32.     void Update()
    33.     {
    34.         isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
    35.  
    36.         if (Input.GetButtonDown("Jump"))
    37.         {
    38.             isGrounded = false;
    39.         }
    40.  
    41.         float horizontal = Input.GetAxisRaw("Horizontal");
    42.         float vertical = Input.GetAxisRaw("Vertical");
    43.         Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
    44.  
    45.     }
    46.  
    47.     void FixedUpdate()
    48.     {
    49.         Vector3 ve = rb.velocity;
    50.         ve.y += gravity * Time.deltaTime;
    51.         rb.velocity = ve;
    52.  
    53.  
    54.         rb.velocity += velocity * Time.deltaTime;
    55.  
    56.         if (Input.GetKeyDown("Jump") && isGrounded)
    57.         {
    58.             isGrounded = false;
    59.             velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
    60.         }
    61.         if (direction.magnitude >= 0.1f)
    62.         {
    63.             float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
    64.             float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
    65.             rb.Rotate(Quaternion.Euler(0f, angle, 0f));
    66.  
    67.  
    68.  
    69.  
    70.             Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
    71.             rb.Move(moveDir.normalized * speed * Time.deltaTime + transform.position);
    72.         }
    73.     }
    74. }
     
  14. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    you set rb.velocity += velocity * Time.deltaTime//which leads to making velocity zero; velocity is not initialized (so it is 0), so I deleted that bc rb.move does that part of moving

    does it work now?

    Code (CSharp):
    1.     using System.Collections;
    2.     using System.Collections.Generic;
    3.     using UnityEngine;
    4.      
    5.     public class PlayerMovement : MonoBehaviour
    6.     {
    7.         public CharacterController controller;
    8.         public Transform cam;
    9.      
    10.         public float speed = 6f;
    11.         public float gravity = -9.81f;
    12.         public float jumpHeight = 3f;
    13.      
    14.         public Transform groundCheck;
    15.         public float groundDistance = 0.4f;
    16.         public LayerMask groundMask;
    17.      
    18.         public Rigidbody rb;
    19.      
    20.        
    21.         bool isGrounded;
    22.      bool jump;
    23.         public float turnSmoothTime = 0.1f;
    24.         float turnSmoothVelocity;
    25.      
    26.         private void Start()
    27.         {
    28.             rb = GetComponent<Rigidbody>();
    29.         }
    30.      
    31.         // Update is called once per frame
    32.         void Update()
    33.         {
    34. if (Input.GetKeyDown("Jump"){
    35. jump = true;
    36. }
    37.             isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
    38.      
    39.             if (Input.GetButtonDown("Jump"))
    40.             {
    41. //better to do with onCollisionStay and OnCollisionExit, but fine for now. Also a Jump timer/cool off would be good idea
    42.                 isGrounded = false;
    43.             }
    44.      
    45.             float horizontal = Input.GetAxisRaw("Horizontal");
    46.             float vertical = Input.GetAxisRaw("Vertical");
    47.             Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
    48.      
    49.         }
    50.      
    51.         void FixedUpdate()
    52.         {
    53.             Vector3 ve = rb.velocity;
    54.             ve.y += gravity * Time.deltaTime;
    55.             rb.velocity = ve;
    56.      
    57.      
    58.            
    59.      
    60.             if (jump&& isGrounded)
    61.             {
    62. jump = false;
    63.                 isGrounded = false;
    64.                 velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
    65.             }
    66.             if (direction.magnitude >= 0.1f)
    67.             {
    68.                 float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
    69.                 float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
    70.                 rb.Rotate(Quaternion.Euler(0f, angle, 0f));
    71.      
    72.      
    73.      
    74.      
    75.                 Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
    76.                 rb.Move(moveDir.normalized * speed * Time.deltaTime + transform.position);
    77.             }
    78.         }
    79.     }
    80.  
     
    Sekudo likes this.
  15. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36


    im back, and i tested it but sadly, it still isn't working. it's back to the issue stated previously where it says that rigidbody isn't capable of moving where it says rb.Move. you also forgot a parenthese at the input.(getkeydown("jump")) line right after the void update. but im not too sure what more to do, but if you found something i would really thank you for it
     

    Attached Files:

    Last edited: Jan 10, 2023
  16. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    Hello,
    does MovePosition instead of move solves the bug?
     
  17. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36
    tysm your amazing i will remember you :)
     
  18. GamerLordMat

    GamerLordMat

    Joined:
    Oct 10, 2019
    Posts:
    177
    Thank you :). does it work now :D? If not just message me
     
  19. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36
    Yes it does!
     
Thread Status:
Not open for further replies.