Search Unity

A question about Tanks!!! character controller

Discussion in 'Physics' started by Raiden-Freeman, Mar 20, 2018.

  1. Raiden-Freeman

    Raiden-Freeman

    Joined:
    May 7, 2013
    Posts:
    15
    In the Tanks!!! sample project for networking, I was examining the implementation of player movement. I noticed that the tanks have a rigidbody component, which does not have the IsKinematic flag enabled. As a result, I expected the controls to be based around AddForce(); to my surprise, the code is setting the rigidbody's position (as well as the transform component's) explicitly:


    private void Move()
    {
    float moveDistance = m_DesiredDirection.magnitude * m_Speed * Time.deltaTime;

    // Create a movement vector based on the input, speed and the time between frames, in the direction the tank is facing.
    Vector3 movement = m_CurrentMovementMode == MovementMode.Backward ? -transform.forward : transform.forward;
    movement *= moveDistance;

    // Apply this movement to the rigidbody's position.
    // Also immediately move our transform so that attached joints update this frame
    m_Rigidbody.position = m_Rigidbody.position + movement;
    transform.position = m_Rigidbody.position;
    }

    From TankMovement.cs, lines 308-320.

    According to the unity manual on Rigidbodies, "you may want to control your character directly from script code" [...] " The Rigidbody component has a property called Is Kinematic which removes it from the control of the physics engine and allow it to be moved kinematically from a script."

    Could this approach be affected by issues, given higher values in movement speed relative to model/mesh/collider sizes?

    Let's say that obstacles usually have a 1 unit diameter, if my speed is too high, it could overshoot the obstacle, ignoring the collision, teleporting through it. According to the scripting API: "Set Rigidbody.position instead, if you want to teleport a rigidbody from one position to another, with no intermediate positions being rendered."

    I am guessing that the choice was made so that movement, causes setting a value, that can be deterministically calculated and propagated to the clients (and thus predicted), instead of using the physics AddForce, which would produce jittering while syncing with the server.

    I wanted to know, if this is the best approach for this exact case (this particular, networked, game) for character movement, compared to:
    1. the Character Controller component
    2. setting the transforms through a custom script
    3. using AddForce
    4. setting the rigidbody's velocity
     
  2. StickyHoneybuns

    StickyHoneybuns

    Joined:
    Jan 16, 2018
    Posts:
    207
    Yes, setting the transform directly can cause a teleporting like affect if not done right and can also cause collision issues. That is why unity recommends using rb.MovePosition if you want to move the rigidbody directly.

    https://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html

    MovePosition still moves the transform directly however, if at anytime it intersects a collider it will still use correct physics even if it overshoots.

    addforce should not produce jitter when using it otherwise all physic interactions would look bad. There are pro's and con's to using any of the mentioned methods and ultimately will be decided by you.

    Personally, I would only use the character controller if you are not good at scripting, otherwise just write your own custom character controller.

    Also, you don't have to use just one method. You can implement different methods for different scenarios. For instance in my game I am currently working on. I use addforce to jump but movePosition to move.