Search Unity

Char Controller pushing rigidbodies, strange behaviour

Discussion in 'Physics' started by Zorranco, Mar 29, 2015.

  1. Zorranco

    Zorranco

    Joined:
    Jul 15, 2014
    Posts:
    23
    Hello.

    PD: if some moderator see this, please move to coding, as it is not exactly a physics issue

    In U4, I was using a free script found in Unify wiki called controllerColliderHit, that worked perfectly, so my character was able to push rigidbodies. Now, since the project was on early stages, I am migrating everything to U5, but the behaviour is not the same...when my character controller pushes, for example a box, as soon as the box start to turn (i.e. it is not perpendicular to the ground), the controller "climbs" over it, as seen in the screenshot:



    In fact, at the moment of the screenshot, the controller is standing over the edge of the box without game being paused or something.

    Now I have found that it is related with FPS walker enhanced script from Unify wiki, see below
     
    Last edited: Mar 29, 2015
  2. Zorranco

    Zorranco

    Joined:
    Jul 15, 2014
    Posts:
    23
    It is the FPS walker enhanced script. If check "Slide when over slope limit" this does not hapen, but the character controller do some stutters while pushing...I think script must be done again in this part, but I am not a good coder UU'

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent (typeof (CharacterController))]
    5. public class FPSWalkerEnhanced: MonoBehaviour {
    6.  
    7.     public float walkSpeed = 6.0f;
    8.  
    9.     public float runSpeed = 11.0f;
    10.  
    11.     // If true, diagonal speed (when strafing + moving forward or back) can't exceed normal move speed; otherwise it's about 1.4 times faster
    12.     public bool limitDiagonalSpeed = true;
    13.  
    14.     // If checked, the run key toggles between running and walking. Otherwise player runs if the key is held down and walks otherwise
    15.     // There must be a button set up in the Input Manager called "Run"
    16.     public bool toggleRun = false;
    17.  
    18.     public float jumpSpeed = 8.0f;
    19.     public float gravity = 20.0f;
    20.  
    21.     // Units that player can fall before a falling damage function is run. To disable, type "infinity" in the inspector
    22.     public float fallingDamageThreshold = 10.0f;
    23.  
    24.     // If the player ends up on a slope which is at least the Slope Limit as set on the character controller, then he will slide down
    25.     public bool slideWhenOverSlopeLimit = false;
    26.  
    27.     // If checked and the player is on an object tagged "Slide", he will slide down it regardless of the slope limit
    28.     public bool slideOnTaggedObjects = false;
    29.  
    30.     public float slideSpeed = 12.0f;
    31.  
    32.     // If checked, then the player can change direction while in the air
    33.     public bool airControl = false;
    34.  
    35.     // Small amounts of this results in bumping when walking down slopes, but large amounts results in falling too fast
    36.     public float antiBumpFactor = .75f;
    37.  
    38.     // Player must be grounded for at least this many physics frames before being able to jump again; set to 0 to allow bunny hopping
    39.     public int antiBunnyHopFactor = 1;
    40.      
    41.     private Vector3 moveDirection = Vector3.zero;
    42.     private bool grounded = false;
    43.     private CharacterController controller;
    44.     private Transform myTransform;
    45.     private float speed;
    46.     private RaycastHit hit;
    47.     private float fallStartLevel;
    48.     private bool falling;
    49.     private float slideLimit;
    50.     private float rayDistance;
    51.     private Vector3 contactPoint;
    52.     private bool playerControl = false;
    53.     private int jumpTimer;
    54.  
    55.     void Start() {
    56.         controller = GetComponent<CharacterController>();
    57.         myTransform = transform;
    58.         speed = walkSpeed;
    59.         rayDistance = controller.height * .5f + controller.radius;
    60.         slideLimit = controller.slopeLimit - .1f;
    61.         jumpTimer = antiBunnyHopFactor;
    62.     }
    63.  
    64.     void FixedUpdate() {
    65.         float inputX = Input.GetAxis("Horizontal");
    66.         float inputY = Input.GetAxis("Vertical");
    67.         // If both horizontal and vertical are used simultaneously, limit speed (if allowed), so the total doesn't exceed normal move speed
    68.         float inputModifyFactor = (inputX != 0.0f && inputY != 0.0f && limitDiagonalSpeed)? .7071f : 1.0f;
    69.      
    70.         if (grounded) {
    71.             bool sliding = false;
    72.             // See if surface immediately below should be slid down. We use this normally rather than a ControllerColliderHit point,
    73.             // because that interferes with step climbing amongst other annoyances
    74.             if (Physics.Raycast(myTransform.position, -Vector3.up, out hit, rayDistance)) {
    75.                 if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
    76.                     sliding = true;
    77.             }
    78.             // However, just raycasting straight down from the center can fail when on steep slopes
    79.             // So if the above raycast didn't catch anything, raycast down from the stored ControllerColliderHit point instead
    80.             else {
    81.                 Physics.Raycast(contactPoint + Vector3.up, -Vector3.up, out hit);
    82.                 if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
    83.                     sliding = true;
    84.             }
    85.          
    86.             // If we were falling, and we fell a vertical distance greater than the threshold, run a falling damage routine
    87.             if (falling) {
    88.                 falling = false;
    89.                 if (myTransform.position.y < fallStartLevel - fallingDamageThreshold)
    90.                     FallingDamageAlert (fallStartLevel - myTransform.position.y);
    91.             }
    92.          
    93.             // If running isn't on a toggle, then use the appropriate speed depending on whether the run button is down
    94.             if (!toggleRun)
    95.                 speed = Input.GetButton("Shift")? runSpeed : walkSpeed;
    96.          
    97.             // If sliding (and it's allowed), or if we're on an object tagged "Slide", get a vector pointing down the slope we're on
    98.             if ( (sliding && slideWhenOverSlopeLimit) || (slideOnTaggedObjects && hit.collider.tag == "Slide") ) {
    99.                 Vector3 hitNormal = hit.normal;
    100.                 moveDirection = new Vector3(hitNormal.x, -hitNormal.y, hitNormal.z);
    101.                 Vector3.OrthoNormalize (ref hitNormal, ref moveDirection);
    102.                 moveDirection *= slideSpeed;
    103.                 playerControl = false;
    104.             }
    105.             // Otherwise recalculate moveDirection directly from axes, adding a bit of -y to avoid bumping down inclines
    106.             else {
    107.                 moveDirection = new Vector3(inputX * inputModifyFactor, -antiBumpFactor, inputY * inputModifyFactor);
    108.                 moveDirection = myTransform.TransformDirection(moveDirection) * speed;
    109.                 playerControl = true;
    110.             }
    111.          
    112.             // Jump! But only if the jump button has been released and player has been grounded for a given number of frames
    113.             if (!Input.GetButton("Jump"))
    114.                 jumpTimer++;
    115.             else if (jumpTimer >= antiBunnyHopFactor) {
    116.                 moveDirection.y = jumpSpeed;
    117.                 jumpTimer = 0;
    118.             }
    119.         }
    120.         else {
    121.             // If we stepped over a cliff or something, set the height at which we started falling
    122.             if (!falling) {
    123.                 falling = true;
    124.                 fallStartLevel = myTransform.position.y;
    125.             }
    126.          
    127.             // If air control is allowed, check movement but don't touch the y component
    128.             if (airControl && playerControl) {
    129.                 moveDirection.x = inputX * speed * inputModifyFactor;
    130.                 moveDirection.z = inputY * speed * inputModifyFactor;
    131.                 moveDirection = myTransform.TransformDirection(moveDirection);
    132.             }
    133.         }
    134.      
    135.         // Apply gravity
    136.         moveDirection.y -= gravity * Time.deltaTime;
    137.      
    138.         // Move the controller, and set grounded true or false depending on whether we're standing on something
    139.         grounded = (controller.Move(moveDirection * Time.deltaTime) & CollisionFlags.Below) != 0;
    140.     }
    141.  
    142.     void Update () {
    143.         // If the run button is set to toggle, then switch between walk/run speed. (We use Update for this...
    144.         // FixedUpdate is a poor place to use GetButtonDown, since it doesn't necessarily run every frame and can miss the event)
    145.         if (toggleRun && grounded && Input.GetButtonDown("Shift"))
    146.             speed = (speed == walkSpeed? runSpeed : walkSpeed);
    147.     }
    148.  
    149.     // Store point that we're in contact with for use in FixedUpdate if needed
    150.     void OnControllerColliderHit (ControllerColliderHit hit) {
    151.         contactPoint = hit.point;
    152.     }
    153.  
    154.     // If falling damage occured, this is the place to do something about it. You can make the player
    155.     // have hitpoints and remove some of them based on the distance fallen, add sound effects, etc.
    156.     void FallingDamageAlert (float fallDistance) {
    157.         print ("Ouch! Fell " + fallDistance + " units!");
    158.     }
    159. }
     
    Last edited: Mar 29, 2015