Search Unity

scripting a dodge-roll with rigidbody component that doesn't pass through walls

Discussion in 'Scripting' started by Tarball, Jan 20, 2018.

  1. Tarball

    Tarball

    Joined:
    Oct 16, 2016
    Posts:
    166
    I rolled my own character controller a while back and thought everything was fine. Now that I've done some level design, I notice that when my character does a dodge-roll with the following coroutine:

    Code (CSharp):
    1.     IEnumerator Roll_Routine(Vector3 roll_direction)
    2.     {
    3.         rolling = true;
    4.         Vector3 position_a = rb_player.transform.position;
    5.         Vector3 position_b = rb_player.transform.position + (roll_direction * 3.5f);
    6.         float elapsed_time = 0f;
    7.         while (elapsed_time < lerp_time)
    8.         {
    9.             float ratio = elapsed_time / lerp_time;
    10.             Vector3 position_c = Vector3.Lerp(position_a, position_b, ratio);
    11.             rb_player.MovePosition(position_c);
    12.             elapsed_time += Time.fixedDeltaTime;
    13.             yield return new WaitForEndOfFrame();
    14.         }
    15.     }
    He goes right through colliders. I tried attaching this script to player character:
    http://wiki.unity3d.com/index.php?title=DontGoThroughThings
    and I still go through colliders when rolling. Collision detection is set to "continuous dynamic" and interpolate to extrapolate.

    What's a better way to code a rigidbody dodge-roll? Root motion is not an option. Thanks.
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Do you normally move with move position or with physics? I'm pretty sure MovePosition should be called in FixedUpdate.

    If by any chance you normally move with physics, I would suggest that you can do your animation and simply move the character as you usually do and that should "just work".
     
  3. Tarball

    Tarball

    Joined:
    Oct 16, 2016
    Posts:
    166
    Thanks for the help again. I see that I was using fixedDeltaTime yet WaitForEndOfFrame(). I changed it to WaitForFixedUpdate(), but still no luck.

    I usually use MovePosition. I was under the impression that that was the way it was done. The lerp above is essentially how I move but with an only-move-while-pressed kind of movement. What I want here is a quick lunge -- like a jump but horizontal. I've tried using AddForce with ForceMode.Impulse but it never felt very smooth.
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Fair enough. I've never felt comfortable moving my character with MovePosition, but I have seen other people that do, like yourself. :)
    Perhaps you should have your collision detection inside this coroutine? Since it's actually being moved there, to me that makes some sense. For instance, if you raycast to your target of your move and hit something, then only move the distance available and break out?
     
  5. Tarball

    Tarball

    Joined:
    Oct 16, 2016
    Posts:
    166
    Well, I just replaced the coroutine by a one-liner:
    Code (CSharp):
    1.             rb_player.AddForce(750f * rb_player.transform.right, ForceMode.Impulse);
    2.  
    with a player character mass of 100kg. It works perfectly. It seems you are correct sir -- it should just work. I don't remember why I thought it was not smooth. It seems totally fine. Thanks for the heads up.
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, to be fair, when I said that I was talking about the physics system with a non-kinematic rigidbody. When I asked if you always use MovePosition, I assumed you use a kinematic one.
    But it's working now, do you still use that script you linked to keep it from going through the walls, yeah?
     
  7. Arqae

    Arqae

    Joined:
    Nov 15, 2018
    Posts:
    4

    I am using movePosition because its feels more snappy i can't seem to get velocity nor force to move like that, its always take ages to decrease down from max speed to no speed at all