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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Player is able to walk through walls

Discussion in 'Scripting' started by NameyMcNameFace, Mar 20, 2023.

  1. NameyMcNameFace

    NameyMcNameFace

    Joined:
    Oct 10, 2022
    Posts:
    12
    So to start I do have colliders on all walls and floors. On the player character I have a rididbody, capsule collider, and my movement script. Admittedly the script is fairly hobbled together, but I'm still new so am confused as to what is going wrong.

    I am using transform as it is not directly influencing the rigidbody in script, so I don't think using .MovePosition would make the difference here, but am wholly unsure. If anyone has an idea or has any critique for how I can improve the code I would appreciate it.
     
  2. NameyMcNameFace

    NameyMcNameFace

    Joined:
    Oct 10, 2022
    Posts:
    12
    Realized I forgot to post the code

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerController : MonoBehaviour
    6. {
    7.     public float speed = 5f;
    8.     public Transform cam;
    9.  
    10.     public float turnSmoothTime = 0.1f;
    11.     float turnSmoothVelocity = 1f;
    12.  
    13.     void Start()
    14.     {
    15.         Cursor.lockState = CursorLockMode.Locked;
    16.     }
    17.  
    18.     // Update is called once per frame
    19.     void Update()
    20.     {
    21.         //Get Player Input
    22.         float playerVerticalInput = Input.GetAxis("Vertical");
    23.         float playerHorizontalInput = Input.GetAxis("Horizontal");
    24.         Vector3 direction = new Vector3(playerHorizontalInput, 0f, playerVerticalInput);
    25.  
    26.         //Get Camera-Normalized Directional Vectors, then remove the y-values of each vector and normalize them
    27.         Vector3 forward = cam.transform.forward;
    28.         Vector3 right = cam.transform.right;
    29.         forward.y = 0;
    30.         right.y = 0;
    31.         forward = forward.normalized;
    32.         right = right.normalized;
    33.  
    34.         //Create Direction-Relative Input Vectors
    35.         Vector3 forwardRelativeVerticalInput = playerVerticalInput * forward * speed * Time.deltaTime;
    36.         Vector3 rightRelativeHorizontalInput = playerHorizontalInput * right * speed * Time.deltaTime;
    37.  
    38.         //Create Camera-Relative Movement
    39.         Vector3 cameraRelativeMovement = forwardRelativeVerticalInput +
    40.             rightRelativeHorizontalInput;
    41.         this.transform.Translate(cameraRelativeMovement, Space.World);
    42.  
    43.         if (direction.magnitude >= 0.1f)
    44.         {
    45.             float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
    46.             float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
    47.             transform.rotation = Quaternion.Euler(0f, angle, 0f);
    48.  
    49.             Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
    50.             transform.position += moveDir.normalized * speed * Time.deltaTime;
    51.         }
    52.     }
    53. }
    54.  
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,951
    Here's one issue:

    With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.

    Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.

    https://forum.unity.com/threads/col...-unity-physic-rigidbody.1216875/#post-7763061

    https://forum.unity.com/threads/oncollisionenter2d-not-being-called.1266563/#post-8044121
     
    Last edited: Mar 21, 2023
    Olipool likes this.
  4. NameyMcNameFace

    NameyMcNameFace

    Joined:
    Oct 10, 2022
    Posts:
    12
    I edited the script to now use .MovePosition/.MoveRotation, however if I set the speed above 5 it seems the player can still clip through walls with it being particularly easy to do so when pressing into a corner of two walls. Any idea what might be causing this?
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerController : MonoBehaviour
    6. {
    7.     public float speed = 5f;
    8.     public Transform cam;
    9.  
    10.     public float turnSmoothTime = 0.009f;
    11.     float turnSmoothVelocity = 1f;
    12.     Rigidbody RB;
    13.  
    14.     void Start()
    15.     {
    16.         Cursor.lockState = CursorLockMode.Locked;
    17.         RB = GetComponent<Rigidbody>();
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.         //Get Player Input
    24.         float playerVerticalInput = Input.GetAxis("Vertical");
    25.         float playerHorizontalInput = Input.GetAxis("Horizontal");
    26.         Vector3 direction = new Vector3(playerHorizontalInput, 0f, playerVerticalInput);
    27.  
    28.         //Get Camera-Normalized Directional Vectors, then remove the y-values of each vector and normalize them
    29.         Vector3 forward = cam.transform.forward;
    30.         Vector3 right = cam.transform.right;
    31.         forward.y = 0;
    32.         right.y = 0;
    33.         forward = forward.normalized;
    34.         right = right.normalized;
    35.  
    36.         //Create Direction-Relative Input Vectors
    37.         Vector3 forwardRelativeVerticalInput = playerVerticalInput * forward * speed * Time.deltaTime;
    38.         Vector3 rightRelativeHorizontalInput = playerHorizontalInput * right * speed * Time.deltaTime;
    39.  
    40.         //Create Camera-Relative Movement
    41.         Vector3 cameraRelativeMovement = forwardRelativeVerticalInput +
    42.             rightRelativeHorizontalInput;
    43.         this.transform.Translate(cameraRelativeMovement, Space.World);
    44.  
    45.         if (direction.magnitude >= 0.1f)
    46.         {
    47.             float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
    48.             float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
    49.             RB.MoveRotation(Quaternion.Euler(0f, angle, 0f));
    50.  
    51.             Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
    52.             RB.MovePosition(moveDir.normalized * speed * Time.deltaTime);
    53.         }
    54.     }
    55. }
    56.  
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,951
    I still see this line:

     
    Olipool likes this.
  6. NameyMcNameFace

    NameyMcNameFace

    Joined:
    Oct 10, 2022
    Posts:
    12
    The issue I'm running into with changing this to MovePosition, is how it requires 2 arguments, but that specific line is just to grab the position of the camera in world space so the movement can be based on it. Still extremely new to this so I apologize if I'm overcomplicating it.
     
  7. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    717
    I don't understand.

    this.transform.Translate(cameraRelativeMovement, Space.World);


    Line 43 does not get the position of the camera in world space. It doesn't get anything at all, in fact! It moves the transform of whatever this script is attached to by calling the Translate method on your transform.

    Were you trying to convert cameraRelativeVector from the camera's local space to world space? If so, you want this:

    Code (CSharp):
    1. var result = cam.transform.TransformVector(cameraRelativeMovement);
    However, that is not necessary. You're already working with world-space vectors, since you used
    cam.transform.forward
    and
    cam.transform.right
    . Those vectors tell you what world-space directions are "forward" and "right" for the camera.
     
    NameyMcNameFace likes this.
  8. NameyMcNameFace

    NameyMcNameFace

    Joined:
    Oct 10, 2022
    Posts:
    12
    I tried actually getting rid of line 43 and without lines 41-43 the player will rotate to face where they are turning, but will not actually move. Instead it teleports the player to the world space origin. I tried replacing this with cam.transfrom.TransformVector but it had the same issue.