Search Unity

Glitching through walls.

Discussion in 'Physics' started by NeonEviscerator, Apr 27, 2016.

  1. NeonEviscerator

    NeonEviscerator

    Joined:
    Apr 27, 2016
    Posts:
    3
    Hello, I am having difficulty creating an open world parkour style game which involves the player running at high speeds. The problem is that the player can very easily go through the walls simply by running into them (even when going at relatively "low" speeds. I am using walls that I made in blender and am using a mesh collider on them. The player is controlled by a rigidbody and this script.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Movement : MonoBehaviour
    5. {
    6.  
    7.     public float XSensitivity = 2;
    8.     public float xRot;
    9.     public float movespeed;
    10.  
    11.     private Rigidbody selfridge;
    12.  
    13.     public void Start()
    14.     {
    15.         selfridge = GetComponent<Rigidbody>();
    16.     }
    17.  
    18.     public void Update()
    19.     {
    20.         xRot = Input.GetAxis("Horizontal");
    21.         xRot = xRot / XSensitivity;
    22.         transform.Rotate(0, xRot, 0);
    23.         //Handles Left/Right Mouselook also rotates player
    24.  
    25.         if (Input.GetButton("Forwards"))
    26.         {
    27.             selfridge.AddForce(transform.forward * movespeed);
    28.         }
    29.  
    30.         if (Input.GetButton("Backwards"))
    31.         {
    32.             selfridge.AddForce(-transform.forward * movespeed);
    33.         }
    34.     }
    35. }
    Any suggestions on how to fix this problem would be greatly appreciated.
    Thanks
     
  2. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,496
    Also, adding a Rigidbody component that isn't Kinematic is you entering a contract telling Unity that you want the Rigidbody component to drive the Transform component. Unfortunately, you're then modifying the Transform component yourself (transform.Rotate). You should stop doing that and drive the Rigidbody itself as you are when you use (selffridge.AddForce).

    BY modifying the Transform you can cause overlaps of other colliders which the physics system is unable to stop; it can only solve them by continually trying to move it out of the overlap you caused. Often this is reported as 'glitching', 'twitching' or 'jiggling'. ;)

    Rotate by adding torque, setting angular velocity or by using MoveRotation.
     
  4. NeonEviscerator

    NeonEviscerator

    Joined:
    Apr 27, 2016
    Posts:
    3
    I tried this, but it did not work :(. Do you think that maybe my mouse look script is getting in the way?
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MouseLook : MonoBehaviour
    5. {
    6.  
    7.     public float YSensitivity = 2;
    8.     public float yRot;
    9.  
    10.     public void Init()
    11.     {
    12.     }
    13.  
    14.  
    15.     public void Update()
    16.     {
    17.         yRot = Input.GetAxis("Vertical");
    18.         yRot = -yRot / YSensitivity;
    19.         transform.Rotate(yRot, 0, 0);
    20.     }
    21. }
    This script is attached to the Main Camera gameobject which is a child of the capsule object, which the previous script is attatched to. The camera, however, does not have a rigidbody component. BTW, the reason I have used moveRotate as opposed to addTorque or setting angular velocity is because I have frozen rotation on the Y asxis on the capsule object as otherwise, on the few occasions that it does collide with the walls, the player spins out of control.

    Once again, any help would be gratly appreciated.
    NeonEviscerator.
     
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,496
    It's hard for me to answer that. What I said before should cover your investigation. If you're moving dynamic bodies by modifying the Transform then you are doing it wrong and causing overlaps and/or completely tunnelling. That can be position, rotation or scales changes.

    You can also set the Rigidbody2D.collisionDetectionMode to one of the continuous detection modes however that won't help if you are explicitly repositioning, rotating or scaling it via the Transform.
     
    Ishidres likes this.
  6. NeonEviscerator

    NeonEviscerator

    Joined:
    Apr 27, 2016
    Posts:
    3
    Thank you, that fixed the problem completely:)!
     
    MelvMay likes this.
  7. GarthLaoshi

    GarthLaoshi

    Joined:
    May 1, 2016
    Posts:
    4
    Related question, I hope I am not imposing. I just stared Unity and did the roll a ball tutorial. After finishing it, I decided to try adding a bounce-off effect and made a few changes to the scoring etc.

    But, I have a problem: If I accelerate the ball reasonably quickly, it just flies right through the wall! However, the script works perfectly at slower speeds.

    This code is from my player (ball) script. I can summarize the problem, as I have tried to debug it and tested the conditions where the ball falls off the map. Although this trigger is always called, sometimes the value of the normal vector (BounceNormal) appears as 0. I am not sure if it is because the position of the ball (RB.position) is registering as being the same as the ClosestPointOnBounds (RB.position) or something else.

    I am under the impression that the surface of the sphere, not the center, should be triggering the event.

    Code (CSharp):
    1. void OnTriggerEnter(Collider other)
    2.     {
    3.         if (other.gameObject.CompareTag("Wall Bounce"))
    4.         {          
    5.             Vector3 BounceNormal;
    6.             BounceNormal = RB.position - other.ClosestPointOnBounds(RB.position);
    7.             if (Vector3.Dot (BounceNormal, RB.velocity) >= 0)  // This should never happen!
    8.             {
    9.                 BounceNormal = -RB.position;
    10.                 Debug.Log (BounceNormal.ToString());
    11.             }
    12.             BounceNormal = BounceNormal.normalized;
    13.             BounceNormal = (Vector3.Dot (RB.velocity, BounceNormal) * BounceNormal);
    14.             RB.velocity = RB.velocity - (BounceNormal * 2);
    15.             Debug.Log (BounceNormal.ToString());
    16.            }
    17.  
    18.     }
    Is there any way to make the trigger happen more quickly so that this script executes before center of the ball reaches the wall?
     
  8. romeinmatthijs

    romeinmatthijs

    Joined:
    Feb 3, 2020
    Posts:
    1
    You made my day dude, Thank you!
     
  9. DrDigg0R

    DrDigg0R

    Joined:
    Apr 7, 2013
    Posts:
    30
    I believe OnTriggerEnter() is called during Update() while OnCollisionEnter() calls are related to FixedUpdate(). I would try changing the trigger to a collider.

    Instead of the collider, you will get a Collision object when OnCollisionEnter() is called - this way, you can get the surface normal from the Collision object directly; and you can set the Rigidbodies collision detection mode to Continuous Dynamic or Dynamic which should give you the OnCollisionEnter() callback right before the object would hit the wall.
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,496
    Note that this isn't correct. All physics callbacks happen at the same time which is when the simulation step has finished. It's part of the the simulation itself which is why you'll get them when you manually step the simulation.
     
    DrDigg0R likes this.
  11. DrDigg0R

    DrDigg0R

    Joined:
    Apr 7, 2013
    Posts:
    30
    Thanks for correcting my false statement @MelvMay ; sorry if it caused confusion :)
     
    MelvMay likes this.
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,496
    Not a problem at all. Just trying to put the info out there. Appreciate you helping on the forums!
     
    DrDigg0R likes this.
  13. Deleted User

    Deleted User

    Guest

    Thanks Man, Helped a lot