Search Unity

[RELEASED] Easy Character Movement 2

Discussion in 'Assets and Asset Store' started by Krull, May 5, 2021.

  1. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @aaronct123

    Beginning with version 1.4.0 (the current version), the package is input agnostic, allowing it to be compatible with any input system or package of your choice. However, the provided examples are still based on the older input manager.

    Having said that, I plan to update documentation to include a new input system example. In the meantime, you could check the package @neptoonism kindly shared with us.
     
  2. Dawid_Matuszewski

    Dawid_Matuszewski

    Joined:
    Mar 2, 2016
    Posts:
    23
    Hello @Krull
    I have a (probably) strange question. I'm using Easy Character Movement 2 and Cinemachine Camera. I have First person view and everything set on default. Many players complains about motion sickness. I don't have any post procesing, blur and other visual things.This is probably on different updates is ECM2 and Cinemachine brine. Do you know how to make them smooth move all together?
     
  3. mookfasa

    mookfasa

    Joined:
    Dec 21, 2016
    Posts:
    46
    @Krull I have a character grabbing an object with a rigidbody and a collider attached to it. That object will be parented under the ecm controller. The issue I am having is that the the object it not being respected and going through walls. Is there any way to fix this with the kinematic settings of the controller? I guess my question is you can do this on ecm1 since its a rigidbody controller. Is there a way to make the emc2 a rigidbody controller when holding something
     
    Last edited: Feb 15, 2024
  4. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @Dawid_Matuszewski

    One possible cause I could think of for this (as not reported / experimented before), is to make sure your Cinemachine camera is being updated in a late update, as Cinemachine by default uses
    Smart Update which could cause issues.

    Additionally if this is in VR one cause of motion sickness is the application dropping below the visor required refresh rate.
     
  5. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @mookfasa

    Given that ECM2 is a kinematic rigidbody, Unity expects us to handle collision detection and response ourselves. Thus, it delegates full responsibility to us for managing these cases. One approach is to make your carried object a regular (dynamic) rigidbody and use a joint to 'attach' it to the Character. This approach mirrors how games like Half-Life, Portal, etc., handle carrying objects, where the joint can break upon collisions.

    Another option is to expand your character's capsule dimensions while grabbing the object, effectively encompassing the carried object. This method allows for a more integrated handling of the carried object within the character.

    Lastly, if more control is required, you will need to implement a form of collision detection and response specifically for the carried object. This involves detecting collisions/overlaps and resolving them accordingly. By doing so, you gain finer control over how the carried object interacts with the environment and other objects in the scene.
     
  6. mookfasa

    mookfasa

    Joined:
    Dec 21, 2016
    Posts:
    46
    That makes all makes sense. The object is a box that is bigger than the character. I think I would need to code all the physics which is out of scope of what I am capable of.
     
  7. Ache_11

    Ache_11

    Joined:
    Apr 3, 2017
    Posts:
    4
    Hi, I am using ECM2 for a personal project and I am struggling with a specific "mechanic" I want to implement. I thought that maybe I could get some advise here on how I could achieve my goal.

    The project's pitch
    A stealth game in first person view where the player can switch between controlling the character and controlling his right hand to execute puzzles while avoiding making sounds with the objects he's holding / is interacting with and that are required for solving puzzles. AI enemies are patrolling around and the game relies a lot on physics interactions.

    Approaches I tried

    1 - For now, the best way I found for controlling the hand is through the animation rigging package, by applying a two bone IK constraint that is controlled by an IK target. All the hand movement logic is in a script attached to the IK target, but I have trouble getting the hand to move realistically. The goal is to have the hand move in the right half of the camera screen without going outside its limits. When in "hand control" mode, the FOV of the first person camera is slightly reduced and the hand is supposed to stay fully extended so that it can be moved along a 2D plan using the gamepad's right stick (frozen on the Z axis). The depth of where the hand can go would be indirectly managed by the player who can still move with the left stick in "hand control" mode, but slower.

    2 - I also tried another approach by making the IK target movement relative to a pivot point that is set at the shoulder level and by making a spherical coordinate system for the movement logic to make it move "on the surface" of an imaginary sphere that has the shoulder as its center and a radius that is equal to the length of the arm. But for some reason, the movement is not consistent and I still can't figure out how to freely move the hand on a specific part of the sphere without the input for the X and Y axis getting messed up. With this approach, the next step would be to not limit the hand by the camera screen border, but rather use cinemachine to make the camera follow the hand / IK target, but this is the next step, and I need to figure this out first.

    image.png
     
  8. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @Ache_11

    While ECM2 would assist solely with locomotion, it won't address the hand movements. For the hands, some form of inverse kinematics is necessary. If the built-in rigging package isn't sufficient for your needs, I recommend exploring the Final IK product. It offers a robust and comprehensive IK solution that is definitely worth considering.
     
  9. Dawid_Matuszewski

    Dawid_Matuszewski

    Joined:
    Mar 2, 2016
    Posts:
    23
    hello, it's not VR.
    I checked every update mode. But in closer test the movement with ECM2 is also jittering. When I moved left-right without camera rotation I can see and sense some "micro jumps". I tested ECM2 with normal camera (not cinemachine) and to be honest the movement is also jittering. I disabled all post procesing effect and so on. Our game is working on 60 fps without droping below.
     
  10. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @Dawid_Matuszewski

    Frankly, I haven't noticed any jitter or received reports of jitter issues before. However, if the default ECM2 implementation isn't working for you, the system is flexible enough for you to easily modify its default functionality to suit your game's needs.

    By default, a Character is simulated after the internal physics engine to ensure seamless physics interactions. This is achieved by implementing a Late FixedUpdate (i.e., a Coroutine), so it requires Rigidbody interpolation enabled and Unity's Auto Simulation enabled. This is important because some other packages, mostly networking libraries, tend to disable Auto Simulation, causing the system to move at your physics time step without any interpolation, resulting in unpleasing movement.


    If you need / prefer, you can disable the Character auto simulation, and manually simulate your character in a regular Update, however I strongly advice implement at least a kind of semi-fixed timestep to simulate your character(s).

    Another option within the default implementation is to prevent your character from rotating. Since a capsule inherently lacks a distinct forward direction, rather than rotating the character directly, you can rotate a pivot (a child Transform) that serves as the parent of your camera. You can then utilize this transformed pivot to define your character's forward and right directions so your movement will now be relative to this transform rather than the capsule (not rotated at all).
     
  11. giraffe1

    giraffe1

    Joined:
    Nov 1, 2014
    Posts:
    301
    edit* Please disregard, I found the teleport method.

    -------------------------------------------------------------------------------------

    Hi,

    I am using the world streaming asset, Gaia Pro. It has an option to apply world origin shifting.

    What would be the recommended way to move the character controller position? Can I just apply the adjusted position to the root transform.position? Or is there a different way or method that I should use?

    Thanks
     
    Last edited: Mar 5, 2024
  12. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @giraffe1

    I recommend utilizing the Character TeleportPosition feature for this purpose. Doing so disables interpolation, preventing the character from moving too quickly between its previous and new positions.
     
    giraffe1 likes this.
  13. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    72
    Hi @Krull

    I have typically just been using the Character Movement and then creating my own Character Script, but since the latest update CharacterMovement.SimpleMove doesn't seem to be working for me. Is there something I should be looking for? I can see that in the same method I call SimpleMove the desired Velocity is ! zero

    Regards
     
    Last edited: Mar 7, 2024
  14. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @Broudy001

    I believe the issue lies with the last parameter, deltaTime, which is now required. However, the function still allows it to be optional. Consequently, if deltaTime is not passed as a parameter, its value defaults to 0 resulting in zero velocity. This will be fixed in the following update, in the meantime just pass the Time.deltaTime as parameter.
     
  15. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    72

    Thank Heaps, that was it, I got your email response as well, but handy to have it here as well.

    Thanks again for the amazing asset, its always my go to for character controllers.
     
    Krull likes this.
  16. Fourius_Craft

    Fourius_Craft

    Joined:
    Oct 3, 2021
    Posts:
    1
    Hi, does this asset support Photon Fusion? Are there any things I should be aware of?
     
  17. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi,

    Not by default, as it requires some state synchronization. Having said that, I expect to release this week an ECM2 update including networking examples for fusion and fishnet featuring client-side prediction and reconciliation.
     
    Last edited: Mar 26, 2024
  18. jmge-ch

    jmge-ch

    Joined:
    Jan 21, 2023
    Posts:
    1
    Hi, just updated to 1.4.0 and looking for an example on how to use the new input system for a third person character. Have the tutorials/walkthroughs not been updated? Did I miss something? Thanks :)
     
  19. ademec

    ademec

    Joined:
    Oct 18, 2022
    Posts:
    1
    Hey. I've made a script "ObjectPickup.cs" that allows the player to grab rigidbodies similar to Half-Life 2, by using RigidBody's AddForce to change its position to stay in front of the player's camera, and AddTorque to rotate it. The script works well, but in some instances, it can apply a lot of undesired velocity to the player. I still want it to collide with the player, which is why I havn't just used the IgnoreCollision method. Funnily enough, it also suffers from the same issue as HL2, where if you "grab" an object that you are standing on, you can launch yourself high into the air, or alternatively jump on it repeatedly to "fly".
    Note that the grabbed rigidbody gets its .interpolation property set to RigidbodyInterpolation.Interpolate in order to prevent jitter (but disabling it doesn't have any effect on the issues). useFlatBaseForGroundChecks is set to True.

    would you mind pointing me in the right direction for how to solve this, if possible?

    I'm using the newest 1.4.0 (very nice update btw)
    Things i've tried:
    - Subscribing to the CharacterMovement.collisionResponseCallback event, and setting both characterImpulse and otherImpulse to zero vectors if the collider matches grabbed RB. This appears to have an effect, but only in some cases as the event doesn't always seem to fire - it fires most of the time when pushing the RB towards me from the side, but not always - the object still pushes the player slightly. It NEVER fires when standing on top of the RB, even when the RB causes the player to elevate.

    - Subscribing to the CharacterMovement.collisionBehaviourCallback event, and returning (CollisionBehaviour.CanNotRideOn | CollisionBehaviour.CanNotPerchOn | CollisionBehaviour.CanNotStepOn) if the collider matches grabbed RB, otherwise returning CollisionBehaviour.Default. Note that if I include the NotWalkable, it causes my character to push the grabbed RB into the ground when I walk on it, and feels very weird.

    - Checking whether the CharacterMovement.groundCollider equals grabbed RB collider in ObjectPickup.FixedUpdate(), and if true, stop applying any Force/Torque to the grabbed RB. This works, but only when standing still on top of the RB. If i jump, or push myself to the side without standing on top of the grabbed RB, it still tends to break and launch me to the moon.

    First example shows the bug

    Second example shows the bug after trying the "CharacterMovement.collisionResponseCallback" fix mentioned above
     
    Last edited: Apr 4, 2024
  20. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi,

    ECM2 is input agnostic, meaning the package doesn't depend on any specific input package and can be used with whichever one you prefer. However the included examples use the input manager (old) as this is still the most common.

    With that said, I'm finalizing an ECM2 update that will include a basic example demonstrating how to utilize the input system. The process is quite straightforward, and the recommended approach is to use the PlayerInput component, as it streamlines many tasks for us. Essentially, all we need to do is create input action event handlers. This example is part of the upcoming 1.4.1 version slated for release this week.
     
  21. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @ademec

    A few observations about how the CM works:

    Being a kinematic character controller, we are fully responsible for handling collision detection and responses. However, the physics engine will still manage collisions and responses involving other Rigidbodies (non-kinematic) interacting with us. Internally, the physics engine perceives a kinematic rigidbody as a regular rigidbody but with infinite mass.

    A Character (being kinematic) only will be affected by others (characters or non-kinematic rigidbodies) when physics interaction is enabled, so the CharacterMovement will handle collisions against others, this occurs in the CharacterMovement ResolveDynamicCollisions method where it compute resolution impulses based on masses and (as you already did) can be modified through the collisionResponseCallback function, so setting both impulses to zero will prevent the character being pushed by other, however its important to note a Character will adjust its position in case of overlaps, I mean, if the other object starts overlapping the character's capsule, the character will move away of this overlap regarldes the Enable Physics Interaction value

    A Character (being kinematic), will only be influenced by other characters or non-kinematic rigidbodies if physics interaction is enabled. For example, in demo scene drag a green cube against the character with physics interaction disabled, it wont move at all unless an overlap occurs.

    When physics interaction is enabled, the CharacterMovement component will manage collisions with others. This happens within the ResolveDynamicCollisions, where resolution impulses are computed based on masses. These impulses can be adjusted via the collisionResponseCallback function, for example, setting both impulses to zero will prevent the character from being pushed by others.

    However
    , it's important to note that a Character will adjust its position in case of overlaps. In other words, if another object begins to overlap the character's capsule, the character will move away from this overlap regardless of the Enable Physics Interaction value.

    Yes, the collision response is independent of platforms management, where a Character will only be affected by a dynamic platform if Impart Platform Movement is enabled.

    As you can see in the CharacterMovement ResolveDynamicCollisions method, it wont compute impulses if the 'other' is walk-able as this will push character off platforms.


    I suggest you first try testing your grab mechanics with Enabled Physics Interaction and all Impart Platform settings disabled. This will help isolate collision responses and platform management, making it easier to pinpoint the cause and determine how to solve it.

    From there you could use the CharacterMovement.collisionBehaviourCallback to model the how the character should hanlde the 'other' when walking into it. I think in this case just using CollisionBehaviour.CanNotRideOn should be enough in order to prevent it being used as a dynamic platform.

    Additionally, you can utilize the Collided event to check for any collision, regardless of whether it involves ground, obstacles, other characters, non-kinematic rigidbodies, etc. This event reports all the collisions and overlaps encountered during the character's last move call.
     
    Walter_Hulsebos likes this.
  22. Walter_Hulsebos

    Walter_Hulsebos

    Joined:
    Aug 27, 2015
    Posts:
    46
    1.4.1 is a great update samples-wise! Nice job.
    One note is that the required assemblies should probably be referenced in the ASMDEF (via name, not GUID) .
    They're not hard requirements, so if some are missing no warnings or errors show up.
     
  23. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @Walter_Hulsebos

    Thank you for your comments, happy to hear you liked the update!

    Thank you for the suggestion! Regarding this, are you receiving any error messages from the update?
     
  24. Walter_Hulsebos

    Walter_Hulsebos

    Joined:
    Aug 27, 2015
    Posts:
    46
    Not when simply installing the update, but when you import the NetCode Sample via the UnityPackage.

    I'd have to try again to get the exact errors, but it couldn't find the namespaces/types it needs for NetCode when I import that sample.
    Because it's not referenced in the assembly definition it doesn't have access.

    EDIT: The FishNet sample does not have this issue, it exports outside the ECM2/v1.4 folder, which makes it so it's not tied to an ASMDEF, which avoids the issue.
     
    Last edited: Apr 5, 2024
  25. Walter_Hulsebos

    Walter_Hulsebos

    Joined:
    Aug 27, 2015
    Posts:
    46
    Actually, when I use FishNet I do get errors from the code generation: (I've tried 4.1.6R and 4.1.5R)
    I guess FishNet doesn't follow proper SemVer if they're doing big API changes like that in a minor or patch version. I think I'll stick with NGO then.
    upload_2024-4-5_19-38-39.png

    ```
    FishNet.CodeGenerating.ILCore.FishNetILPP: (0,0): error - Replicate method Simulate within PlayerController requires exactly 4 parameters. In order: replicate data, asServer boolean, channel = Channel.Unreliable, replaying boolean.
    ```
    ```
    FishNet.CodeGenerating.ILCore.FishNetILPP: (0,0): error - Reconcile method Reconciliation within PlayerController requires exactly 3 parameters. In order: replicate data, asServer boolean, channel = Channel.Unreliable.
    ```
    ```
    PostProcessing failed: Unity.ILPP.Runner.ILPostProcessorDiagnosticsException: FishNet.CodeGenerating.ILCore.FishNetILPP: (0,0): error - Replicate method Simulate within PlayerController requires exactly 4 parameters. In order: replicate data, asServer boolean, channel = Channel.Unreliable, replaying boolean.
    ```
    ```
    (0,0): error - Reconcile method Reconciliation within PlayerController requires exactly 3 parameters. In order: replicate data, asServer boolean, channel = Channel.Unreliable.
    ```
     
  26. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Ah, I see, thanks for the clarification. I am not familiar with this since I mostly use Rider for development. I'll fix this in a following update.

    Regarding the error messages, I suggest completely removing the ECM2 folder before importing the 1.4.1 version. This update modifies the folder structure by removing the version (1.4.0) from it, which will definitely cause duplicates, etc. So the new (and future folder structure) is without version number, i.e:

    ECM2
    -> Editor
    -> Examples
    -> Shared Assets
    -> Source
    -> Walkthrough
    -> README.md

    Regarding the specific FishNet version, they have probably made some changes in their latest release (after the ECM2 update) (need check it).

    This was actually one of the reasons why the FishNet example lags behind Fusion, as their development is changing quickly. Therefore, I decided to wait for a more stable version.
     
  27. Fleaw

    Fleaw

    Joined:
    Dec 15, 2016
    Posts:
    1
    It seems ECM2 FishNet example use PredictionV2.
    You can enable PredictionV2 from the menu : Fish-Networking > Experimental > PredictionV2 > Enable.
     
    Walter_Hulsebos and Krull like this.
  28. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Yes, thats correct. FishNet example is based on version 4 and PredictionV2.
     
  29. Zultron

    Zultron

    Joined:
    Dec 26, 2012
    Posts:
    57
    @Krull Hi, I have a simple question. I am looking at Character.cs, but I can't seem to find a way to check which leg is currently on the ground. I have a case where I have left and right animation Stop and I need to somehow check which current leg is in animation cycle to trigger my animation booleans to stop accordingly. Perhaps you can suggest good way of doing it for my root motion character.
     
  30. Zultron

    Zultron

    Joined:
    Dec 26, 2012
    Posts:
    57
    Just realised I can do checks on Animator.pivot
     
  31. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @Zultron,

    ECM2 manages all locomotion-related movements based on its capsule collider. However, it does not perform any animation-related tasks. This means you are free to use plain Unity code to handle your animations or any other animation method your game requires.

    One approach used by unity ethan character animation (specific to this animation and how it was animated) is check its animation normalized time as show in included example:

    Code (CSharp):
    1. // Calculate which leg is behind, so as to leave that leg trailing in the jump animation
    2. // (This code is reliant on the specific run cycle offset in our animations,
    3. // and assumes one leg passes the other at the normalized clip times of 0.0 and 0.5)
    4.  
    5. float runCycle = Mathf.Repeat(animator.GetCurrentAnimatorStateInfo(0).normalizedTime + 0.2f, 1.0f);
    6. float jumpLeg = (runCycle < 0.5f ? 1.0f : -1.0f) * forwardAmount;
    7.  
    8. if (_character.IsGrounded())
    9.     animator.SetFloat(JumpLeg, jumpLeg);
    Additionally, if necessary (and without using any IK solution), you can perform a short raycast from your model's feet. This allows you to determine which foot is on the ground or not.
     
  32. Kinami37

    Kinami37

    Joined:
    Jun 12, 2016
    Posts:
    17
    hi did you forget to add the input example mentioned in the changelog into 1.4.1? i cant find it under Examples

    I am actually really disappointed by the 1.4 update and the change in input system.
    Going to stick with prior versions since the 1.4 basically breaks my whole project lol

    Dont understand the change, i think it was completely unnecessary and is confusing

    Also what happend to all the other changelogs? Why cant i see before 1.4
     
    Last edited: Apr 12, 2024 at 3:31 PM
  33. Xwad

    Xwad

    Joined:
    May 14, 2020
    Posts:
    40
    Hello! I am trying to implement a "Idle to Run" animation to my non root motion character. How should i move the character when the animation is played? Maybe i could use a curve for controlling the position of the character so it matches the animation?
     
  34. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @Kinami37,

    As previously mentioned, the changes are based on the feedback received from users during this time. As stated in the change logs, version 1.4.0 is a comprehensive package revision. Therefore, it is recommended to import it into a separate project before merging it into your main project, as it introduces significant changes.

    About the input system usage, It is located in the Walkthrough Guide, Example 2.3 under the 'Controlling a Character' section. Additionally, you can find its documentation here.

    Changelogs before version 1.4 are not included in the updated documentation. Please feel free to contact me via email support (please include your invoice number) if you require access to previous packages.
     
  35. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    770
    Hi @Xwad,

    Yes, you could take a look at the included animation example, where its AnimationController uses a 'Forward' parameter to blend from idle to walk to run animations.

    This 'Forward' parameter is updated based on the character's speed using the 'inverseLerp' method, which essentially creates a linear curve.

    You can follow the same approach but feed the result of 'inverseLerp' (a value from 0 to 1) to your animation curve and use its result to update your AnimatorController accordingly.
     
    Xwad likes this.