Search Unity

Standard Unity 2D Character script not working with Surface Effector 2D

Discussion in '2D' started by DarkPine, Nov 17, 2016.

  1. DarkPine

    DarkPine

    Joined:
    Oct 5, 2016
    Posts:
    9
    Using these two standard unity package scripts:
    Platformer2DUserControl - Used mainly as a input that sends info to PlatformerCharacter2D
    PlatformerCharacter2D - Does the actual work.

    Those two scripts are attached to my Character that also has a Rigidbody 2D and 2D Collider. If I disable "Platformer2DUserControl" the "Surface Effector 2D" script attached to the platform works as expected. When "Platformer2DUserControl" is enabled the "Surface Effector 2D" has no effect on the character.

    Is there a way to change the default/standard Unity character control script so the Surface Effector 2D works when the character stands on the platform?

    The default "PlatformerCharacter2D" where the movement is made:

    Code (CSharp):
    1.  
    2.             //only control the player if grounded or airControl is turned on
    3.             if (m_Grounded || m_AirControl)
    4.             {
    5.                 // Reduce the speed if crouching by the crouchSpeed multiplier
    6.                 move = (crouch ? move*m_CrouchSpeed : move);
    7.  
    8.                 // The Speed animator parameter is set to the absolute value of the horizontal input.
    9.                 m_Anim.SetFloat("Speed", Mathf.Abs(move));
    10.  
    11.                 // Move the character
    12.                 m_Rigidbody2D.velocity = new Vector2(move*m_MaxSpeed, m_Rigidbody2D.velocity.y);
    I commented out "m_Rigidbody2D.velocity = new Vector2(move*m_MaxSpeed, m_Rigidbody2D.velocity.y);" and Surface Effector works on the platform moving the character, but you obviously cannot control the character with that disabled, so is there a way to fix this?
     
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Try replacing it with this line:
    Code (CSharp):
    1. m_Rigidbody2D.AddForce(move * m_MaxSpeed * Vector2.right, ForceMode2D.Impulse);
    The problem is that the code is setting your Rigidbody2D velocity directly, overriding any outside forces from affecting the velocity. This code will change the movement to only add a force to the character, and let the physics system determine the final velocity, all other forces considered.

    You may need to tweak your speed values, and it probably wont feel exactly the same because the speed changes are gradual instead of instant.
     
  3. DarkPine

    DarkPine

    Joined:
    Oct 5, 2016
    Posts:
    9
    @jeffreyschoch

    Thank you for providing solution. You are right about the change in overall feel.

    I was not planning to use the Surface Effector 2D; the fact it was not working with the standard 2D character controller was unsatisfying. It irritates me when something seemingly default doesn't work as expected. Gives an overall sense of, "If this default components do not work together, how am I going to get my own to work right?"

    If I wanted a platform to do this in the future keeping the current feel of responsiveness in control I would do a ground check for a game object with a name or script that identifies that it is a conveyor belt and that character control would then apply the force directly. I am not sure if that is correct, but from my layman's understanding I think that might be an additional alternative.

    Come to think of it, I would just need to look at a 2D moving platform example to get an idea of how that would work and instead of the platform moving with the character it would stay still and move the character.

    Thank you again for giving a solution that gives me closure. It might sound odd, but if I left this issue without some sort of solution I would feel cheated in gaining understanding is problem solving.
     
  4. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Unfortunately the only way in the past I've been able to accomplish "stop on a dime" style unrealistic physics using the built-in components was to use very high drag, along with very high forces to overcome this drag for motion. This is not ideal, but results in a character that stops as fast as you want when no forces are applied, but can also interact with all the built in physics components. It takes a fair amount of fiddling with the equilibrium between drag and forces.
     
  5. shanefolden

    shanefolden

    Joined:
    Sep 6, 2020
    Posts:
    3
    I am having the exact issue, but am having trouble using your solution with my code, any chance of an assist?


    Code (CSharp):
    1.     private void ApplyMovement()
    2.     {
    3.         rb.velocity = new Vector2(movementSpeed * movementInputDirection, rb.velocity.y);
    4.     }
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,497
    FYI: I answered your post here. Above also answers your issue though.