Search Unity

[RELEASED] Easy Character Movement

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

  1. discofhc

    discofhc

    Joined:
    Dec 18, 2017
    Posts:
    47
    I bought it yesterday... today it is on sale (50%)... but i don´t mind, it´s worth the full price!

    Congrats!
     
  2. Krull

    Krull

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

    Thank you :D I really appreciate your kind words. Glad to know you liked ECM!

    Regards,
    Oscar
     
  3. Didriksen

    Didriksen

    Joined:
    Aug 9, 2015
    Posts:
    4
    Hey! Grabbed this asset because the description sounds like it fixes all the things that are wrong with my own character controller, so I'm really looking forward to trying it.

    I have one question - When I try to import it to my project I get a warning that it will override my project settings, and that I shouldn't continue if I didn't know what that implied. Googling it wasn't very helpful. Can you provide any details as to what it will override?

    Many thanks
     
  4. Krull

    Krull

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

    First of all, thank you for purchase ECM!

    About your question, you can safely import ECM without any project settings at all (just Easy Character Movement folder), as this are basically unity default settings. The reason of this is because the asset store category includes the project settings but as I commented, this is not required at all by ECM.

    By other hand if you do not need / do not want to include the ECM examples, you can deselect the Examples folder (Easy Character Movement/Examples)

    Please, let me know if need any further help.

    Kind Regards,
    Oscar
     
  5. lmakor

    lmakor

    Joined:
    Oct 31, 2016
    Posts:
    23
    I really like the character controller!

    However i got one question:
    Is it possible to stop the character from pushing other rigid bodies (e.g. other players) around

    My usecase is that I am developing a multiplayer game and if 2 players collide I want both to keep their position. This should also happen if e.g. one player is standing still and another one is runing into that player.
    Do you have any idea how to implement such a behaviour?
     
  6. Krull

    Krull

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

    Thank you for purchase ECM!

    About your question:

    Currently the only way to prevent this is modifying the character's rigidbody mass for the character you want to be immobile in response to other character's collision AND your character state (I develop a bit more below)

    ECM character default to a mass of 1, so for a completely immobile character the other character's mass must be greater enough to prevent it, for example a mass of 100 units.

    However this is non trivial issue, an must be handled in a priority alike, I mean which character can push other. For example, when your character is IDLE, and detect a collision with other moving character, you can set your character mass to 100, to prevent being pushed by other character, and so on for other character's states as needed.

    Additionally, modifying the BaseCharacterController deceleration / friction values, help a bit, but do not completely stop being pushed as the mass does.

    Worth note that Physx have a function to handle this cases, but unfortunately it is not currently exposed in unity yet, as you can see HERE

    Please, let me know if need any further help.

    Kind Regards,
    Oscar
     
  7. lmakor

    lmakor

    Joined:
    Oct 31, 2016
    Posts:
    23
    @Krull

    Thanks for your super fast answer.

    I didn't know that there was actually an PhysX way to solve this issue. So I learned something new today :)

    As adding that feature to the Unity API would not only solve my issue, but would be a great addition in general IMHO, I voted for that feature request!
    I will also try to get a few other people to vote for that feature request :D

    I also thought about trying to manipulate the masses of the characters for the time being. I will report back how it turns out.

    Thanks again!
     
  8. Krull

    Krull

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

    That would be great! hopefully Unity decide to add that function soon, as this will help a lot to better define custom character interactions, in an easier and more correct way.

    Yes, it works, however requires a little more 'housekeeping' to get the desired interactions.

    Thank you :), and please do not hesitate to message back if need any further help.

    Kind regards,
    Oscar
     
  9. Kellyrayj

    Kellyrayj

    Joined:
    Aug 29, 2011
    Posts:
    936
    Hi @Krull, excellent asset!

    I was curious, how does addForce and this function interact with each other? I was trying to do some like spring type stuff but the simple implementation of addForce(direction * force) is not working properly. I'm assuming that is has something to do with how you move the rigid-body.

    Thanks!
     
  10. Krull

    Krull

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

    Thank you, glad you liked ECM!

    About your question, ECM move the character by velocity (2nd order control), basically takes the rigidbody current velocity and modify it to the desired move velocity.

    Worth note ECM respect the use of external forces on the character, however this forces are limited by the character settings (eg: maxLateralSpeed, maxRiseSpeed, maxFallSpeed, friction settings, etc).

    Actually the character jump basically just add a vertical force (well impulse, hehe) using the following code:

    Code (csharp):
    1.  
    2. public void ApplyVerticalImpulse(float impulse)
    3. {
    4.     var verticalImpulse = Vector3.up * impulse;
    5.     _rigidbody.velocity = _rigidbody.velocity.onlyXZ() + verticalImpulse;
    6. }
    7.  
    However an important consideration, ECM implements a ground snap feature, in order to maintain the character ground (when grounded), so you need to explicitly tell when the character is allowed to leave the ground using the movement.DisableGrounding() method, as you can see in the BaseCharacterController Jump method (line 465).

    Additionally ECM expose the use of addForce basically wrapping it on the movement.ApplyForce method.

    I appreciate if could develop a bit more about what are implementing, in order to better help you.

    Kind regards,
    Oscar
     
  11. Kellyrayj

    Kellyrayj

    Joined:
    Aug 29, 2011
    Posts:
    936
    Hi @Krull thanks for your reply. This is the behavior I am seeing when I use your suggestions for applyForce and DisableGrounding. I've also uped the maxLateral Speed, rise and fall parameters to a giant number



    This is my code:

    Code (CSharp):
    1. movement.ApplyForce(force, ForceMode.Force);
    2.             movement.DisableGrounding();
    I've tried a variety of forceModes, different magnitude of behavior each time but basically the same motion. Any thoughts?
     
  12. Krull

    Krull

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

    mmm, are you moving the character just by force using movement.ApplyForce(force, ForceMode.Force)? as I can see in your above video, this is expected , as I see the character friction / deceleration is slowing the character as expected.

    Is there any reason why no use the default ecm movement? I mean supply its desired move direction?

    mmm, are you implementing some kind of jetpack movement?

    Regards,
    Oscar
     
  13. Kellyrayj

    Kellyrayj

    Joined:
    Aug 29, 2011
    Posts:
    936
    Hi @Krull
    I do use the move function for all its intended walking around. And its great! Jump works perfect.

    I'm attempting to do some like explosion force stuff and springs and stuff of that sort with the addForce business.
     
  14. Krull

    Krull

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

    Oh I see :), well in this case I think the best approach is to modify the character friction / deceleration values, for example, the main settings which affect the character movement when on air, are Air Friction and Air Control. To allow the character move 'freely' when not grounded, set its Air Friction and its Air Control to 0, this basically will prevent the system to 'slow' its velocity.

    The same happen when character is on ground, ECM will slow down the rigidbody's velocity, based on its Deceleration / Ground Friction / Braking Friction. Basically when ECM receives no input (eg: a desiredVelocity == zero), will drive the rigidbody's velocity to zero, based on its friction/ deceleration settings.

    The same happen when it receive a desired move direction, it will drive the rigidbody's velocity to the given new desired velocity vector, in this case based on the character Acceleration and Ground Friction values.

    So for the character to be more affected by external forces, you will need to handle a set of this values, and apply them when an external force should happen (eg: when an explosion trigger hit character) and re-enable your default settings when player 're-gain' control of the character.

    Let me know if this helps.

    Regards,
    Oscar
     
  15. lmakor

    lmakor

    Joined:
    Oct 31, 2016
    Posts:
    23
    Hey @Krull ,

    If I may ask one more question:
    I am trying to stop the player from stepping onto certain objects, which are quite small (on y axis). Thus I tried setting the stepOffset to a very low value (however it was clamped to the minimum of 0,1), but from my experiments the setting does not affect the height of the objects the character can step onto. - no matter whether i set it to 0,1 or 0,5 the character still stepped onto the box.

    Initially I also tried enabling the freeze y position option on the rigidbody of the character, however then the values of the position are still changed (I guess from one of your scripts).

    Can you think of some elegant solution? :)

    Regards,
    Lukas
     
  16. Krull

    Krull

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

    In ECM the step offset is different from Unity character controller, in ECM it reflects a 'cast distance' and internally this offset is used to detect and separate steps and ledges.

    By other hand capsules are able to go over small obstacles since their rounded bottom produces an upward motion after colliding with a small obstacle, that's why in the documentation I suggest to configure it to your character's collider radius, because it is directly related to it.

    One possible solution to for this, is put your step collider on separate layer from character's GroundMask (eg: your character's GroundMask == Default, and your step layer == STEPS), this way the character will treat the step as 'invalid' ground. Having said that this may or may not solve the issue once again depending on your character capsule's radius and the step height.

    This happend because ECM resolve overlaps, which are permitted in PhysX (at some degree), and when you freeze the Y position and walk over a tiny step an interpenetration will occur, however this is 'fixed' by ECM.

    You can easily test this behavior enabling freeze Y position on editor, and comment the _rigidbody.MovePosition(p); in the CharacterMovement LateFixedUpdate method (Line 1328). Basically the character will walk over and pass through the step.

    An alternative solution, in order to fully prevent walking on un-desired ground, is use 'invisible' walls, however not a elegant solution, but widely used one ;)

    Please let me know if need any further help.

    Best Regards,
    Oscar
     
  17. amcagurban

    amcagurban

    Joined:
    Dec 12, 2018
    Posts:
    12
    Hey @Krull ,
    I have a problem. My character can't push a rigidbody when my character is on it. It rarely pushes(but buggy). When it can push, character seems like in picture1. You can see whole scene in picture2. The mass of my character is 10, the big cube's mass is 2 and also the long and thin cube's mass is 1... Character is heavy, so he must push... Please help me Oscar.

    PICTURE 1
    upload_2018-12-12_21-27-7.png

    PICTURE 2
    upload_2018-12-12_21-27-17.png

    Regards,
    Murat
     
  18. Krull

    Krull

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

    First of all, thank you for your support!

    A ECM character can push / be pushed by other rigidbodies, simply setting its masses and / or its friction settings (BaseCharacterController), because ultimately an ECM character is just a regular rigidbody acting like a character.

    However, by default ECM does not allow climb other NON-Kinematic rigidbodies, as it will prevent climb it, this behaviour is by design in order to prevent an ECM Character, to 'climb' other character (eg: non-kinematic rigidbody), so in order to implement your requested behavior, will need to modify some of the core ECM functionality.

    To allow an ECM character to walk over a non-kinematic rigidbody, please comment the following in the CharacterMovement component, DetectGround method (line 696).

    Code (csharp):
    1.  
    2. ...
    3.  
    4. // If other is a non-kinematic rigidbody, prevent climbing it
    5.  
    6. //_normal = Vector3.up;
    7.  
    Additionally in the CharacterMovement SnapToPlatform method, you must comment the non-kinematic rigidbody check condition, so the character can snap to dynamic rigidbodies) (line 1234).

    Code (csharp):
    1.  
    2. ...
    3.  
    4. // If not on a platform, return
    5.  
    6. var otherRigidbody = hitInfo.groundRigidbody;
    7. if (otherRigidbody == null || !otherRigidbody.isKinematic)
    8.     return;
    9.  
    10.  
    Another possible changes (depending on your custom game mechanics) could be:

    - apply forces to non-kinematic rigidbodies when it's grounding, and / or apply a weight proportional force when your character lands on a non-kinematic rigidbody, etc:

    ECM expose (CharacterMovement component) many properties to check and or query the current grounding information, for example you can use the following code snippet to detect when your character has landed:

    Code (csharp):
    1.  
    2. if (!wasGrounded && isGrounded)
    3.  Debug.Log("Just Landed!)
    4.  
    Don't hesitate to get back in touch if you have any further issues or questions.

    Kind regards,
    Oscar
     
  19. amcagurban

    amcagurban

    Joined:
    Dec 12, 2018
    Posts:
    12
    Oh, thank you very much for really rapid answer. I have never seen a creator who is faster than you @Krull .
    I fixed this problem thanks to your answer
    upload_2018-12-13_16-49-44.png

    But unfortunately, my character can't push a rigidbody ground, still.
    upload_2018-12-13_16-54-7.png

    Thank you very much again for your rapid support :)

    Regards,
    Murat
     
    Last edited: Dec 13, 2018
  20. amcagurban

    amcagurban

    Joined:
    Dec 12, 2018
    Posts:
    12
    And good news :) I fixed my problem.
    I added this code
    Code (CSharp):
    1. if (isGrounded) {
    2.                     if (groundHit.groundRigidbody)
    3.                         groundHit.groundRigidbody.AddForceAtPosition(Vector3.down * gravity * Time.deltaTime * GetComponent<Rigidbody>().mass * 5, groundHit.groundPoint);
    4.                 }
    to LateFixedUpdate and now my character pushes the nonkinematic rigidbody that is under.
     
    Pascal_NotVeryMoe likes this.
  21. amcagurban

    amcagurban

    Joined:
    Dec 12, 2018
    Posts:
    12
    Hey Oscar,
    Everything is great and works like a charm at the moment. But there's just a simple problem.
    upload_2018-12-13_21-25-58.png
    This slope is a non-kinematic rigidbody, but my character slides down. If I set rigidbody to kinematic, my character doesn't slide. I don't want my character to slide down while he's on a slope which is a non-kinematic rigidbody. What is the problem?

    EDIT:
    I fixed my problem. I changed here..
    upload_2018-12-13_21-58-56.png
    I added a condition to 1263rd line. If rigidbody isn't kinematic, this line is skipped. And so my character doesn't slide down, too.
    upload_2018-12-13_21-59-50.png

    Also I changed here and added a feature to push the ground which a is nonkinematic rigidbody. This is my code,
    upload_2018-12-13_22-9-41.png
    At the moment everything is great and works. I have no problem.

    Can you advise me something to make better my codes..

    Regards,
    Murat
     
    Last edited: Dec 13, 2018
  22. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hi Murat (@amcagurban),

    Glad to help you :D

    Some advices, I suggest you create a custom character controller extending one of the included ECM 'base' controllers (eg: BaseCharacterController, BaseAgentController, BaseFirstPersonController), and use this newly custom controller to add your game custom mechanics.

    Here override its FixedUpdate method (don't forget to call base.FixedUpdate on it) and use it to add your force related code, instead of adding it on the LateFixedUpdate, mostly because LateFixedUpdate is called after the Physx internal update, additionally you keep a separation of your game custom code and ECM code.

    In this custom controller you can query all the required information using the cached CharacterMovement component using the movement property.

    Yes, this is expected as you are adding the gravity force all time, that's why in ECM I manually control the gravity and apply it only when character is not grounded.

    Hope this help you, however do not hesitate to message back if need any further help.

    Regards,
    Oscar
     
    amcagurban likes this.
  23. amcagurban

    amcagurban

    Joined:
    Dec 12, 2018
    Posts:
    12
    Hi Oscar
    Thanks for yet another fast answer :)
    Your support and your perfect controller have solved my almost all issues..

    Regards,
    Murat
     
  24. Krull

    Krull

    Joined:
    Oct 31, 2014
    Posts:
    772
    Hey Murat,

    Excellent!, glad to know it :)

    Don't hesitate to get back in touch if you have any further issues or questions.

    Best regards,
    Oscar
     
    amcagurban likes this.
  25. Didriksen

    Didriksen

    Joined:
    Aug 9, 2015
    Posts:
    4
    Just a heads up to anyone else wanting to supply their own input (movement direction):

    After a stupid amount of time debugging why the heck my simple transform.forward/transform.right movement directions were absolutely wrong, I eventually realized that ECM apparently expects Vector3.forward/right!

    Anyway, I've just started integrated ECM into my project, and aside from that blunder it's going fairly well. Will be nice to get a proper controller working instead of my own half-assed one!
     
  26. Krull

    Krull

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

    You are right, by default ECM handles the input (moveDirection), in world space, however this can easily be modified in the HanldeInput method (BaseCharacterController), so you can transform it to your needs.

    For example, here shows how to transform the input moveDirection to be relative to the main camera's view (cached in playerCamera) direction:

    Code (csharp):
    1.  
    2. protected override void HandleInput()
    3. {
    4.     // Handle your custom input here...
    5.  
    6.     moveDirection = new Vector3
    7.     {
    8.         x = Input.GetAxisRaw("Horizontal"),
    9.         y = 0.0f,
    10.         z = Input.GetAxisRaw("Vertical")
    11.     };
    12.  
    13.     walk = Input.GetButton("Fire3");
    14.  
    15.     jump = Input.GetButton("Jump");
    16.  
    17.  
    18.     // Transform moveDirection vector to be relative to camera view direction
    19.  
    20.     moveDirection = moveDirection.relativeTo(playerCamera);
    21. }
    22.  
    Great!, glad you liked ECM and it helps you with your project :)

    Please do not hesitate to message me if have any question(s).

    Kind Regards,
    Oscar
     
  27. Didriksen

    Didriksen

    Joined:
    Aug 9, 2015
    Posts:
    4
    Hello again!
    I tried increasing the deceleration value so that my character stops more quickly after releasing the input keys. This also applies when the character is in the air (e.g. I run forward, jump, then let go of the input key). Any way to tweak the settings so that my character stops quickly on the ground, but maintains velocity in the air?
     
  28. Krull

    Krull

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

    The deceleration value affects the character when is on ground ('grounded') and when is on air, however when the character is not grounded, this deceleration value is multiplied by airControl value, so you can tweak the airControl property to allow more / less deceleration when on air.

    Another setting that affects the movement on air is the airFriction, this is analogous to the groundFriction and affects the character movement control. Higher values allow faster changes in direction, however I suggest leave this value in 0, and use it only when you need to move the character when not grounded, for example, to simulate a swing, flaying mechanics.

    Best Regards,
    Oscar
     
  29. lmakor

    lmakor

    Joined:
    Oct 31, 2016
    Posts:
    23
    Hey @Krull

    This might be a long shot, but I'll ask anyway.
    How would you go about implementing multiplayer networking using ECM?
    Especially server reconciliation after a client side miss-prediction is what bugs me.

    What I would want to do is like the following:
    When a user triggers movement, the client reacts instantly (client side prediction) and sends the command to the server. (E.g. that the player moved to the right. Suppose the client is now at pos (1,0,0))
    Then the server answers with the new position of the client. But as the RTT between client and server usually is a few frames long, the client can move further before it receives the answer. Suppose the client processed 2 more movements and moved both times to the right - thus in the simple example is now at position (3,0,0).
    Now the client receives the acknowledge from the server where the server reports client is at (1,0,0). If the client would now naively reset its position (or even interpolate) to the acknowledged position - the user experience would suffer.
    As I read, to solve this issue usually the last inputs and positions are saved on the client and all movementCommands/snapshots that are sent between client and server contain the time (e.g. as a certain tick) which signals when they were created/valid.
    So, in the example the server ack would contain tick 1 and the client would compare the acknowledged position of tick 1 with its stored position at tick 1 and as they match no error correction would be necessary.
    However if the positions don't match, the position is reset to the acknowledged position AND all inputs between the time of the acknowledged position and the current time are re-simulated.
    E.g. in the example if the server responded that the client was still at position (0,0,0) at tick 1 - because it wasn't allowed to move that tick - the client would re-simulate the inputs for tick 2 and 3 and would predict (2,0,0) as the new position for the client.

    Please correct me if I have made wrong assumptions ;)

    AFAIK to implement this, it would be necessary to "tick" the character movement - e.g. we would need to be able to reset the position and then trigger multiple steps/ticks withing one Update/FixedUpdate of Unity.
    But then again as ECM is non-kinematic rigidbody-based that might not be so easy/possible. From the top of my head I am also thinking that to reproduce the character movement the position and input is not enough - as we would need to also send e.g. current velocity (and probably other information), right?
    Though physics.simulate might be able to help? (However I don't know the performance of physics.simulate)

    Then there is still the fact that physx is not deterministic, however if the aforementioned issues are solved I think that the non-determinism shouldn't be much of a problem as any differences in e.g. position would be solved by client side error correction anyway.

    It would be really cool if you could tell me your thoughts about how you would implement multiplayer networking using ECM. :)
     
  30. sfun_G

    sfun_G

    Joined:
    Feb 28, 2017
    Posts:
    1
    Hi @Krull ,

    I have some simple questions before purchasing it.

    Let's say there are 2 Characters (A), (B)
    1. What happens when (A) tries to push (B)?
    2. What happens when (A) is standing on top of (B)'s collider and (B) tries to move and jump?
    3. Can I make a Character's collider tagged as a "Ground" so if (A) is standing on top of (B), (A) is considered grounded.
    3. Can I make Characters don't push each other like this demo?
    https://phil-sa.itch.io/kinematiccharactercontroller?secret=rjRvT8GfZCAXEkevCF92TV07UQ
    4. Do you have any playable demo where I can test these things?

    Sorry, my english is bad.
     
    Last edited: Dec 31, 2018
  31. Krull

    Krull

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

    Well, unfortunately I am not really familiar / experienced with network game programming, however being this said, as ECM is basically a regular Rigidbody acting as a character controller, you can treat it as a rigidbody, so syncing its velocities (velocity, desiredVelocity, etc) / rotation should work, and actually some customers has successfully accomplished it using the Smooth Sync asset, which basically help to sync rigidbodies across the network. However being completely honest I have not tried it.

    By other hand, you actually can use the rigidbody movePosition method to force a character position, and actually it is used to 'fix' character's interpenetration (allowed by PhysX), however this is handled in a coroutine, to simulate a 'LateFixedUpdate' as you can see in the CharacterMovement component.

    A ECM character is moved using its Move method, which expect a desired velocity, but this basically (at a great scale), just adjust the current rigidbody's velocity (accelerating / decelerating it) towards your given desired velocity, so in theory syncing its velocities / rotations should works, and can use the movePosition in case / need to rewind the character's position.

    Hope this helps you.

    Kind regards and happy new year!
    Oscar
     
  32. Krull

    Krull

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

    Thank you for your interest in ECM!

    About your questions, ECM being a rigidbody based, currently the only way to prevent this is modifying the character's rigidbody mass for the character you want to be immobile in response to other character's collision AND your character state (I develop a bit more below) or based on collisions, modify (zero out) its velocities.

    An ECM character default to a mass of 1, so for a completely immobile character the other character's mass must be greater enough to prevent it, for example a mass of 100 units.

    For example (using its mass) a character can push other character. when your character is IDLE, and detect a collision with other moving character, you can set your character mass to 100, to prevent being pushed by other character, and so on for other character's states as needed.

    Additionally, modifying the BaseCharacterController deceleration / friction values, help a bit, but do not completely stop being pushed as the mass does.

    Worth note that Physx have a function to handle this cases, but unfortunately it is not currently exposed in unity yet, as you can see HERE

    So in your given cases:

    Assuming both characters has equal mass, both character will be able to push each other, the only way to prevent being pushed by other, is having a greater mass, eg: Character A have a mass of 1, and character B has a mass of 100. character A wont push character B, but character B will push A easily.

    Again depends upon its masses, but character B will just up to some degree. Worth note that by default ECM will not snap (snap to ground feature), the top character (A) to the Bottom, but this behaviour is easy to modify as you can see in the above posts.

    Sure, only need to add your Character's B layer to your walkable 'ground' layer. So you can easily create a stomp / stomp jump mechanics, like mario for example.

    Is possible, but as commented above, requires modifying the characters mass depending on its state, for example when idle is immovable, etc. This could be easily solved if unity expose the commented Physx function...

    You can download the included demo scene HERE, however it shows the different character controllers and its interaction with world and world objects (platforms, elevators, etc) and no a specific example of 'other' character interaction.

    Please let me know if can help you any further.

    Best regards and happy new year!
    Oscar[/quote]
     
  33. Tracecat

    Tracecat

    Joined:
    Mar 20, 2014
    Posts:
    23
    Hi @Krull
    For our current project, we are considering to replace Unity's first person controller with another solution. At the moment we have problems to get the character controller working in the inner of a moving environment (in our case a moving space ship). The general idea is easy: The ships is controlled by an autopilot and the player should be able to freely move in its inner. But when we tried to solve this with the standard Unity controller we ran into a lot jittering and other physics problems when the ship turns and moves.
    In general all ships movements need to be applied to the character and the direction of gravity has to be altered when the ships turns (the ship has its own gravity). The player also may leave the ship or enter other ships so the controller need to accept changes to which "object" it is currently conencted to.

    Would that be possible to solve with ESC? How much effort would it be?
     
  34. Krull

    Krull

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

    Thank you for your interest in ECM!

    About your case, the moving ship can be handled by default with ECM, assuming your ship is treated as a 'platform' marking it as a kinematic rigidbody, this way ECM, will automatically snap the character to it, moving and rotating with the ship. This will also handle the ships change, treating this as platforms.

    You can try the ECM demo scene HERE, in particular focus on platforms, basically kinematic rigidbodies moved by script or animator.

    The only downside, is the current ECM version does not allow gravity direction change, only its magnitude, so a ECM core modification is needed to fully support it, however having said that, this is a planned feature and actually have added bases to fully support it, but not yet implemented.

    Hope this helps you, however if have any further question, please let me know it.

    Kind regards,
    Oscar
     
  35. Tracecat

    Tracecat

    Joined:
    Mar 20, 2014
    Posts:
    23
    Hey @Krull
    Thx for your fast reply! Concerning the platform meachnism: I tried your demo and there some very nice platforms to test out. But if I understand you correctly, when a platform would flip upside down, the character would just loose grip and fall down wouldn't it? I mean since gravity comes always from the same direction(downwards)....Another question, do you provide full soruce code accesst your "core" (no dlls)? Because then we may try to implement the gravity feature ourselves....

    Best regards,
    Tracecat
     
  36. Krull

    Krull

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

    Well, as mentioned earlier, the current ECM version does not allows modify the gravity direction and expect the character to be vertical aligned (not rotated), however as commented before, I added base code required to allow character / gravity rotation, but not yet implemented.

    If the character / gravity is rotated along with the platform, it should snap to it, as the character's ground detection will casts towards character's down axis, however this need tests in order to fully implement / support (in a robust way) this feature.

    Absolutely, ECM includes full commented and clean source code. This has been developed to be easy to add into existing projects and to be easy to extend its features, so a clear / commented code is one of the ECM features. Additionally if need any help, please do not hesitate to message me, Ill be happy to help :D.

    Kind regards,
    Oscar
     
  37. Tracecat

    Tracecat

    Joined:
    Mar 20, 2014
    Posts:
    23
    Hey @Krull!
    Thank you for all the help. One last question: As you mentionend before, we have to mark our space ship rigidbody as kinematic... Is there a way around that? Because if we do so, we wouldn't be able to add physics forces like thrust to our space ship.

    Best regards,
    Tracecat
     
  38. Krull

    Krull

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

    By default, ECM will treat kinematic rigidbodies as 'platforms' while it treat regular (non-kinematic) as other characters (eg: non-climbable), this behavior is by design in order to prevent an ECM Character, to 'climb' other characters.

    You can move the platfroms (kinematic rigibodies) by scritps (eg: rb.MovePosition()) or by predefined animations, however if you need it to be a regular (non-kinematic) rigidbody, you will need to modify some of the ECM core functionality, to allow snap on regular (non-kinematic) rigidbodies.

    You can find additional info related to necessary changes HERE

    Feel free to contact me if have further questions or need any help.

    Take care,
    Oscar
     
  39. Jrodz

    Jrodz

    Joined:
    Apr 8, 2014
    Posts:
    29
    Hi @Krull I am trying to find your email address to request a third person example, but I cannot seem to find it and the contact form on your website appears to be broken currently
     
  40. Krull

    Krull

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

    First, thank you for purchase ECM, I appreciate your support!

    About your question:

    By default ECM uses the given input (moveDirection) in world space, so in order to move your character relative to your camera, all you have to do is transform the moveDirection so it be relative to main camera, actually ECM includes a helper function for this, eg:

    // Transform moveDirection vector to be relative to camera view direction

    moveDirection = moveDirection.relativeTo(playerCamera);

    You can add this in the HandleInput method as follows:

    Code (csharp):
    1.  
    2.         /// <summary>
    3.         /// Overrides 'BaseCharacterController' HandleInput,
    4.         /// to perform custom controller input.
    5.         /// </summary>
    6.  
    7.         protected override void HandleInput()
    8.         {
    9.             // Handle your custom input here...
    10.  
    11.             moveDirection = new Vector3
    12.             {
    13.                 x = Input.GetAxisRaw("Horizontal"),
    14.                 y = 0.0f,
    15.                 z = Input.GetAxisRaw("Vertical")
    16.             };
    17.  
    18.             walk = Input.GetButton("Fire3");
    19.  
    20.             jump = Input.GetButton("Jump");
    21.  
    22.  
    23.             // Transform moveDirection vector to be relative to camera view direction
    24.  
    25.             moveDirection = moveDirection.relativeTo(playerCamera);
    26.         }
    27.  
    Worth note, for a complete third person controller (eg: like WoW), where you rotate the character with the mouse, you also will need to modify the UpdateRotation method, because by default ECM will rotate the character towards the give moveDirection vector. Eg:

    Code (csharp):
    1.  
    2. protected override void UpdateRotation()
    3. {
    4.         // By default ECM rotates the character towards the given moveDirection vector,
    5.         // However this can be easily modified in this method.
    6.  
    7.         // Rotate towards movement direction (input)
    8.  
    9.         // RotateTowardsMoveDirection();
    10.  
    11.  
    12.         // Perfrom character(CharacterMovement component) rotation, around its Y - axis(yaw rotation)
    13.  
    14.         movement.rotation = Quaternion.Euler(0.0f, _yaw, 0.0f);
    15. }
    16.  
    Here I attach you a complete example scene, to use it, please create a Unity Project with ECM on it, then import included package. Please refer to the ThirdPersonCamera (\ECM_THIRD_PERSON_CONTROLLER\Scenes) example scene

    By other hand you can find the contact email here, please feel free to message if need any further help.

    Best regards,
    Oscar
     
  41. Jrodz

    Jrodz

    Joined:
    Apr 8, 2014
    Posts:
    29
    You're the best! Thank you so much!

    I'll be sure to share some video of the results when I get it working nicely
     
  42. Krull

    Krull

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

    Glad I was able to help you :D

    Thanks! I look forward to hearing from you.

    In the meanwhile if need any further help, please do not hesitate to message me.

    Take care,
    Oscar
     
  43. CliffCawley

    CliffCawley

    Joined:
    Mar 30, 2009
    Posts:
    22
    Hi @Krull !

    Loving your asset but the project I'm using it on currently is struggling a little because I'm using NavMeshLinks to join NavMeshes.

    If I leave it on auto traverse, then the NavAgent will teleport to the other side and then the visual mesh usually separates and things go pear shaped.

    I believe you need to set the NavAgent 'Auto Traverse Off Mesh Link' to off and then handle it yourself.

    The examples in https://github.com/Unity-Technologies/NavMeshComponents show an example of this in the AgentLinkMover.cs (You can choose different types, but I just want it to continue travelling, not jump).

    I've attempted to do this in SyncAgent using code similar to:

    Code (CSharp):
    1.  
    2.             if (agent.isOnOffMeshLink)
    3.             {
    4.                 OffMeshLinkData data = agent.currentOffMeshLinkData;
    5.                 Vector3 endPos = data.endPos + Vector3.up * agent.baseOffset;
    6.                 agent.transform.position = Vector3.MoveTowards(agent.transform.position, endPos, agent.speed * Time.deltaTime);
    7.                 if (transform.position == endPos)
    8.                 {
    9.                     agent.CompleteOffMeshLink();
    10.                 }
    11.             }
    There are some issues with the code, for example it will travel at max agent speed, not the current velocity.

    I've also tried assigning the position to transform.position instead and moving the code before the:
    Code (CSharp):
    1.             agent.nextPosition = transform.position;
    And while that kind of works, there are still other quirks.

    I haven't spent enough time understanding how you're following the agent control normally and so odd things such as the character rotating as they travel the link or other things get out of sync and I'm not sure how to fix them right now.

    I don't suppose you've investigated this and have a fix?
    Or perhaps already have a way to have to do it in ECM that I've missed?
     
  44. Krull

    Krull

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

    Well, in ECM being a rigidbody based controller, the agents works a little different compared to the Unity's character controller, in ECM we move the agent with us, no the other way as unity's does.

    In ECM, at great sight, the character is moved by velocity, this velocity is derived from a given input moveDirection (eg: from user input, AI, etc) and a predefined speed (eg: walking speed, running speed, etc.) the system then calculate the desired velocity vector and feed it to the CharacterMovement component Move method, which in turn will move the character.

    The Agents are controlled in a similar way, after all the BaseAgentController is based on BaseCharacterController, however the agent's default implementation, derives the character moveDirection from the agent's desiredVelocity, worth note we use this agent's desired velocity to generate our desired moveDirection, which in turn will be used to calculate our final desired velocity based on our character's speed (CalcDesiredVelocity method).

    Then, as a final step, we move the agent with us (BaseAgentController SyncAgent method), syncing the agent properties with our character properties (eg: acceleration, velocity, etc).

    So in your given code, you are attempting to move the character transform directly which is not expected by the ECM, once again, it is expected to move by velocity given a desired moveDirection vector, so in your case, when the character is on a mesh link, you should compute a desired moveDirection instead of attempt to modify the transform, this way, ECM will follow your given moveDirection vector respecting the character's speed.

    Additionally, I suggest you give the character a 'tolerance radius' to decide when call agent.CompleteOffMeshLink(), in case the character can not land exactly at the target point, just like we use the 'stopping distance'.

    I suggest you review BaseAgentController HandleInput, CalcDesiredVelocity, SetMoveDirection, to get a much clear image of how the ECM agent's controller moves.

    Hope this helps you, however if have any question(s), please let me know it.

    Kind regards,
    Oscar
     
  45. CoderPro

    CoderPro

    Joined:
    Feb 21, 2014
    Posts:
    327
    Hi,
    Could you make a demo for mobile devices or somethings else ? I want to try before buy.
    Thanks
     
  46. Krull

    Krull

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

    Thank you for your interest in ECM!

    Here you can find a demo for windows, this is the included demo scene. Worth note that ECM does not include any mobile input controls, as it is focused on character controller, however its pretty easy add you own custom input.

    Please let me know if have any further questions.

    Regards,
    Oscar
     
  47. Kellyrayj

    Kellyrayj

    Joined:
    Aug 29, 2011
    Posts:
    936
    Hi Krull, I'm getting a very strange behavior and I think I've narrowed it down to intersecting geometry. Both of these mesh have box colliders and are not marked static.

    I only see this bouncing behavior when I am onto of an object that is intersecting with another mesh.



    Any clues as to what I should look into to solve this?
     
  48. Krull

    Krull

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

    One major cause of collision issues is the use of convex mesh colliders for environments colliders, this simply gives inconsistent results, and should only be used on non-kinematic rigidbodies like a vehicle for example, so I strongly recommend you not use convex colliders for your environment colliders additionally revise the following cases (stated in Unity's documentation) :

    - The Mesh Collider’s Transform has negative scaling (for example, (–1, 1, 1)) and the Mesh is convex.
    - The Mesh Collider’s transform is skewed or sheared (for example, when a rotated transform has a scaled parent transform).
    - The Mesh Collider’s Cooking Options flags are set to any value other than the default.

    I suggest you create a new project with ECM on it, and add and test flawed objects to it, and check the above requirements, this way you can easily discard any issue about modified project settings which could be messing with Unity Physics queries results and thus with ECM.

    Please let me know if this helps you

    Best regards,
    Krull
     
  49. Fabbs

    Fabbs

    Joined:
    Dec 2, 2013
    Posts:
    43
    Hello! love the asset, apart from the super jittery movement when moving the player + rotating the camera on the horizontal axis. is there any fix for this? Tested with smoothing both on and off, fps is steady well over 100. Right now its unusable

    Update: Been troubleshooting the problem some and altho my fps isnt changing when enabling my reflection probes, the jitter is only there when they are enabled. Seems like this might be on my end! il keep looking.

    Yeah one of my probes was accidently set to update every frame instead of scripting <.< . ooops.
     
    Last edited: May 8, 2019
  50. Krull

    Krull

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

    Glad you like ECM, and thank you for the update about the jitter issue!

    About the jittery, well yes there is a little bit of jitter when strafing + rotating as you comment but not really that bad (unity controller levels) and actually only has been reported by one customer (well two now :D) so yes I am aware of it and as you I been trying to completely remove it.

    I have come with an easy solution to this, using an additional 'CameraPivot' GameObject in the camera rig, then we rotate this 'CameraPivot' (yaw) instead of rotate the character (Rigidbody), this give the smoothest rotation with no perceived jitter.

    This updated FPS controller will be available in the following ECM update.

    HERE can download an example asset package to show this updated method, to use it simply import it in a project with ECM on it and please, refer to the 'smooth_fps_controller' example scene. As a bonus, this also shows how to add animation based head bob movement.

    Hope this helps you, however if need any further help, please do not hesitate to message me back.

    Best regards,
    Oscar