Search Unity

Player - Terrain/Object collision

Discussion in 'Physics' started by fefolinjo, Jun 5, 2015.

  1. fefolinjo

    fefolinjo

    Joined:
    May 30, 2015
    Posts:
    7
    I have a collider ob both, terrain and player. The player also has a rigidbody component.




    Inside the box collider on the picture above is another box collider (trigger):


    The player goes through the terrain. What am I missing?

    The triggers work.
     
  2. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    The rigidbody has "Is Kinematic" enabled. This means it basically ignores the physics and will not collide.
     
    fefolinjo likes this.
  3. fefolinjo

    fefolinjo

    Joined:
    May 30, 2015
    Posts:
    7
    Thank you. Guess that solves it, but now I've got this haha



    Problem with gravity, drag?
     
  4. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    freeze the rigidbodies rotation
     
  5. fefolinjo

    fefolinjo

    Joined:
    May 30, 2015
    Posts:
    7
    The collision seems to be working now.

    Had to resize the box collider on the player and freeze those:



    Now my movement is very weird. It looks like it ignores the speed in the movement script + the player seems to be sliding a bit. Is it because of the rotation freeze?

    If I freeze x and z the collision does not work anymore, but the player is moving normally again, like it would with kinematic enabled.

    My movement script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Movement : MonoBehaviour {
    5.     public float speed = 3.0F;
    6.     public float rotationSpeed = 100.0F;
    7.     void Update() {
    8.         float translation = Input.GetAxis("Vertical") * speed;
    9.         float rotation = Input.GetAxis("Horizontal") * rotationSpeed;
    10.         translation *= Time.deltaTime;
    11.         rotation *= Time.deltaTime;
    12.         transform.Translate(0, 0, translation);
    13.         transform.Rotate(0, rotation, 0);
    14.     }
    15. }
    16.  
    Tried changing the speed in the code but it does not change anything/much.
     
  6. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    You need to use fixedupdate and move your player either with addforce or affecting the velocity directly.
    The reason your script worked before with movement but not collision is cuz you had the rigidbody set to kinematic, which basically means it ignores physics. Now that you have it as non kinematic, physics is starting to affect it. So if you bang into a wall, you will be pushed off the wall by the physics, and since you have nothing changing your velocity, your velocity will just stay the same and keep sliding forever until something else hits it.

    By checking the constraints, it is basically ignoring physics for that axis. By checking constraints on all x y and z, you will no longer be affected by physics which will make your movement work again and collision won't. It is ok to constrain the rotation axis though. Most people do for character controllers.
     
    fefolinjo likes this.
  7. fefolinjo

    fefolinjo

    Joined:
    May 30, 2015
    Posts:
    7
    Thank you. It works now. I'm using Rigidbody.AddForce for the movement. Is there a way to get similar style of movement like without physics enabled? I actually don't need that kind of realistic movement but I'd like to keep the collision.

    I've tried changing velocity directly but it's just weird.

    Another option would be using the force but making it stop very soon. Imagine driving a RC drone, just floating when nothing is pressed.
     
  8. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    your best bet might be something like
    Code (CSharp):
    1. myRigidbody.velocity = Vector3.zero;
    2. myRigidbody.AddForce(translation, ForceMode.VelocityChange);
     
  9. fefolinjo

    fefolinjo

    Joined:
    May 30, 2015
    Posts:
    7
    Ended up with something like this
    Code (CSharp):
    1. public class ForceMovement : MonoBehaviour
    2. {
    3.     public float force;
    4.     public float rotation_speed;
    5.     private float rotation_tmp;
    6.     private Rigidbody rb;
    7.  
    8.     void Start() {
    9.         rb = GetComponent<Rigidbody>();
    10.     }
    11.  
    12.       void FixedUpdate() {
    13.           if (Input.GetKey(KeyCode.W))
    14.           {
    15.             rb.velocity = Vector3.zero;
    16.               rb.AddForce(transform.forward * force,ForceMode.VelocityChange);
    17.           } else if(Input.GetKey(KeyCode.S)) {
    18.             rb.velocity = Vector3.zero;
    19.             rb.AddForce(transform.forward * (-1) * force,ForceMode.VelocityChange);
    20.         }
    21.         else
    22.         {
    23.             rb.Sleep();
    24.         }
    25.           rotation_tmp = Input.GetAxis("Horizontal") * rotation_speed;
    26.           rotation_tmp *= Time.deltaTime;
    27.           transform.Rotate(0,rotation_tmp,0); // rotate around Y axis
    28.       }
    29. }
    Pretty happy with the result. Thank you for all the help @HiddenMonk!
     
    HiddenMonk likes this.