Search Unity

[RELEASED] Easy Character Movement

Discussion in 'Assets and Asset Store' started by Krull, Apr 21, 2016.

  1. Pixelith

    Pixelith

    Joined:
    Jun 24, 2014
    Posts:
    580
    This was actually explained a little bit in one of my previous questions asking about dodging. There's a function built in called (if I remember correctly) Rotatetowards() that you can use to rotate towards the raycast hit position from your mouse click.
     
  2. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Yes, as @FireSwordStudio said, you can use the RotateTowards function, for example, in the HandleInput method, you use the same method as the one used to set the moveDirection property on mouse click, however in this case you use a new variable, eg: lookDirection when left click you set this lookDirection and when right click you set the moveDirection.

    Then in the UpdateRotation method, you check if moveDirection has a value (non zero) rotates toward this, otherwise rotate towards your new lookDirection vector.

    Regards,
    Krull
     
  3. redmotion_games

    redmotion_games

    Joined:
    May 6, 2013
    Posts:
    84
    ground snagging.JPG
    Hi Krull, I'm using your FPS controller prefab and I've added an animated character model. This is all working fine for my purposes.

    However, I'm using an environment asset (for testing) with lots of small objects (stones, small rocks, and fallen branches) with steep edges to their colliders and very uneven terrain (unity terrain). It means that the player can't step over a low fallen branch because the player gets caught against it. Or step up a steep but low rise in the ground level. It's also causing subtle sliding and shaking even on nearly flat terrain and with the character standing still.

    Turning off colliders on small rocks and branches helps with these objects but the terrain and some larger objects I'd just like the character to use as a step are still causing issues even if I set a ground mask to only look at the terrain and ground limit to 89. Ground sliding is turned off. Ground snap is on and set to 1.

    Thanks for any input you can provide.
     
    Last edited: Mar 27, 2021
  4. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @redmotion_games

    A few things to check:

    - If your model has colliders, make sure it does not collides with the capsule and is not part of the ground (walkables) layers, otherwise it will get caught by ground detection routines.

    - Make sure all the terrain debris are part of the Ground mask, otherwise those will be completely ignored by the ground detection system, causing the Character trying to snap to the 'ground' below them. And if possible group them in chunks and mark it mesh collider as convex.

    II suggest you leave the GroundDetection groundLimit in the range 60 (default value) to 80 degrees, this gives serves to separate 'ground' from 'walls' and use the CharacterMovement SlideOnSteepSlope and Slope Limit to prevent climbing unwanted 'ground'

    The same for the Snap To Ground and snapStength, its 0.5 value if the most flexible and IMO should not need to be modified.

    Last but not least, please make sure you are using the latest version as some older version introduced a ground-snap related bug fixed in latest version on store.

    This actually is not recommended, as the ground detection will not see the debris and when the character stands on them, it will try to snap to the terrain below them.

    Regards,
    Krull
     
  5. rahilsha2000

    rahilsha2000

    Joined:
    May 17, 2020
    Posts:
    2
    Check out this tutorial video for simple Player Movement
     
  6. dock

    dock

    Joined:
    Jan 2, 2008
    Posts:
    605
    Code (CSharp):
    1.   protected override void HandleInput()
    2.   {
    3.     jump = _playerControls.Player.Jump.triggered;
    4.  
    5.     if (_playerControls.Player.Jump.triggered)
    6.     {
    7.       Debug.Log("input happened");
    8.     }
    9.   }
    I'm just starting to implement ECM and having trouble with jumps not firing. I'm using the new input system but I have no reason to suspect that's the problem because the debug message is still firing.

    I keep getting a lot of ignored inputs for jump events, despite the input firing and the character being visibly grounded. How can I see why ECM rejects the inputs? Changing pre or post grounded tolerance does not help, so it appears to be something else.

    Any suggestions?
     
  7. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @dock

    I think this is caused because ECM adds some logic into the jump input property, and as such it need to be polled in a continuous way, like the old Input.GetButton("Jump") does, while triggered only tells is it was enabled that particular frame.

    With the new input system (verified version) for the jump to properly work, you'll need to setup a callback function to respond to the jump input action events (started, performed, canceled) and update the jump property value, eg:

    Code (csharp):
    1. // Jump InputAction callback
    2.  
    3. private void OnJump(InputAction.CallbackContext callback)
    4. {
    5.     if (callback.started || callback.performed)
    6.         jump = true;
    7.     else if (callback.canceled)
    8.         jump = false;
    9. }
    10.  
    11. ...
    12.  
    13. // Subscribe to jump input action events
    14.  
    15. jumpInputAction = actions.FindAction("Jump");
    16. if (jumpInputAction != null)
    17. {
    18.     jumpInputAction.started += OnJump;
    19.     jumpInputAction.performed += OnJump;
    20.     jumpInputAction.canceled += OnJump;
    21.  
    22.     jumpInputAction.Enable();
    23. }
    24.  
    Alternatively as you can see here, if using the preview version 1.1-preview.2, you could use a simpler approach, eg:

    Code (csharp):
    1.  
    2. jump = actions["Jump"].IsPressed();
    3.  
    As the IsPressed() function is a direct replacement for the old GetButton() function.

    Regards,
    Krull
     
  8. dock

    dock

    Joined:
    Jan 2, 2008
    Posts:
    605
    @Krull Ah, thanks! that explains a lot.
     
  9. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Thank you for the update, glad I could help.

    Regards,
    Krull
     
  10. wrensey

    wrensey

    Joined:
    Mar 12, 2017
    Posts:
    15
    Hey @Krull, using your asset and am having fun with it, but I was wondering if there was a way to delay the jump action so that a wind-up animation can finish before the player controller actually gets airborne.

    Basically, I have a pre-jump animation of my character getting ready to jump and I want that to play before the character leaves the ground if that makes sense.

    This is a different functionality from the 'delay jump' for after the button is pressed as sort of an anti-bunny hoping feature, I want to delay the jump even if the button has not been pressed previously
     
  11. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hello @wrensey

    I think you can wait your animation to finish, and only after it has been completed trigger the jump.

    You can use an animation event, an use it to trigger the real jump instead to let the jump be started from the input you start your pre-jump animation and once it completes trigger the jump event.

    Let me know if need further help.

    Regards,
    Krull
     
  12. jnbbender

    jnbbender

    Joined:
    May 25, 2017
    Posts:
    487
    Best controller I have but simple question. Why the Max Lateral Speed on CharacterMovement and Speed on BaseCharacterController? They appear to do the same thing.
     
  13. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @jnbbender

    The main different is CharacterMovement Max Lateral Speed is the maximum lateral speed the character can move accounting its current speed (BaseCharacterController) plus any extra speed generated by external forces, eg. the character wont move faster than this max lateral speed.

    By other hand the BaseCharacterController speed is the character's current moving speed for its current state, eg: the one you specified for walk, run, crouch, etc. e.g. your given input desired speed.

    Regards,
    Krull
     
    jnbbender likes this.
  14. wrensey

    wrensey

    Joined:
    Mar 12, 2017
    Posts:
    15
    I think I've got it, thanks!
     
  15. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Awesome! thank your for the update

    Regards,
    Krull
     
  16. xrajishx

    xrajishx

    Joined:
    Apr 21, 2019
    Posts:
    2
    Is there a way to get the character to move towards the camera is looking at? The character always moves in the same four directions when you move using WASD regardless of where you are looking at from the camera. It is a common behavior in third person games where if you keep pressing W and move the mouse, the character's direction changes. This does not seem to be how the ECM character works by default and I couldn't find any options in the script to reference a camera of any sort. I just want to confirm if this is not something that is done by ECM and I need to do myself or if I am missing something.. Thanks.
     
  17. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @xrajishx

    While ECM does not includes a third person camera controller, by default the character is moved WRT world axis, however it includes a helper extension function (relativeTo) to make your input moveDirection vector relative to your camera's view direction.

    For example, to make your movement relative to main camera's view direction:

    Code (csharp):
    1.  
    2. protected override void HandleInput()
    3. {
    4.     // Toggle pause / resume.
    5.     // By default, will restore character's velocity on resume (eg: restoreVelocityOnResume = true)
    6.  
    7.     if (Input.GetKeyDown(KeyCode.P))
    8.         pause = !pause;
    9.  
    10.     // Handle user input
    11.  
    12.     jump = Input.GetButton("Jump");
    13.  
    14.     crouch = Input.GetKey(KeyCode.C);
    15.  
    16.     moveDirection = new Vector3
    17.     {
    18.         x = Input.GetAxisRaw("Horizontal"),
    19.         y = 0.0f,
    20.         z = Input.GetAxisRaw("Vertical")
    21.     };
    22.  
    23.     // Transform the given moveDirection to be relative to the main camera's view direction.
    24.     // Here we use the included extension .relativeTo...
    25.  
    26.     var mainCamera = Camera.main;
    27.     if (mainCamera != null)
    28.         moveDirection = moveDirection.relativeTo(mainCamera.transform);
    29. }
    30.  
    You can find a working example in the included Walkthrough guide, example #3 Movement Relative to Camera.

    Regards,
    Krull
     
  18. xrajishx

    xrajishx

    Joined:
    Apr 21, 2019
    Posts:
    2
    Thank you @Krull. I should have probably went through the examples before asking the question. Thanks.
     
  19. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Don't worry about it :), let me know if need any further help.

    Regards,
    Krull
     
  20. Chilli

    Chilli

    Joined:
    Aug 12, 2012
    Posts:
    9
    Great character controller asset!
    Was wondering if there is any functionality for slowing down while moving up a slope and accelerating faster when moving down a slope?
     
  21. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hello @Chilli

    Thanks, happy to know you like it!

    No by default, as it tries to maintain the character's speed constant, however it can be simulated using the slope information to modify the speed when character's is moving up or down.

    The following code shows how to detect when character is going up or down a slope:
    Code (csharp):
    1. if (movement.isOnSlope)
    2. {
    3.     Vector3 v = movement.velocity.normalized;
    4.  
    5.     float signedSlopeAngle = Mathf.Asin(v.y) * Mathf.Rad2Deg;
    6.  
    7.     bool movingUp = signedSlopeAngle > 0;
    8.  
    9.     bool movingDown = signedSlopeAngle < 0;
    10. }
    Additionally you can use the signedSlopeAngle to get a speed modifier from a curve, so you can slow / accelerate when moving up / down slope.

    You use this speed modifier (from the curve) to modify you character's current speed property value.

    I am adding this as example to next ECM update.
     

    Attached Files:

  22. Chilli

    Chilli

    Joined:
    Aug 12, 2012
    Posts:
    9
    Oh thanks a lot for the help! That's super useful. Great idea tying it to a curve as well!
     
    Krull likes this.
  23. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi Guys,

    I am happy to let you know that ECM2 has been released! (finally! :D)

    You can find its dedicated forum post HERE

    or

    Its Asset Store page HERE

    Thank you all for your great support!
     
  24. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    22
    Hi :) Just a question: Will I be able to use this controller for animal character? I'm thinking about rotation on uneven grounds like mountains. What do you think?
     
  25. JakartaIlI

    JakartaIlI

    Joined:
    Feb 6, 2015
    Posts:
    30
    Are you broke ECM 1 on purpose ?
    I'm not going to buy another one like this, even at a discount.
    Unity 2020.3.4f1 last asset version
     
    twitchfactor likes this.
  26. Pixelith

    Pixelith

    Joined:
    Jun 24, 2014
    Posts:
    580
    You're the only person that I've seen with these issues. I've imported original ECM1 and ECM2 with no problem at all.

    It looks like you tried to combine ECM1 and ECM2 into the same project based on some of the issues I see. You should only have one or the other in a project.
     
    Krull likes this.
  27. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @JakartaIlI ,

    No, I am not that kind of person, both packages can be on same project, I have that way on my development machine whole time, and its the intended way as each package leaves on its own namespaces, so if you are having issues importing both should be caused by other reasons.

    A typical cause of those error messages is another CharacterMovement script (non ECM related) on global namespace.

    Also while using ECM1 and ECM2 on same project make sure to enable BOTH input systems, as ECM1 uses old input system and ECM2 the new unity.

    I suggest you create new project (empty), import ECM1 and then import ECM2 (requires new input system), last but not the least, as commented above, enable BOTH input systems.

    Let me know if I can be of further help.

    Regards,
    Krull
     
  28. JakartaIlI

    JakartaIlI

    Joined:
    Feb 6, 2015
    Posts:
    30
    yes, its another CharacterMovement in project,
    i am sorry, was really frustrated with the decisions of other assets that day.
     
  29. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @JakartaIlI,

    Don't worry about it, I totally understand. Glad to know your issue is fixed.

    Do not hesitate to message if need any further help.

    Regards,
    Krull
     
  30. ccjay

    ccjay

    Joined:
    Mar 24, 2014
    Posts:
    20
    I feel like this still missing a lot of features that I found in a similar package with support for different ground types and grabbing ledges / wall jumping.

    From what I recall ECM was really easy to read / abstract code wise and I liked how it was done but many edge cases I had seemed to fail for it, namely how it interacted with stairs that caused it to be more pain than it's worth.

    I see ECM2 supports steps taller than the cylinder base but is it really worth upgrading for that when I already found another tool that does that and more.. Meh..
     
    Last edited: May 17, 2021
  31. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @ccjay,

    Do you mean ECM? and ECM2? Well it is up to you if you decide to upgrade to ECM2, as ECM is not being deprecated at all, actually working on an update.

    IMO ECM2 it's a much robust system with many more features than just support for climbable steps, it's a whole new package that offers similar features to the Character and CharacterMovement class from UE4, those has been my principal inspiration since original ECM, and now with ECM2 its really on par (IMHO)

    About different ground types, yes I agree this is a planned feature for future updates, will be implemented similar to current physics volumes; while wall jump, wall grab, wall run are planned as examples too.

    Keep in mind ECM and ECM2 has been developed to serve as a general purpose tool where users can build their own game mechanics on top of it, one again, pretty much like the UE4 counterparts.

    Actually those familiar with UE4, can easily follow UE4 tutorials and adapt those to be used with ECM2, I have done it :D

    Let me know if I can be of further help.

    Best regards,
    Krull
     
    my_little_kafka and Pixelith like this.
  32. ccjay

    ccjay

    Joined:
    Mar 24, 2014
    Posts:
    20

    Sorry, Yes I meant ECM.. Posting while tired.. :confused:

    I guess my biggest question is what does ECM2 offer over ECM.. to justify the upgrade? If I compare this to other movement controller assets that are half the price they already have those "Will be added in the future" options.

    I understand I could add those features myself.. but from a cost / time benefit if I was willing to code those myself I wouldn't of bought an asset that does it for me in the first place.

    Likewise, I can understand charging for Upgrades when Unity continuously releases non-backwards compatible features to their SRP's and it requires constant upkeep from creators to keep things working.. But in this case though it seems ECM2 was just forked off ECM with a new price tag. I'm not understanding what revolutionary feature set was added here..

    Thanks for your time.
     
  33. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    First, I won't be arguing with you, if you prefer other assets that's perfectly fine, that's the beauty of a healthy competition, but please do not come making false assumptions and claiming ECM2 is just a forked version of ECM with an increased price tag.

    I am a pretty transparent and honest guy (and proud to be) and never would lend myself to those practices.

    ECM2 is a complete new product written from the ground up using much modern and improved algorithms, in the same way a new Windows version exists, or a new iPhone, etc.

    ECM2 offers a lot of new features over the still very capable ECM, for example, a robust continuous collision detection algorithm capable of graceful handling slowly shrinking corridors, angled corners and concave colliders, a common pitfall in many character controllers.

    ECM2 uses a new physical model including water buoyancy, Physics Volumes (to easily handle water, falling zones), integration with new unity input system, character events, Cinemachine, etc. Please refer to this post for the full features as see no point repeat those here.

    Those "Will be added in the future" (as you call), are part of a live and continuously improving product, so it's expected features will be added along the product life cycle.

    - Oscar Gracián (Krull)
     
    Pixelith, my_little_kafka and asored like this.
  34. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    429
    Hi @Krull , really liking the asset but getting stuck on a couple of things...

    I'd like to reverse the Shift to Walk (into Shift to Run) on the custom character controller that the Ethan character uses but can't see how it's set-up in the custom controller script. The BaseCharacterController doesn't have that functionality so I'm assuming it's in CustomCharacterController somewhere. I just can't see it in the code logic.

    That Ethan controller essentially replicates the Standard Assets 3rd person controller. One of the things I'd been able to do with that, is to make the character walk backwards when holding down the S key (i.e. a negative value on the forwardAmount and adding a new walk back animation clip in the Grounded blend tree). I've tried using the Tank walkthrough example to get the orientation right but I just can't get it working with the animator. Also the tank rotation isn't what I want. I'm trying to redo this but with your controller:


    ps. I've remove Mathf.Max(0.0f, value) in the setter for walk and run speed (so negative value would be enabled)

    Any help would be much appreciated
     
  35. VincentAbert

    VincentAbert

    Joined:
    May 2, 2020
    Posts:
    123
    Hello !
    I have a small issue where, if the player is facing a wall, pressing forward and jumping, they won't jump as high as if they were only pressing jump. The player rigidbody has the ECM default physics material so it shouldn't have friction... Would anyone know why, and how to fix it ?

    It's a big problem for me because everyone expects to have to go forward while jumping to climb on things.

    Thank you !

    PS : @jeromeWork I don't get why you would want a negative speed, it doesn't make sense. You want a positive speed, but the direction to change. Just make the moveDirection vector opposite to the player forward when pressing S ?
     
  36. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    429
    Because the 2D blend tree has the walk backwards animation on the negative Y axis
     
  37. VincentAbert

    VincentAbert

    Joined:
    May 2, 2020
    Posts:
    123
    Still though, you can't have negative speed. If the player is pressing S (or you can do some vector work if you want it to be more precise, like the dot product of the velocity and the player forward vector), simply send the speed * -1 to the animator.
     
  38. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    While working with ECM I always suggest you create a custom controller extending one of the included 'base' controllers, and use this custom controller to add your game features on top of ECM default functionality.

    For example, in the Custom Character Controller Example scene and its CustomCharacterController script, it just modifies the speed property value depending if the walk key is pressed or not.

    For example, using the same CustomCharacterController, modify the GetTargetSpeed method to:
    Code (csharp):
    1. private float GetTargetSpeed()
    2. {
    3.     //return walk ? walkSpeed : runSpeed;
    4.  
    5.     return sprint ? runSpeed : walkSpeed;
    6. }
    Then in HandleInput method, you set the sprint (a bool var) value from your input key, e.g:
    Code (csharp):
    1. sprint = Input.GetKey(KeyCode.LeftShift);
    About the Ethan controller, are you using root motion ? if no, a ECM character by default will rotate towards the given moveDirection vector as you can see in the UpdateRotation method. This can be modified in your custom controller overriding the UpdateRotation and replacing its default implementation with the one you need.

    About the negative speed, well remember a vector is both a direction and a magnitude, where the magnitude is always positive, take for example the velocity vector, its magnitude it's the speed.

    In your case I think what you need it's the forward speed, this is the signed speed relative to the character's forward direction (e.g. Vector3.Dot(velocity, transform.forward)), so moving forward will be positive and moving backwards will be negative. You can retrieve it using: movement.forwardSpeed

    Kind Regards,
    Krull
     
  39. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hey @VincentAbert

    Is your character implementing some kind of wall grab / climb mechanic ? I ask this because if it does, your character could be grabbing the wall while still jumping up cutting the jump initial impulse.

    You can take a look at the included example 10 - Wall Grab and Wall Jump, this allows the character to grab the wall only until the character's vertical velocity is negative, so it wont cut the initial jump impulse.

    And yes, as long as your ECM character capsule has its frictionless material, it will slide along a wall as long it does not hit any 'walkable' ground.

    Regards,
    Krull
     
  40. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    Could you please post some example video about humanoid character walking on stairs.
    I am really interested in the look of the feet contact with the stairs.
     
  41. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    Sorry to say, but I do not like idea that while installing ECM has Package Manager dependencies.
    It has happend to me with similar packages, that after I clicked to continue, the project becomes broken
    and it was not so easy to fix the issue.
    Maybe it is ok, if ECM is the only package in the project, but it is not practical while using many different packages from Unity asset store in the same project.
     
  42. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    You advertise ECM2 as "Fully configurable friction based movement including water buoyancy!"
    Could you please post some video with the humanoid character swimming in the water.
     
  43. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hello @Artini

    Thank you for your interest in ECM!

    About your questions:

    You can try the WebGL demo here. ECM / ECM2 does not include IK.

    Once again, you can try the WebGL demo here or the windows download version here, it is the same included in the package. The package includes over 25 examples to help you get the most of it.

    ECM2 does not include swimming animation as included animations are mostly for demonstrative purposes.

    Please keep in mind ECM / ECM2 is a general purpose character controller and not a complete out of the box project you basically mod to fit your game, with ECM / ECM2 is actually the other way, it servers as a robust platform where you build your game custom mechanics extending / complementing the functionality ECM / ECM2 provides you.

    ECM2 Takes care of all your character's interaction with your game world, allowing you to focus on your game mechanics.

    Let me know if you have any further questions.
     
    my_little_kafka likes this.
  44. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    429
    Hi Krull,

    Thanks for the reply. Walk/run thing makes sense now. Thank you.

    Re. walking backwards, I am using rootmotion so what you suggested just didn't work and yes I have my own CustomCharacterController which is extending your Base script.

    So if this is the Animate method:

    Code (CSharp):
    1. protected override void Animate()
    2.         {
    3.             // If no animator, return
    4.  
    5.             if (animator == null)
    6.                 return;
    7.  
    8.             // Compute move vector in local space
    9.  
    10.             var move = transform.InverseTransformDirection(moveDirection);
    11.  
    12.             // Update the animator parameters
    13.  
    14.             var forwardAmount = animator.applyRootMotion
    15.                 ? Mathf.InverseLerp(0.0f, runSpeed, move.z * speed) // rootmotion
    16.                 : Mathf.InverseLerp(0.0f, runSpeed, movement.forwardSpeed); // not rootmotion
    17.  
    18.             var turnAmount = Mathf.Atan2(move.x, move.z);
    19.  
    20.             animator.SetFloat("Forward", forwardAmount, 0.1f, Time.deltaTime);
    21.             animator.SetFloat("Turn", turnAmount, 0.1f, Time.deltaTime);
    22.  
    23.             animator.SetBool("OnGround", movement.isGrounded);
    24.  
    25.             animator.SetBool("Crouch", isCrouching);
    26.  
    27.             if (!movement.isGrounded)
    28.                 animator.SetFloat("Jump", movement.velocity.y, 0.1f, Time.deltaTime);
    29.         }
    and In my own version of the ThirdPersonCharacterController (my version of the Standard Assets one rather than EasyCharacterController) I have this, which allows the character to walk backwards as shown in my video:

    Code (CSharp):
    1. public void Move(Vector3 move, bool crouch, bool jump)
    2.         {
    3.  
    4.             // convert the world relative moveInput vector into a local-relative
    5.             // turn amount and forward amount required to head in the desired
    6.             // direction.
    7.             if (move.magnitude > 1f) move.Normalize();
    8.             move = transform.InverseTransformDirection(move);
    9.             CheckGroundStatus();
    10.             move = Vector3.ProjectOnPlane(move, m_GroundNormal);
    11.  
    12.            
    13.             m_TurnAmount = Mathf.Atan2(move.x, move.z);
    14.             m_ForwardAmount = move.z;
    15.            
    16.    
    17.                 // if player wants to go backwards
    18.                 if (Mathf.Abs(m_TurnAmount) > Mathf.PI * 0.5f && m_ForwardAmount < -1e-4f)
    19.                 {
    20.                     m_ForwardAmount = -1f; // walking backwards
    21.                     m_TurnAmount = 0f; // without turning
    22.                 }
    23.    
    24.  
    25.             ApplyExtraTurnRotation();
    26.  
    27.             // control and velocity handling is different when grounded and airborne:
    28.             if (m_IsGrounded)
    29.             {
    30.                 HandleGroundedMovement(crouch, jump);
    31.             }
    32.             else
    33.             {
    34.                 HandleAirborneMovement();
    35.             }
    36.  
    37.             ScaleCapsuleForCrouching(crouch);
    38.             PreventStandingInLowHeadroom();
    39.  
    40.             // send input and other state parameters to the animator
    41.             UpdateAnimator(move);
    42.         }
    43.  
    44. void UpdateAnimator(Vector3 move)
    45.         {
    46.             // update the animator parameters
    47.             m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
    48.             m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
    49.             m_Animator.SetBool("Crouch", m_Crouching);
    50.             m_Animator.SetBool("OnGround", m_IsGrounded);
    51.             if (!m_IsGrounded)
    52.             {
    53.                 m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
    54.             }
    55.  
    56.             // calculate which leg is behind, so as to leave that leg trailing in the jump animation
    57.             // (This code is reliant on the specific run cycle offset in our animations,
    58.             // and assumes one leg passes the other at the normalized clip times of 0.0 and 0.5)
    59.             float runCycle =
    60.                 Mathf.Repeat(
    61.                     m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
    62.             float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount;
    63.             if (m_IsGrounded)
    64.             {
    65.                 m_Animator.SetFloat("JumpLeg", jumpLeg);
    66.             }
    67.  
    68.             // the anim speed multiplier allows the overall speed of walking/running to be tweaked in the inspector,
    69.             // which affects the movement speed because of the root motion.
    70.             if (m_IsGrounded && move.magnitude > 0)
    71.             {
    72.                 m_Animator.speed = m_AnimSpeedMultiplier;
    73.             }
    74.             else
    75.             {
    76.                 // don't use that while airborne
    77.                 m_Animator.speed = 1;
    78.             }
    79.         }
    How would I go about doing the equivalent of :

    Code (CSharp):
    1. if (Mathf.Abs(m_TurnAmount) > Mathf.PI * 0.5f && m_ForwardAmount < -1e-4f)
    2.                 {
    3.                     m_ForwardAmount = -1f; // walking backwards
    4.                     m_TurnAmount = 0f; // without turning
    5.                 }
    in Easy Character Movement?
     
  45. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @jeromeWork

    About your questions:

    The code on Animate method, it's just an example of how to read the Character state (speed, is grounded, etc), and use those to feed you Animator parameters, so its implementation is completely dependent on your animations and your animation controller.

    ECM is animation agnostic, I mean, it does not need or use it in any way, as you can see on the capsule character who is not animated, with ECM you feed your AnimatorController parameters with the information provided by the Character.

    So in your case, you can (and should) use your old animator code to feed your animator controller, just need to use the data provided by ECM. If you prefer, you can even leave the Animate method empty, and use an external script to handle your animation, as I commented above, this is plain unity animation.

    When using root motion, you are basically controlling your animation with your input, in the end to move an ECM character (using root motion or not), you just need to set its moveDirection vector with your desired direction in world space, as you can see in the HandleInput method.

    Then the character's will use the animation velocity to perform the character movement.

    Additionally, you can let your root motion handle the character rotation, just need to set the root motion rotation property to true.

    As you already did, since it is animation related, you can add it to the Animate method (if you are using it) or to the function / script where you are handling your animation (feeding animator controller).

    Regards,
    Krull
     
  46. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    Hi,
    we experience a movement where our character slows down, accelerates, slows down etc. noticeable at low speed values. It's a really simple setup. On higher speed values it isn't that much noticeable.
    Any ideas to what might cause this issue would be appreciated.

    Edit: looks like it was an editor related issue - its gone in the build
     
    Last edited: Jun 11, 2021
  47. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi @Marco-Sperling

    Thank you for the update, happy to hear your issue is solved.

    Please do not hesitate to message me (or post here) if you need any help.

    Regards,
    Oscar
     
  48. WryMim

    WryMim

    Joined:
    Mar 16, 2019
    Posts:
    69
    Thanks for the great asset!
    Can you tell me how to implement a catapult? If I just get a Rigidbody of the player and apply force AddForce(force, ForceMode.Impulse) then the player does not fly but is sharply transferred (that is not natural)
     
  49. WryMim

    WryMim

    Joined:
    Mar 16, 2019
    Posts:
    69
  50. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hello @WryMim

    First of all thank you for purchasing ECM and happy to hear you like it!

    About your question, the best way to handle this is like a jump or a bouncer adding an impulse to the character, however worth note ECM implements a ground snap feature to prevent the character being launched off ramps / slopes and because of this, you need to explicitly tell when your character is allowed to leave the ground (such as jumping) using the DisableGrounding method.

    An ECM character at great sight works by accelerating / decelerating the Rigidbody velocity towards our given desired velocity, so all its movement its affected by the character's current settings (eg: speed, acceleration, deceleration, friction, etc) so it's a common method to keep a set of this properties for each of your character states (eg: walking, running, falling, etc), and update the Character properties (speed, accel, decel, etc) depending of your character's current logical state.

    Last but not least, CharacterMovement Speed Limiters (Max Lateral Speed, Max Rise Speed and Max Fall Speed) define the maximum velocity a character can move, so make sure update this accordly to your catapult impulse (eg: set all those to a 20 or 30 value) otherwise it will cut your catapult impulse.

    Now back to the 'bouncer' I created a basic script (shown below), this will launch the character along this bouncer up direction. As you can see it temporarily disables the ground snap feature to allow the character to leave the ground.

    - Bouncer example, this will apply a vertical impulse to the character, similar to how its jump works:

    Code (csharp):
    1.  
    2. public class Bouncer : MonoBehaviour
    3. {
    4.     public float bounceImpulse = 20.0f;
    5.  
    6.     private void OnTriggerEnter(Collider other)
    7.     {
    8.         BaseCharacterController characterController = other.GetComponent<BaseCharacterController>();
    9.  
    10.         if (characterController == null)
    11.             return;
    12.  
    13.         // Temporary pause grounding to allow the character leave the ground
    14.  
    15.         characterController.movement.DisableGrounding();
    16.  
    17.         // Apply a bounce impulse, preserving character's lateral velocity and overrides its vertical velocity with bounce impulse
    18.  
    19.         Vector3 characterVelocity = characterController.movement.velocity;
    20.  
    21.         Vector3 characterUp = transform.up;
    22.  
    23.         Vector3 characterLateralVelocity = Vector3.ProjectOnPlane(characterVelocity, characterUp);
    24.  
    25.         characterController.movement.velocity = characterLateralVelocity + characterUp * bounceImpulse;
    26.     }
    27. }
    28.  
    To use it, simply add this Bouncer script to a trigger collider.

    Kind regards,
    Krull