Search Unity

[RELEASE] Easy Character Movement 2

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

  1. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Easy Character Movement 2

    Easy Character Movement 2 is a feature-rich, highly customizable, general purpose (not game-genre tied) rigidbody-based character movement system, yet incredible easy to use.



    DESCRIPTION

    ECM2 is a powerful character controller, highly customizable and easy to use.

    ECM2 has been written from the ground up improving the very capable ECM with a much more robust continuous collision detection system (aka Collide and Slide).

    This new Collide And Slide algorithm is capable of detecting and resolving future collisions allowing the character to gracefully traverse the world geometry.

    ECM2 sweeps your character's full capsule collider (not a floating shrinked representation of it) this ensures full contact detection and transparent use of Unity's OnTriggerXXX OnCollisionXXX functions.

    With ECM2 you are in full control of all your character interactions, you can easily decide to ignore a specific collider, prevent / allow pushing other characters, should apply standing downforce?, should your character be affected by external forces? etc.

    ECM2 can be used for any kind of character (player or AI controlled) and for a wide range of games like, platformer, first person, third person, adventure, point and click, and more!

    ECM2 has been developed with extensibility in mind so you can rest assured it will serve you as a robust platform to build your game and to add your unique game mechanics on top of it.

    ECM2 includes 30+ examples, ranging from using the new input system custom actions, PlayerInput component, first person, third person, target lock, twin-sick movement, dash, slide, ladders, Cinemachine, Bolt, and many more! Extensive documentation, and fully commented readable source code.


    FEATURES
    • Rigidbody-based general purpose character movement.
    • Capsule-based character collisions.
    • Full integration with Unity New Input System (but not limited to).
    • Cinemachine and Bolt integration examples.
    • Highly configurable and robust, ground and collision detection and response system based on the well-known Collide and Slide algorithm.
    • Ability to climb high steps (higher than capsule radius), up to character’s height.
    • Different movement modes and states, like walking, falling, unlimited variable height jump, crouching, sprinting, flying, swimming.
    • First person, Third person, Agent “base” characters.
    • Different template scenes (First person, Third person, Side scroller, Top down) for faster startup.
    • 30+ examples including custom input actions, Cinemachine and Bolt integration, first person, third person, character events, bouncers, fly, swim, dash, slide, ladders, and much more!
    • Developed with extensibility in mind, can be used as it is, extend one of its “base” characters or simply take control of them using controllers such as other scripts or visual scripts (e.g. Bolt).
    • Physics Volumes, to easy handle water, falling zones, etc. with configurable properties.
    • Fully configurable friction based movement including water buoyancy!
    • Root motion support.
    • Moving platforms without parenting.
    • Custom gravity and up direction (eg: mario galaxy like).
    • Full control over how a character is affected (or not) by external forces, platform velocity, platform movement and / or rotation, push other rigidbodies and or characters.
    • Character events like, GroundHit, MovementHit, Landed, WillLand, Jumped, ReachedJumpApex, etc.
    • Extensive and configurable collision filtering.
    • Easy integration into existing projects.
    • Fully commented C# source code. Clear, readable and easy to modify.
    • Mobile friendly.
    • Garbage-Collector friendly.
    • And much more!

    FAQ

    Do I have to use new input system?

    No, while ECM2 uses Unity New Input system by default, you can completely ignore it an replace it with any other input system you prefer. ECM2 It include several examples of how to make use of old input system.

    Can I use URP/HDRP with ECM2?

    Yes, ECM2 doesn’t do any rendering, it’ll work with any render pipeline. The demos are made using the Standard Render Pipeline (built-in), as it’s still the only stable one, and the most common denominator, but you can use any RP you prefer.


    TECHNICAL DETAILS

    - ECM2 requires Unity's New Input System and is recommended to install it before importing ECM2 into your project as this will ease the ECM2 import process.

    - ECM2 includes Cinemachine based examples, this are distributed as a .unitypackage, so before unpack this, please make sure to install the Cinemachine package into your project.

    - ECM2 includes Bolt based examples, this are distributed as a .unitypackage, so before unpack this, please make sure to install Bolt into your project.


    ASSET STORE PAGE
    Easy Character Movement 2


    DEMOS

    WebGL Demo
    Windows Demo



    DOCS AND SUPPORT

    User Manual
    API Reference
    Email








    Please don’t hesitate to post any questions, doubts or issues on the package. I’ll be happy to help you.
     
    Last edited: Jun 2, 2021
  2. my_little_kafka

    my_little_kafka

    Joined:
    Feb 6, 2014
    Posts:
    47
    I'm a big fan of the first version, glad to see this asset evolving!

    I think I asked the same question in the old thread, but I want to know (as I haven't upgraded yet), how does the new version treats character to character collisions and pushing forces. In the old version the capsule checks when moving were necessary, so if a character was moving into other character, I'd reset the movement speed vector of the character so one character won't push another. This makes the character to stop, and when you're controlling that character, it doesn't feel good when your input is being nullified. Is there a built–in algorythm that prevents pushing and just makes the moving character to slide over another character, does the mentioned Collide and Slide algorithm have something to do with it?
     
    Krull likes this.
  3. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @my_little_kafka,

    Thank you!

    In short yes, one of the big advantage of ECM2 over ECM, as previously stated, is the implementation of the Collide and Slide Algorithm, this is a form of continuous detection and response, basically it means that whenever our character collides with other collider (other character, rigidbody, a wall, ground, etc), instead of stopping our movement, we compute a sliding vector to let the character gracefully traverse the world solving future collision before it happens!

    Actually the ECM2 implementation let you decide how to react to each of this contacts, the CharacterMovement is the responsible to perform all the geometric and collision related task, and in the end to physically move the character to its new computed position, while it let the Character to decide how the character should be moved (walking, running, falling, flying, etc), and how should react to contacts through the use of delegates, so in your custom controller (if needed) you can completely modify it as much as needed.

    For example, when a collision between us (our character) and another character is detected, the CharacterMovement will call the Character's OnApplyPushForce delegate, so you can use this function to take full control over how to solve this collision.

    Actually ECM2 is somewhat an hybrid between a fully kinematic and a dynamic controller, where all the collision of Character vs others (e.g. character walks into a wall) is resolved by us, while the others collisions vs Character (Character is hit by a moving platform) is managed by PhysX (but can be omitted too if desired).

    In the attached image, you can find the Character (replaces BaseCharacterController) properties you can use to decide how it should react to physical interactions, but as commented is not limited to, as all can be extended / replaced in your custom Character if desired or needed.

    Captura de pantalla (183).png

    Mass
    This character's mass. Will set the Rigidbody’s mass.

    Impart External Velocity
    If true, impart the velocity caused by external forces during internal physics update.

    Impart Platform Velocity
    If true, impart the platform's velocity when jumping or falling off it.

    Impart Platform Movement
    Whether the character moves with the moving platform it is standing on.

    Impart Platform Rotation
    Whether the character receives the changes in rotation of the platform it is standing on.

    Apply Push Force
    Should apply a push force to rigidbodies when walking into them?

    Push Force Affect Characters
    Should apply push force to characters when walking into them ?

    Apply Standing Downward Force
    Should apply a downward force to rigidbodies we stand on ?

    Push Force Scale
    Force applied to rigidbodies when walking into them (due to mass and relative velocity) is
    scaled by this amount.

    Standing Downward Force Scale
    Force applied to rigidbodies we stand on (due to mass and gravity) is scaled by this amount.

    All those properties can be toggled at run-time as needed.

    Regards,
    Krull
     
    my_little_kafka likes this.
  4. FireSwordStudio

    FireSwordStudio

    Joined:
    Jun 24, 2014
    Posts:
    345
    I was just checking up on the old thread to see if this released yet. Going to be upgrading as soon as possible. So many new examples, Character Events, Custom Gravity, I honestly can't wait to try this out!

    I've been working on a sorta Hack and Slash type game using the first one. It worked by using a mix of Root Motion and traditional movement for different animations. I used my own event system to switch between these 2 modes. Does that type of quick changing still work here?
     
  5. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @FireSwordStudio

    Sounds great! one my preferred game genre to be honest :)

    Absolutely, in ECM2 you can toggle root motion as desired, and it's easier than ECM as in ECM2 all you have to do is set its useRootMotion property to enable or disable.

    actually it includes an example showing how to toggle root motion while walking taking advantage of its new movements modes and its OnMovementModeChanged event, for example:

    Code (csharp):
    1. protected override void OnMovementModeChanged(MovementMode prevMovementMode, int prevCustomMode)
    2. {
    3.     // Call base method implementation
    4.  
    5.     base.OnMovementModeChanged(prevMovementMode, prevCustomMode);
    6.  
    7.     // Toggle root motion, allow when walking, otherwise, disable it
    8.  
    9.     useRootMotion = IsWalking();
    10. }
    Actually ECM2 is not just a better motor (analog to unity character controller) but also a high level layer on top of what ECM offers.

    Having said that, please keep in mind that while it shares a lot with ECM, its basically a new product so unfortunately there is not a direct port between ECM BaseCharacterController to ECM2 Character classes.

    Let me know if you need any further help.

    Regards,
    Krull
     
    FireSwordStudio likes this.
  6. FireSwordStudio

    FireSwordStudio

    Joined:
    Jun 24, 2014
    Posts:
    345
    I'm already loving it so far! Something I am having a bit of trouble with though.

    I use a custom camera. I've noticed that without using the camera that comes with it, I get errors and my character won't rotate properly. Is there a way around this without editing code?

    I wanna add that editing out HandleCameraInput() from the update fixes my issue, just gonna add a bool to use camera input or not.

    I did a couple more edits to fix the Cursor Lock as well. I made it its own script and reference it instead so I don't have to reference the Original Camera Script at all.
     
    Last edited: May 8, 2021
  7. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Nice, happy to hear it!

    Are you using the ThirdPersonCharacter? If so, worth note this has been developed to make use of its included ThirdPersonCameraController, however as all with ECM it can be extended as needed.

    In you case since you are using a external camera with its own controller (I assume), you probably should use a Character, and simply assign your Camera to its camera property so it moves relative to it (e.g. Its Rotation Mode), after all the ThirdPersonCharacter is just extending a Character to control the ThirdPersonCameraController.

    Let me know if you need any further help

    -Krull
     
  8. FireSwordStudio

    FireSwordStudio

    Joined:
    Jun 24, 2014
    Posts:
    345
    Ahhh, that makes a bit more sense. I was basing everything off of the MyCharacter Script provided in the examples, so I followed and inherited from ThirdPersonController. I didn't even think to just use Character instead. Thanks for the help!
     
    Krull likes this.
  9. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Yes, the Character is a full-feature highly customizable class, and the base for all your game avatars (player or AI controlled), however ECM2 already includes some Character derived classes, customized for different game-genres, like First Person, Third Person, Top Down (e.g. NavMeshAgent), etc. You can use any of these “base” characters as your parent class (e.g. Creating a derived Character class) or to be used by your Controller, but in the end all of those are just extending the "master" Character Class.

    Take for example, the ThirdPersonCharacter, if you review the code, basically all it's doing is extending a Character class and adding input related code to handle the ThirdPersonCamera or another third person example you can take a look is the Cinemachine based one.
     
  10. seoyeon222222

    seoyeon222222

    Joined:
    Nov 18, 2020
    Posts:
    21
    upload_2021-5-9_18-57-1.png

    I share personal tips about using Cinemachine for configure Character Controllers (With ECM2)

    CM example(CMThirdPersonCharacter.cs) manages InputAction through Script.
    (Initialization, binding etc..)

    but Cinemachine can setting InputAction without Script
    The way is simple.
    Just add "Cinemachine Input Provider" and binding InputAction, setting related option to use.
    It will be helpful if you refer to the reference document for detailed setup instructions and related information.

    There is no correct answer to the method.
    This is just a tip for users who configure character controllers using Cinemachine .

    For the purpose of "ECM2 example,"
    I think the content of CMThirdPersonCharacter.cs will be more appropriate.
     
    Krull likes this.
  11. seoyeon222222

    seoyeon222222

    Joined:
    Nov 18, 2020
    Posts:
    21
    There is parameters named "JumpLeg" in the "UnityCharacterController"
    (ex ThiredPersonCharacter Example animator..)
    It is used in Airborne Blend Tree

    However, there is no script that uses that parameters
    Of course, it has no effect on Blend tree's behavior.
     
  12. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @seoyeon222222

    Thank you for sharing your tips, and sure will help me and others!
     
  13. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    19
    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?
     
  14. mookfasa

    mookfasa

    Joined:
    Dec 21, 2016
    Posts:
    27
    First off love the ECM2 having used ECM1 for a while now. Trying to learn the new input system I was wondering if there was a way to toggle sprint instead of having to hold it down?
     
  15. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @asored,

    Well ECM and ECM2 are designed for vertical oriented characters (e.g. Humanoids) where it can be rotated as needed, e.g. Like Mario galaxy, but the bottom part of the capsule will always represent the character's feet and the area designated to perform the ground detection.

    So you can approximate your animal volume with the capsule an let it handle the locomotion, and use a more detailed collider hierarchy like hit boxes to say something. For example:

    dog_capsule.jpg

    Here the yellow capsule will be your Character's capsule and is the responsible to control all your movement, however in case you use additional collliders, make sure those do not collides with character's capsule collider.

    You can use the Character IgnoreCollision(Collider otherCollider, bool ignore = true) method to ignore additional colliders.

    Regards,
    Krull
     
  16. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hey @mookfasa,

    Happy to know you like ECM2!

    About your question, absolutely, in your custom controller simply override the OnSprint InputAction Handler method and replace its implementation as follows:

    Code (csharp):
    1. // Overrides OnSprint InputAction Handler to handle toggle sprint
    2.  
    3. protected override void OnSprint(InputAction.CallbackContext context)
    4. {
    5.     if (context.started)
    6.     {
    7.         if (!IsSprinting())
    8.             Sprint();
    9.         else
    10.             StopSprinting();
    11.     }
    12. }
    By other hand, I recommend this article to get familiar with unity's new input system, is really great!

    Regards,
    Krull
     
  17. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    19
    Thanks Krull. I've bought your asset and I try my first steps :) But I can't get to work jumping behavior with Root Motion animations. "Use Root Motion" is checked. Also my model has the Root Motion Controller as component. But when I jump, my character first jumps up on the y axis with physics and after that the root motion animation runs. I could prevent this behavior by setting the Jump Impulse to 0..then the Root Motion animations works, but only on each third or fourth jump..for many jumps nothing happens, because the "OnGround" parameter is set immediately to true.

    Do I made something wrong? :)
     
  18. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Not really hehe, its expected behavior since in other to make root motion jumps work, you will need to set your character's movement mode to Flying.

    Quoted from user manual:


    The reason behind this is because by default (walking / falling movement modes) ECM2 will discard any vertical velocity so it ignores your given root motion vertical velocity while in flying movement mode it uses the full velocity (lateral and vertical).

    Having said that, the jump is always physics based, you can disable it overriding the CanJump method and make it return false and implement your own root-based jump, just play your root-motion based jump animation.

    Let me know if have any further questions

    Regards,
    Krull
     
  19. Predulus

    Predulus

    Joined:
    Feb 5, 2018
    Posts:
    12
    Hi, so I just bought ECM2 and imported into my project. I realise that the 2D version is actually 2.5D, but my character is a 2D sprite, so I want to rotation to be instant. The manual says "Rotation Rate: If set to zero (0) will perform instant
    turns. This is particularly useful for 2D / 2.5D games to perform side to side lock rotation."

    I set Rotation Rate to zero, but rotation is not instantaneous, it still rotates about the Y axis, meaning the sprite gets skinny, disappears, reappears, and gets fatter in the opposite direction, if you know what I mean. Help please :)

    Edit: Hmmm the problem was me, not being observant :) There was a MyCharacter component already in Side Scroller Controller, so when I added my own MyCharacter directly to my sprite, it messed things up. So now, there's no slow 3D rotation of my sprite about Y, but the sprite does not flip direction when I move run the other way. Maybe this is something I have to implement myself. I'll get started - please let me know if this is the case.

    Edit2: So I have a workaround by setting OrientToMovement and RotationRate to 1000000, but this is not ideal ;)
     
    Last edited: May 11, 2021
  20. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hello @mikedono

    Thank you for purchasing ECM2!

    About your issues:

    Yes this is a "bug" since this feature was removed at last minute, but still managed to get in the manual. So Ill fix it in first update!

    Having said that, actually its pretty easy to get the lock feature added, in your custom controller, e.g. using the MyCharacter from the SideScroller template scene, override the UpdateRotation mode to perform the movement direction lock as follows:

    Code (csharp):
    1. /// <summary>
    2. /// Extends UpdateRotation method to perform instant side to side lock rotation.
    3. /// </summary>
    4.  
    5. protected override void UpdateRotation()
    6. {
    7.     Vector3 movementDirection = GetMovementDirection();
    8.  
    9.     if (movementDirection.sqrMagnitude > 0)
    10.         transform.rotation = Quaternion.LookRotation(movementDirection, GetUpVector());
    11. }
    The above code will replace the Character's rotation mode (ignores rotation rate) to perform an instant rotation towards movement direction vector.

    Regards,
    Krull
     
    Predulus likes this.
  21. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    19

    Hey Krull,

    first of all I'm very excited about your efforts to help your customers :) This is very rare and I really appreciate it!

    So for my understanding: The best way I can go is to create a Custom Character class and extend the Character class, right? There I can overwrite the functions I need for my preferred behavior.

    For example I wrote this for my Root Motion Jumping behavior:


    Code (CSharp):
    1. // Prevent character to jump because of root motion
    2.     public override bool CanJump() {
    3.         return false;
    4.     }
    5.  
    6.     // When the character jumps, set IsJumping to true. After the animation finishs set it again to false
    7.     protected override void OnJump(InputAction.CallbackContext context) {
    8.         Debug.Log("Jump");
    9.         if (!this.animator.GetCurrentAnimatorStateInfo(0).IsName("Jump_Trot")) {
    10.             _anim.SetBool("IsJumping", true);
    11.         } else {
    12.             _anim.SetBool("IsJumping", false);
    13.         }
    14.     }
    I think caused by setting the CanJump to false and deactivating physics jumping, events like OnLanded() are not triggered...so I could not find a better solution than waiting until the animation finishs to set the IsJumping to false. Or do you know a better solution in this case?

    Also I see that when extending the Character class by removing the Monobehavior the character does not react anymore for inputs like Crouching and Sprint. It still moves and jumps, but all other inputs are ignored. Is this an expected behavior?

    Thanks in advance! :)

    Best regards,
    Asored
     
    Last edited: May 11, 2021
  22. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @asored,

    Thank you, glad I could help :D

    About your questions:
    Yes that's correct, however this is only really required when you want or need to extend the Character base functionality, as in your case, replace the physics-based jump with a root-motion based.

    Sorry if I was not clear enough, to implement a root-based jump, you just need to play your jump animation in response to jump input, so basically you are replacing the Character Jump (physics based) with an animation.

    For example to trigger your animation from jump input action:

    Code (csharp):
    1. /// <summary>
    2. /// Override OnJump InputAction handler to trigger a root-based jump animation
    3. /// </summary>
    4.  
    5. protected override void OnJump(InputAction.CallbackContext context)
    6. {
    7.     if (context.started)
    8.     {
    9.         var animator = GetAnimator();
    10.         if (animator)
    11.             animator.SetTrigger("jump"); // Use your trigger name here!
    12.     }
    13. }
    However, the above code will just trigger your "jump" but remember to use root-motion vertical velocity, you need to set the character's movement mode to Flying and when it completes change it back to Walking or Falling as this can be safely be used as the exit movement mode, since those are automatically changed based on character's ground status.

    Typically I handle this kind of "jumps" using a StateMachineBehaviour so you can use its OnEnterState / OnExitState to change the movement mode as needed, as follows:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using ECM2.Characters;
    4.  
    5. public class RootMotionJump : StateMachineBehaviour
    6. {
    7.     // Cached Character
    8.  
    9.     private Character _character;
    10.    
    11.     public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    12.     {
    13.         // On RootMotionJump state enter...
    14.  
    15.         // Cache ECM2 Character
    16.  
    17.         if (_character == null)
    18.             _character = animator.transform.root.GetComponent<Character>();
    19.  
    20.         // Set Flying movement mode to use root-motion vertical velocity
    21.  
    22.         _character.SetMovementMode(MovementMode.Flying);
    23.     }
    24.    
    25.     public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    26.     {
    27.         // On RootMotionJump state exit...
    28.  
    29.         // Exit Flying movement mode.
    30.         // Its perfectly fine use Falling as our exit movement mode since it is automatically handled based on character's ground status.
    31.  
    32.         _character.SetMovementMode(MovementMode.Falling);
    33.     }
    34. }
    Since we are replacing the Character's Jump, we will not receive the jump related events, e.g. OnJumped, OnReachedJumpApex, however other events like OnWillLand, OnLanded, etc will be triggered as those are not jump related but ground status based.

    Having said that, If you still having issues, and in case you prefer to reach me through email and willing like to share the root-motion based jump with me, I can set a basic working example for you, as this will be more clearer seeing it in action.

    Regards,
    Krull
     
  23. Predulus

    Predulus

    Joined:
    Feb 5, 2018
    Posts:
    12
    Hi @Krull,

    Thanks for your reply. I appreciate it :) I'm sure ECM2 will be awesome when I get it working. I added the overload you suggested:



    It didn't have the desired effect:



    I've tried with Rotation Mode: Orient to Movement, and None.

    Cheers
    Pred
     
    Last edited: May 12, 2021
  24. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Ah I see, I think this is caused because you are modifying the character's scale, which I strongly advise against as it will mess with the rigidbody.

    The solution I gave to you, will rotate the character side to side (you can try it with Unity Character).

    Another alternative is to disable character's rotation (e.g. rotation mode == none) and use your scale method BUT on your sprite model and not on the Character's transform.

    Also and easier option, is disable character's rotation and just flip your sprite on x, e.g. Flips the Sprite texture along the checked axis depending if moving to right or left.

    Last but not least, please make sure your sprite's visible side are aligned with character's side, in the side-scroller the character defaults to forward (along world z-axis), so take that into consideration.

    Let me know if need any further help.

    Regards,
    Krull
     
    Last edited: May 12, 2021
    Predulus likes this.
  25. Predulus

    Predulus

    Joined:
    Feb 5, 2018
    Posts:
    12
    Hi again Krull :)

    Thanks for your reply. I noticed that I still had the scale code in there, and I removed it, but you obviously saw my post before I edited it haha. I took the scale code out but still had the problem. The updated code and clip are in the original post now. I will check your post above and see if there's a solution there.

    Thanks again
    Pred

    p.s. "Another alternative is to disable character's rotation (e.g. rotation mode == none) and use your scale method BUT on your sprite model and not on the Character's transform."

    Oooh I see. Gonna try it thanks mate.
     
  26. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @mikedono,

    Yes :), let me know if that worked for you, if no, Ill send you a modified sidescroller example so you can try it.

    Cheers,
    Krull
     
    Predulus likes this.
  27. Predulus

    Predulus

    Joined:
    Feb 5, 2018
    Posts:
    12
    Sorry @Krull,

    that still doesn't work - it orients the sprite along the Z axis.



    Cheers
    Pred
     
  28. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Yes, that's what I mean about the character orientation :), so when your character is rotated the sprite faces the wrong direction.

    Here I attach you the modified side scroller example with a very basic sprite attached, so you can take a better look at it.

    To use it, simply import the attached package into a project with ECM2 installed on it. You'll notice the code is the same I shared earlier with you, just the character and sprite orientations are modified.
     

    Attached Files:

  29. Predulus

    Predulus

    Joined:
    Feb 5, 2018
    Posts:
    12
    Thanks very much @Krull, you're the best :D
     
  30. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Awesome!, happy I was able to help :)

    Regards,
    Krull
     
    Predulus likes this.
  31. mookfasa

    mookfasa

    Joined:
    Dec 21, 2016
    Posts:
    27
    Awesome thank you!
     
    Krull likes this.
  32. mookfasa

    mookfasa

    Joined:
    Dec 21, 2016
    Posts:
    27
    ECM 1 had an example for custom rotation. How would one implement that on ECM2?
    Code (CSharp):
    1.         protected override Vector3 CalcDesiredVelocity()
    2.         {
    3.             // By default ECM will use the moveDirection to compute our desired velocity, however you can use this method
    4.             // to modify this behaviour, in this case we simple move the character's toward its current view direction
    5.  
    6.             return transform.forward * speed * moveDirection.z;
    7.         }
    8.  
    9.         protected override void UpdateRotation()
    10.         {
    11.             // By default an ECM character will be rotated toward its given moveDirection, however you can use this method
    12.             // to modify it, in this example to perform a tank-like rotation.
    13.  
    14.             // Generate a rotation around character's vertical axis (Yaw rotation)
    15.  
    16.             var rotateAmount = moveDirection.x * angularSpeed * Time.deltaTime;
    17.  
    18.             // Rotate character along its y-axis (yaw rotation)
    19.  
    20.             movement.rotation *= Quaternion.Euler(0f, rotateAmount, 0f);
    21.         }
     
  33. Mythran

    Mythran

    Joined:
    Feb 26, 2013
    Posts:
    68
    in ecm2 how how do we make the character auto-crouch on trigger or when a a collider collider with the head of the character?
     
  34. Krull

    Krull

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

    Actually is quite similar, however since ECM2 adds a higher level layer, IMO it is somewhat easier to do, for example:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using ECM2.Characters;
    4.  
    5. namespace ECM2.Support.CustomRotationExample
    6. {
    7.     // Extends a Character to perform a tank-like rotation
    8.  
    9.     public class MyCharacter : Character
    10.     {
    11.         /// <summary>
    12.         /// Extends HandleInput method, here to move along character's forward vector
    13.         /// </summary>
    14.  
    15.         protected override void HandleInput()
    16.         {
    17.             var movementInput = GetMovementInput();
    18.  
    19.             SetMovementDirection(GetForwardVector() * movementInput.y);
    20.         }
    21.  
    22.         /// <summary>
    23.         /// Extends UpdateRotation method to rotate along character's yaw.
    24.         /// </summary>
    25.  
    26.         protected override void UpdateRotation()
    27.         {
    28.             var movementInput = GetMovementInput();
    29.  
    30.             float yaw = movementInput.x * rotationRate * Time.deltaTime;
    31.  
    32.             AddYawInput(yaw);
    33.         }
    34.     }
    35. }
    Regrds,
    Krull
     
  35. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @Mythran,

    You can use the Character Crouch and StopCrouching methods, for example using a trigger:

    Code (csharp):
    1.  
    2. private void OnTriggerStay(Collider other)
    3. {
    4.     if (!other.CompareTag("Player"))
    5.         return;
    6.  
    7.     Character character = other.GetComponent<Character>();
    8.     if (character)
    9.         character.Crouch();
    10. }
    11.  
    12. private void OnTriggerExit(Collider other)
    13. {
    14.     if (!other.CompareTag("Player"))
    15.         return;
    16.  
    17.     Character character = other.GetComponent<Character>();
    18.     if (character)
    19.         character.StopCrouching();
    20. }
    21.  
    By other hand, a Character will report a movement hit event (e.g. OnMovementHit(...)) the passed MovementHit struct let you know the hit location WRT capsule (e.g. bottom, sides, top), but this is only triggered if the character is moving, however you can use regular OnCollisionXXX events and use the CharacterMovement ComputeCapsuleHitLocation to check if is a top hit.

    Once you detected a head collision, proceed as the trigger example.

    Regards,
    Krull
     
    Mythran likes this.
  36. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    19
    Wow. Thanks! The OnLanded() event triggers again now! This solution is very elegant.

    Now I have the next challenge...I see that there is no setting to react on uneven grounds regarding the rotation. See the following image:



    When the ground is ascending, like a mountain or other slopes, the character does not change the rotation parallel to the ground. Is there a helper function in your script to handle this?

    I wish you a great day and again: many thanks in advance. I appreciate your great support!

    Best regards,
    Asored
     

    Attached Files:

  37. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @asored,
    Awesome! thank you for the update and happy to know I was able to help you!

    Ah yes, well it is not implemented by default, ECM2 includes an example somewhat similar, PlanetWalk where the character follows the planet contour its not exactly what you need.

    Having said that, Ill create a basic helper component to allow a character follow the terrain slope, once available ill post it here (prob tomorrow), and actually this will be added to package on first update, thanks!

    Thank you and have a nice day too!

    - Krull
     
  38. FireSwordStudio

    FireSwordStudio

    Joined:
    Jun 24, 2014
    Posts:
    345
    Hey so I'm having a weird issue that I'm not sure why its happening.

    When I switch to Root Motion Movement on the fly (like how I did it ECM1) I'm getting a weird teleport. It isn't across the map teleporting or anything. It's maybe a couple of spaces forward from the character. But its still a little jarring.

    Here's the code I'm calling to switch between the 2 modes.

    Code (CSharp):
    1. void UseRootMotion()
    2.     {
    3.         useRootMotion = true;
    4.         SetRotationMode(RotationMode.None);
    5.     }
    6.     void DisableRootMotion()
    7.     {
    8.         useRootMotion = false;
    9.         SetRotationMode(RotationMode.OrientToMovement);
    10.     }
    Any help on a better way to handle this would be great. I might just have to use root motion the whole time.
     
  39. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @FireSwordStudio,

    That's strange and to be honest, I have no noticed it before, actually ECM2 includes a toggle root motion example (ECM2\Samples\Examples\2.- Animation\Root Motion Toggle) where the character only use root motion while on Walking movement mode.

    This example makes use of the Character OnMovementModeChanged event to toggle root motion based if the character is walking or not.

    By other hand, while using root motion or not, you can default the character's rotation mode to RotationMode.OrientToMovement, as the only way a Character will use root motion rotation to orient the character is setting its rotation mode to RotationMode.OrientWithRootMotion, while RotationMode.OrientToMovement disables the character rotation at all.

    So in your case you simply set useRootMotion property value to true to move the character with root motion, and set it to false to move the character procedurally.

    Regards,
    Krull
     
  40. FireSwordStudio

    FireSwordStudio

    Joined:
    Jun 24, 2014
    Posts:
    345
    I think it has to do with my animations. I've noticed one of my animations doesn't blend to the next so smoothly so its causing the jump I mentioned. Its only from running to the animation in question so I'll figure out the fix. Thanks for the super quick response though!
     
    Krull likes this.
  41. FireSwordStudio

    FireSwordStudio

    Joined:
    Jun 24, 2014
    Posts:
    345
    It took a little bit and staying up way past late, but I squashed the issue. I have my own little homemade asset for combo animations and it used CrossFade to attempt smooth animations, however it was always breaking with the first and only first animation.

    I decided to add a bool that allows for a "Start Intro Transition" function. Basically, the first animation in the combo will use a transition from Mecanim instead of calling crossfade like the rest of the animations.

    TLDR: I fixed the issue in my own asset and it now works perfectly.
     
  42. Mythran

    Mythran

    Joined:
    Feb 26, 2013
    Posts:
    68

    Thank you very much, will you consider on adding a vault or step height or perhaps a ledge climb example?
    I'll try to add these either way. Could i ask you alot of help for these? :x
     
  43. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    19
    Hi @Krull

    Thanks! Its very rainy here for the next days and weeks. So..I have a lot of time for ECM2.. hehe :D

    Oh, that's great! I'm excited to see your way to handle this. Thanks in advance.

    Have a nice day,
    Asored
     
    Krull likes this.
  44. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @FireSwordStudio,

    Thank you for the update, and happy to know you was able to solve your issue!

    Cheers,
    Krull
     
    FireSwordStudio likes this.
  45. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @Mythran

    For high steps, it is already included, an ECM2 character can climb a step up to its capsule height, just adjust the stepOffset property as needed.

    By other hand, yes, I have planned to add further examples to ECM and ECM2, like vaulting, wall run, wall-grab, etc. however those will be part of future updates.

    Regards,
    Krull
     
    Mythran and FireSwordStudio like this.
  46. Mythran

    Mythran

    Joined:
    Feb 26, 2013
    Posts:
    68
    Thank you very much.
    Regards!
     
    Krull likes this.
  47. Predulus

    Predulus

    Joined:
    Feb 5, 2018
    Posts:
    12
    Hi Krull,

    I'm using Spine to create animations, and I want to use PlayMaker to manage changing states. How can I integrate that with ECM? Should I edit OnMovementModeChanged, and get a reference to my PlayMaker FSM and send a PlayMaker message to it? I'm thinking that's what I probably need to do. I'm still pretty new to Unity, PlayMaker, Spine etc, but not really so new to programming, maths, physics etc ;)

    Edit: Okay, I have got this basically working, using the method above, but I need to know, when the player goes from moving to stationary, what is the MovementMode? Is it MovementMode.None?

    Cheers
    Pred
     
    Last edited: May 16, 2021
  48. mookfasa

    mookfasa

    Joined:
    Dec 21, 2016
    Posts:
    27
    Once again thank you!
     
    Krull likes this.
  49. cursedtoast

    cursedtoast

    Joined:
    Apr 27, 2018
    Posts:
    38
    Is there upgrade pricing for those of us that bought ECM1??
     
  50. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    270
    Hi @cursedtoast,

    Absolutely, those who bought ECM in the past 90 days (from ECM2 release date) should get ECM2 for free, while current ECM users who decide to upgrade to ECM2 have an upgrade discount, basically the price difference between both versions, so upgrade price is about $25 USD, at least that's what I set on portal :D.

    Hope this helps.

    Regards,
    Krull
     
unityunity