Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Character Controller Pro

Discussion in 'Assets and Asset Store' started by lightbug14, Jan 15, 2020.

  1. ikemen_blueD

    ikemen_blueD

    Joined:
    Jan 19, 2013
    Posts:
    341
    @lightbug14 Thanks for the clearer explanation about the External Velocity, I kind of get it now. Another quick question, can the actor controller get hits from some objects in a specific layer only, with Physic simulation ON, External Velocity ON? Or, do I have to set External Velocity OFF, use "Contact Rigidbodies tag" to collect Collision response contact (like version 1.0.x)?
     
  2. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, to be honest i don't think there is a way to filter the collisions like that (using the physics API or something), i might be wrong. In that case it would be better to disable externalVelocity and use you own collision response.

    The "Contact Rigidbodies" tag was previously used by the CharacterActor. These contacts were coming from dynamic riigidbodies, using the tag "contactRigidbodies" tag, and the flag "firstContact".

    Code (CSharp):
    1. for( int i = 0 ; i < Contacts.Count ; i++ )
    2.         {
    3.             Contact contact = Contacts[i];
    4.  
    5.             if( !contact.firstContact )
    6.                 continue;
    7.  
    8.             if( !contact.isRigidbody )
    9.                 continue;
    10.  
    11.             if( contact.isKinematicRigidbody )
    12.                 continue;
    13.          
    14.             if( !contact.gameObject.CompareTag( tagsAndLayersProfile.contactRigidbodiesTag ) )
    15.                 continue;
    16.  
    17.             collisionResponseContacts.Add( contact );  
    18.         }

    Now there is no need to impose a certain behaviour within the CharacterActor itself, since basically you have the freedom of doing whatever you want with the contacts from outside (probably what most people are going to do). For example:

    Code (CSharp):
    1. for( int i = 0 ; i < CharacterActor.Contacts.Count ; i++ )
    2.         {
    3.             Contact contact = Contacts[i];
    4.            
    5.             // continue if the contact doesn't belong to the contact  layer mask
    6.             if( !CustomUtilities.BelongsToLayerMask( contact.gameObject.layer , contactLayerMask ) )
    7.                 continue;
    8.  
    9.             // Do something with this "contact"...
    10.  
    11.         }
     
    ikemen_blueD likes this.
  3. CastryGames

    CastryGames

    Joined:
    Oct 1, 2014
    Posts:
    77
    work in firts person?
     
  4. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, yes it does, play the demo to see the result, press V to toggle between third person and first person. The character itself has almost nothing to do with the first person perspective, this is a camera thing (95% camera, 5% NormalMovement state).
     
  5. CastryGames

    CastryGames

    Joined:
    Oct 1, 2014
    Posts:
    77
    It has a swimming system, I just saw that you have animations in the project.
     
  6. dmarqs

    dmarqs

    Joined:
    Oct 16, 2013
    Posts:
    41
    Hi, me again.

    I bought the asset today and it has been really frustrating making it work. =/ I have experience, but I can't make it work.

    I'm trying following your doc (its unfortunately confusing):

    1- I created the blank character. The next step you asks to create a behaviour for controlling the character. But that doesn't really goes against what the asset offers? An 3d movement? I looked at your NormalMovement ( I couldn't find a mention of it during the 'How to...') and I copied the content. Is that the right approach? How can I have 3d movement without me writing too much of the code?

    2- After add the blank character (with NormalMovement) to my own scene, Scene Controller keeps giving me this exception

    NullReferenceException
    UnityEngine.Transform.get_rotation ()

    Don't know why it happens, in your own demo that doesn't happen. I really don't have anything in this scene, I just created it and followed along with your tutorial. I tried coping the Demo Player too but it keeps giving me that same exception.

    So as you figured already, I can't make the minimum work. =/

    Sorry if my words look harsh, but it has been very disappointing this whole afternoon trying to make it work. =/
     
  7. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, check the movement reference, from the CharacterStateController, you are probably using a "external" movement reference with a null reference. Since the demo character was prepared for a tutorial in 1.0.5, which included the camera as well.


    If that's the case (probably is) i should've included a warning message, apologies for that :(, will include that in 1.1.1. Thanks for letting me know.

    ──────────────────────────────────────────────
    Also a quick fix for a stupid mistake i made (i found that yesterday). Replace the "for" in line 321 from CharacterStateController.cs

    Code (CSharp):
    1. for( int i = 0 ; i < transitionsQueue.Count ; i++ )
    with the following:

    Code (CSharp):
    1. while( transitionsQueue.Count != 0 )
    If you don't want to do this don't worry, version 1.1.1 (minor version) will be uploaded tomorrow, including this + the warning for the external movement reference.

    Not really, the asset allows you to move in a 2D/3D world, based on a set of rules defined by the character controller features (CharacterActor). If you use the same movement logic from the NormalMovement in a vainilla rigidbody, this will not be able to walk over steps, slopes, it will fall on edges, will not be able to stick to the ground, etc.

    The movement logic is really easy to do, probably represents the 2% of the asset. In fact the whole movement logic can be described as a fancy MoveTowards (Vector3) (although it has a bunch of clever tricks behind). This logic without the CharacterActor is kinda useless.

    From the start i didn't want to force you to move your character in a certain way, for example: you could add a velocity (to the existing one), or set the value frame by frame, maybe add a force, use a PID to set a target velocity (using acceleration/force), or maybe use a root motion-based character (more like all those locomotion system out there), ... there are a lot of ways to move a character.

    The NormalMovement state is a scrpt-based movement state that covers the basic movement of the character (it's more than enough for most cases). You can clone that, derive from that, or create your own state. In other words, it is basically an example, same for the rest of the states (that's why they are part of the Demo). Examples can be valuable as well, but the idea of this controller is to allow you to write your own logic (don't be "scared" with this, you can write your logic in 10 minutes), the CharacterActor should do the rest (plus the state controller). If you don't like that you can use the NormalMovement, it's perfectly fine.

    Yes :), i have a Swimming, RopeClimbing and AntiGravity (like the one in Prey) states for 1.2.0, but those will have to wait for now. They will be part of the demo.
     
    Last edited: Jul 2, 2020
  8. dmarqs

    dmarqs

    Joined:
    Oct 16, 2013
    Posts:
    41
    Hi again,

    Thank you for your explanation and sorry again for the harsh words.

    I still have a few questions:

    Ok, NormalMovement is part of the Demo.

    Looking at your doc again you ask to create a class derived from CharacterActorBehaviour, which goes all the logics. But NormalMovement is a CharacterState and CharacterStateController is derived from CharacterActorBehaviour. So what should I do to create my own movement logic?

    1 - Add CharacterStateController and create my own 'NormalMovement'.
    2- Create a custom CharacterActorBehaviour. ( in this case, that custom class will be like my own 'NormalMovement'? )

    I liked how your demo character is organised, but would like to know how exactly you planned the use of CharacterState and CharacterActorBehaviour classes.


    Another question: I created another blank character now, added the tags and layers and fixed the line of code you asked. When I start the scene, the character don't start falling (it's in the air about the ground) Shouldn't start falling already?

    ˆˆˆˆˆˆˆˆˆ I edited the question above because I already figure it out. =) I was messing with your NormalMovement and found that you handle gravity here too.

    Thank you! =)
     
    Last edited: Jul 2, 2020
  9. dmarqs

    dmarqs

    Joined:
    Oct 16, 2013
    Posts:
    41
    Hi again,

    I'm messing with your NormalMovement again. Why did you choose to separate stuff like ledge climbing but keep together jump and crouch under the same class? Is there any design decision behind that? Or it was just personal preference?
     
  10. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, don't worry, unfortunately sometimes one user has to lose a day or two dealing with some stupid error, this is usually the only way i can note that something is missing, especially since i do most of the work based on demo scenes and prefabs. By the way i already submit version 1.1.1 (pending review).

    If something like this happens again, please send me an email, it will be much faster for me to fix it.

    That's a "Core" tutorial (if you will). This assumes you don't have any content from the implementation at your disposal (for example, you decided to implement your own "logic controller" on top, so you need to create a CharacterActorBehaviour for the CharacterActor). If you want to use the state machine (probably) then ignore this (because the state machine is a CharacterActorBehaviour).


    Indeed, to me gravity is just an acceleration, i never put gravity in a "special" place (like the Rigidbody component does). In the NormalMovement state, gravity means one more "velocity" (although it is an acceleration) applied to the character, you can ignore it or not.

    Because jumping involves just an impulse or change to vertical velocity, most games (especially platformers) use a jump in this way. However, LedgeClambing involves a change in the type of movement (now the character moves using a root motion-based logic), it also involves more specific parameters, inspector fields, another animator controller, etc. Putting all that in one state would be a mess.

    That said, there is not rule or criteria to define where a state starts and where it ends. To me, implementing the jump was easy to do within the NormalMovement state.
     
    twitchfactor likes this.
  11. titoasty

    titoasty

    Joined:
    Dec 2, 2018
    Posts:
    25
    Hi,

    I'm trying to add a custom Input Handler (inherited from InputHandler), but I can't drag'n'drop my class in the Character Brain.
    I selected Custom in Human Input Type, but I can't even drop the base UnityInputHandler.. :/

    Unity 2020.1.0f1

    Thansk for your help

    Code (CSharp):
    1. using Lightbug.CharacterControllerPro.Implementation;
    2. using UnityEngine;
    3.  
    4. public class UnityInputHandler : InputHandler
    5. {
    6.     public override bool GetBool(string actionName)
    7.     {
    8.         return false;
    9.     }
    10.  
    11.     public override float GetFloat(string actionName)
    12.     {
    13.         return 0;
    14.     }
    15.  
    16.     public override Vector2 GetVector2(string actionName)
    17.     {
    18.         return new Vector2(0, 0);
    19.     }
    20. }
    21.  
    EDIT:

    I figured it out.
    I had to create a GameObject first, assign it the component THEN drop the component in InputHandler field of Character Brain.

    EDIT 2:
    When starting the game, the field InputHandler in the Character Brain is emptied...
     
    Last edited: Aug 29, 2020
  12. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, i just replied you by mail. I'll copy/paste the message here, just in case anyone else is experiencing the same issue.
    ───────────────────────────────────────

    I'm really sorry for that, there is a very silly bug with the custom input handler (i forgot to add one line of code). Go to InputHandlerSettings.cs and add the following (see the arrow):

    Code (CSharp):
    1. public void Initialize( GameObject gameObject )
    2. {
    3.         if( inputHandler == null ) //<---
    4.             inputHandler = InputHandler.CreateInputHandler( gameObject , humanInputType );
    5. }
    6.  
    That should work, there is still one more thing to do (removing the "custom" case from the CreateInputHandler method), however that should not be relevant at this point, so don't worry about it

    Remember to create the component (your custom input handler), add it to any gameObject you want, and then drag it to the input handler slot.

    I'll upload (hopefully today, maybe tomorrow) a minor update including this and some other minor improvements. Thanks for letting me know that.
     
  13. titoasty

    titoasty

    Joined:
    Dec 2, 2018
    Posts:
    25
    Yes thanks it worked perfectly!
    Great assey by the way!
     
    lightbug14 likes this.
  14. LTE_

    LTE_

    Joined:
    May 31, 2013
    Posts:
    19
    hello, how can i add pun multiplayer on this?

    And could u explain more on why is the SceneController needed? why doesnt the character use the update from monobehavior?
     
  15. Gaucho

    Gaucho

    Joined:
    Apr 21, 2013
    Posts:
    12
    Hi lightbug14,

    just stumbled upon your asset. What i really like is the "Water" / "Honey"-System, could you elaborate if it can be extended as a system for an astronaut aswell? I'd like to use it in a game, where the player can leave the spaceship and start flying in space as an astronaut. As far as i can see, the player still has some gravity being applied to him - can it be set to zero aswell, so that the player floats in space? Are all other components (like the character response) working aswell when being in water / honey / space?

    Thanks a lot for your reply, looking forward.

    best regards
     
  16. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, to be honest i never tested Photon PUN by myself (i got some results with Bolt, but that was me just playing around for 1 hour). I guess that if you own the player locally (the rigidbody) then you can do whatever you want it (I know that UNET works like this). A CCP Character is just a rigidbody component (dynamic), so if you can send the rigidbody position/rotation over the network then you'll fine.

    I don't promise anything but i'll look into PUN, and see if i can make it work. After that i'll post a tutorial or something in the documentation.

    In 1.1.X the scene controller is responsable of syncing the character position with the platforms. If this is not done the character will always be one frame away from its target destination. This is very noticeable with interpolation enabled, something you'll need to get smooth results.

    In 1.2.X (next major release) this scene controller is not longer necessary, meaning that characters, kinematic and dynamic(now supported) platforms understand each other perfectly.

    Kinematic rigidbodies moves (with interpolation on) using MovePosition/Rotation.If you do the following:
    Code (CSharp):
    1. print( "pos = " + rb.position );    // pos = posA
    2. rb.MovePosition( posB )
    3. print( "pos = " + rb.position );    // pos = posA  <---
    ... you'll see that the position is not updated immediately, which is fine. The position is updated after the physics simulation, so there is no way for me to know if you use MovePosition or not, since i can't get that "posB" position from the vainilla rigidbody. So, the character see that hte platform didn't move, so he/she will not move. The problem is that at the end of the frame the platform did actually moved, causing this delay i was talking about before.


    Hi there, thanks. Every character has a material controller, this component gets the current volume/surface information, which consists basically of multipliers (acceleration, deceleration, etc). The state (e.g NormalMovement state by deafult) is responsible for using those multipliers.
    You can create your own material asset (scriptable object) with all the materials you want (even for the "default material"), and then add that asset to the material controller component. This is the asset:



    What do you mean by character response? These materials are not changing the rigidbody drag or similar, they are totally "fake", only the material controller knows about this.
     
    Last edited: Sep 9, 2020
  17. u39

    u39

    Joined:
    Oct 26, 2018
    Posts:
    2
    I tried the demo scene on the editor, but I couldn't land on the bridge or the rotating floor. Do I need to do any configuration?
    upload_2020-9-11_17-55-10.png
     
  18. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, Did you apply the layers preset to your project? (initial setup, from the docs) If those rigidbodies are marked as "Dynamic Rigidbody" then that should not happen (i'm assuming nothing was modified, especially the "tags and layers" profile). My guess is that those objects are not part of what the character considers as ground, make sure they are part of the "Dynamic Rigidbody" layer.

    Regards
     
  19. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    789
    Hey there!

    I've created a custom InputHandler which returns the X and Y AxisRaw values. This is to clamp movement to 8 directions. Seems to work correctly.

    I'd like to implement the movement system to only allow planar movement if the character has finished turning to face the correct direction. Which script should I be looking to extend to achieve this?

    Thanks!
     
  20. u39

    u39

    Joined:
    Oct 26, 2018
    Posts:
    2
    Thank you for your quick reply.
    English is hard for me.
    For some reason your Docs doesn't have chrome's translation feature working and I seem to have missed reading the settings.
     
  21. Vincenzo

    Vincenzo

    Joined:
    Feb 29, 2012
    Posts:
    146
    Hey, I'm checking out your asset.

    I wonder if it is possible to make the character controller being able to bump into another player without pushing him?
     
  22. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    789
    Looking a bit more into this, I've added this check to the ProcessPlanarMovement method of Normal Movement, in the StableGrounded switch statement.

    Code (CSharp):
    1.  
    2. if(!CustomUtilities.isCloseTo(CharacterActor.Forward, targetLookingDirection, 0.1f))
    3. {
    4.   targetPlanarVelocity = Vector3.zero;
    5.  }
    Seems to work. Would be interested if you would take a different approach or if there are potential drawbacks with this method. (I will override the normal movement class at some point)
     
  23. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    That's really interesting, i'll probably implement it in future versions. By the way thanks for sharing.

    Oh sorry, the initial setup is really simple, just go to the inputs and layers settings and load the presets included with the asset (one for inputs, one for layers).

    Hi, yes you can do that. You can choose your "static obstacle" layer mask however you want.
    In the following gif the layer "Character" is considered as "Static Obstacle".It will work for moving characters of course.


    You can also stand on top of any character.
     
    Last edited: Sep 11, 2020
    omarca14 likes this.
  24. Vincenzo

    Vincenzo

    Joined:
    Feb 29, 2012
    Posts:
    146
    What happens if both players walk into eachother? this makes them both stop moving? slide around eachother?
     
  25. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    it depends on the layers/layers profile of each character.
    Here's an example:


    In this example:
    Red characters are considered are obstacles (layer = "Default", the same layer as the ground)
    White character are normal characters (layer = "Character").

    The layer by itself is not that important, what matters is the "tags and layers" profile (nothing fancy, just two or three layerMask put together into a scriptableObject). This is used by the character controller component (almost in a kinematic way, predicting if the character is going to collide with something). Anything that's not an obstacle will be treated as a normal rigidbody interaction, like two bodies colliding with each other.

    • Two white characters: ChA and ChB do not detect each other.
    • white vs red: ChA detects ChB. ChB does not detect ChA.
    • Two red characters: ChA and ChB detect each other.
     
  26. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    789
    It’s really useful for games where the player needs precise control of what direction to align to. A game that does it really well is Animal Crossing.

    I improved the code I posted to first check if the player is already moving - if they are, then they should be able to change direction freely. But if they are stationary, then they can turn on the spot before moving.
     
    lightbug14 likes this.
  27. jvetulani

    jvetulani

    Joined:
    Dec 20, 2016
    Posts:
    55
    Hi!

    Just bought your controller and I really like it!

    Just of the bat I changed two things:
    In the Animator:

    Going back from Not Grounded to Stable Grounded now goes through the Crouched state to give you an oompf when landing - but ideally I would like to have that transition to be a 2D blend tree where one axis is the vertical velocity (so we can have a soft landing or a hard one with an animation where you lie flat on the ground) and the other axis is planar speed so you can have a different landing while standing still and a different one while running - but since it's a 2D blend tree we have a lot of different behaviours covered - like falling really fast while running really fast, the character would also have a different idle in that state that depends on the vertical velocity. Rn I can't do that since vertical velocity goes down to zero very quickly - I'm guessing it should be some sort of different parameter that persists for a while after landing.

    In the Code:
    In NormalMovement.cs starting on line 671 I added damping and smooth time since some transitions - like run to sprint where too harsh.

    CharacterStateController.Animator.SetFloat( verticalSpeedParameter , CharacterActor.LocalVelocity.y,0.5f,1f);
    CharacterStateController.Animator.SetFloat( planarSpeedParameter , CharacterActor.PlanarVelocity.magnitude,10f,1f);
    CharacterStateController.Animator.SetFloat( horizontalAxisParameter , CharacterActions.movement.value.x,0.5f,1f);
    CharacterStateController.Animator.SetFloat( verticalAxisParameter , CharacterActions.movement.value.y,5f,1f);

    Changing to the new Input System was relatively easy! :)

    Thing's I'm worried about going forward with using it:
    I'm worried about the different AnimationControllers for each type of movement since there's no clear way to blend nicely from running to hanging off a ledge - I'd rather have it in a single animator so I can blend differently when moving, when not grounded, when jumping straight up etc. Possible solution is to use different layers in there to account for transitioning to being on a ledge from different states but it seems like wat too much of a hassle.

    I saw in your documentation that RootMotion is supported - I want to limit foot sliding, is it easy to set up for all kinds of motion?
    Is leaning into the direction of motion supported?
    Can I use an animation with root motion for rotating around the characters axis - so they don't spin on the spot like a drill but take steps in that direction?
    As much as you've made a bangin camera I'd still like to use cinemachine instead, how hard will it be to hook it up myself, or will I need to wait for your implementation? - EDIT: Nevermind, added Cinemachine and it works out of the box, just had to assign the new camera to the character's StateController as an External Movement Reference :)

    Will it work with final IK out of the box?
    Can I have a different set of animations while ascending/descending stairs and slopes.

    Cheers! It's a great asset! :)
     
    Last edited: Sep 12, 2020
  28. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, thank you very much @jvetulani!

    Interesting, i'll look into that.

    I'll probably improve those small details with each update. Thanks for the suggestion.

    Good, I want the "new" system to be the default one. That way i can put the Unity input manager and UI input handlers aside (they will be there as custom input handlers).

    By the way i added some examples to download (CharacterActions and CameraActions) at the end of the "How to" section from the documentation:
    https://lightbug14.gitbook.io/ccp/how-to.../implementation/use-the-new-input-system


    Yes, i agree. You can still use one animator controller, although the current ones (Demo) are not prepared for that. I think Mecanim is one of those things that can save you and sentence you to death at the same time depending on the complexity of what you are trying to do. Just to name one thing, if you are a good citizen and orginize everything using sub-state machines (using Enter and Exit nodes), then you won't be able to customize transitions between different sub-state machines. So, the system encourages you to be messy, and we know that messy + complexity + debugging is not a good mix.

    For smoothing out different controllers i've been implementing a new system based on playables:
    NewAnimsystem.png

    In the image, there is a transition from Dash (a single clip) to Normalmovement (an animator controller).
    You could also define or override different transition durations between states (this was the issue i mentioned before with mecanim).


    it's not there yet, but it will be ready soon :). I was hoping to release this with 1.2.0.

    Sorry what do you mean by motion supported? A full root motion character?

    My NormalMovement state is a script-based movement state, for that you'll need to implement those root motion behaviours. The support is there, you just call CharacterStateController.UseRootMotion = true/false and the rest should be handled by the animation system.

    The character is independent from the camera, so you can use Cinemachine if you want.

    No idea, this is a dynamic rigidbody moving around, if finalIK supports that then yes.

    You will have to implement that yourself, sorry. But that should be relatively easy, get the ground (object, tag, layer, whatever), is it a stair? then go to another blend tree. Finally use a "deltaPosY" as your parameter. That should do the trick.

    Regards.
     
  29. jvetulani

    jvetulani

    Joined:
    Dec 20, 2016
    Posts:
    55
    Thanks for the reply!

    Yeah I don't think I've ever seen a character switch between different character controllers like in your example. An animation controller can't interact with other controllers - you could have layers instead and just change their influence - the added benefit being that you could easily blend different kinds of motion based on layer masks.

    I was asking if a feature that would rotate the character towards the direction of motion already exists in the controller.
    When the character runs forward the whole controller will tip slightly towards that direction - with the pivot for it at the feet. When running right the character will lean slightly forward and slightly to the right - to varying degrees based on the velocity.

    Here's an example he calls "acceleration tilt":


    Are there any downsides? Will I break how the character interacts with physical objects, or do some other kind of damage doing that? ;

    You have that inbuilt parameter for different kind of blending when going down a slope or stairs and one for up that's already in the controller, I was wondering if I could use that to drive a state in the animator using that to have different kinds of animations for walking uphill/downhill/stairs and keep it more "automatic" - it doesn't have to be an animation that fits stairs precisely, just a bit of a different leg or spine motion to indicate going up or down.
     
  30. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    It's possible yes, however the issue you have is that layers are now state machines too.

    A classic and excelent video;), a good example on how some brain can make animations look great and still get good gameplay.

    I think what he is doing is modifying the graphics of the character to get that tilt. Also the tilt action is not constant, it's based on the velocity change.That should be fairly easy to achieve (i think), i will probably include it for future updates, thanks for the suggestion.

    My approach is based on extracting that root motion data and apply it as Velocity. So, everything should work in the same way.

    If the parameter is there, and Unity allows that parameter to be used by the Animator, then yes. if you mean the verticalVelocity parameter, that won't work, since grounded -> verticalVelocity = 0. In 1.1.2 you can use the PostSimulationVelocity for (i forgot to include the "Pre" version *facepalm* ) since this is the velocity projected onto the ground.


    Regards.
     
  31. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    789
    Hey @lightbug14

    If I want to implement a "bouncing" state, where the player can bounce on trampolines, would the best approach be to create a new CharacterState and transition to that, or to just add Vertical Velocity when the player collides with the surface?

    Thanks
     
  32. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, maybe it would be better to modify your current state (Is it NormalMovement?). By default the character won't leave the grounded state unless 1. there is no ground at all or 2. you call ForceNotGrounded. One thing you can do is to use the PostSimulationVelocity property (+ForceNotGrounded) by measuring if its vertical value is greater than some threshold. If so, then call ForceNotGrounded and apply that same PostSimulationVelocity as your velocity (this code example does not use localvelocity, which is the right way to do it):

    Code (CSharp):
    1. if( CharacterActor.PostSimulationVelocity.y > bounceThreshold )
    2. {
    3.       CharacterActor.ForceNotGrounded();
    4.       CharacterActor.Velocity = CharacterActor.PostSimulationVelocity;
    5. }
     
    flashframe likes this.
  33. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    789
    Thanks! That sounds like a good approach.

    Apologies for the questions - I know most of the additional scripts are supposed to be a demo of what's possible - there's just a lot of stuff you've already implemented that is useful to build off of.

    Update:

    I've implemented this and it works really nicely, with one issue. I'm using Vector3.reflect to get the reflection of the movement as the actor hits the surface. But, the planar velocity is overridden by the NormalMovement state as soon as the actor bounces.

    Would I need to temporarily disable the NormalMovement state, or can I add additional velocity to avoid it being overridden?

    Here's my code:

    Code (CSharp):
    1. public class Trampoline : MonoBehaviour
    2. {
    3.     public CharacterActor actor;
    4.  
    5.     public float bounceThreshold = 1f;
    6.     public float bounceStrength = 2f;
    7.     public float maxVeclocity = 20f;
    8.  
    9.     private void OnTriggerEnter(Collider other)
    10.     {
    11.         Vector3 vel = actor.PostSimulationVelocity;
    12.  
    13.         if(vel.y < -bounceThreshold)
    14.         {
    15.             Vector3 normal = transform.up * bounceStrength;
    16.  
    17.             vel = Vector3.Reflect(vel, normal);
    18.             vel = Vector3.ClampMagnitude(vel, maxVeclocity);
    19.  
    20.             Debug.DrawLine(transform.position, transform.position + vel, Color.blue, 4f);
    21.  
    22.             actor.ForceNotGrounded();
    23.             actor.Velocity = vel;
    24.         }
    25.     }
    26. }
    27.  
    Thanks!


    Update 2:

    I think I can tweak the planar movement parameters to get the right feel.

    But still interested to know if "AddForce" is an option in the controller. Or should I just add the force to the Rigidbody?

    Update 3: (Ha ha)

    I realise that the best approach is to just make my own NormalMovement state and add the ability to apply forces. So I'll do that :)
     
    Last edited: Sep 15, 2020
  34. jvetulani

    jvetulani

    Joined:
    Dec 20, 2016
    Posts:
    55
    A few more questions! :)

    1. StepDownSpeed set to something like 0.15 smooths out walking down stairs nicely, but StepUpSpeed doesn't seem to work? Or it's doing something different than I expect it to do - namely walking up stairs doesn't get any smoother. Ideally I'd like the character to go smoothly over stairs - I'll have IK over it anyway.
    2. How would you change the ladder behaviour to be automatic? - walking towards a ladder would initiate climbing up/down instead of a button press.
    Also how to go back to regular movement and away from the ladder after pressing the jump button?
    3. Adding Ledges (tagged as ledge) to dynamic objects doesn't seem to induce the Ledge Hanging behaviour, can this be tweaked or is it some sort of hard limit?
     
  35. noomieware

    noomieware

    Joined:
    Jun 18, 2019
    Posts:
    18
    Hi, importing the CCP into a fresh 2020.1 project, I get compilation errors


    [CompilerError] Cannot implicitly convert type 'CharacterActions' to 'Lightbug.CharacterControllerPro.Implementation.CharacterActions'
    Compiler Error at /Library/Character Controller Pro/Demo/Scripts/AI/AISequenceBehaviour.cs:85 column 22

    Is asset supposed to run in 2020? At least it is written 2019.3 or higher. Did not check in 2019 though.
     
  36. nobluff67

    nobluff67

    Joined:
    Nov 3, 2016
    Posts:
    338
    Hi,

    Interested in this for AI characters, what is the performance like for these situations, when compared with other controllers?

    I would also like to know if you know how this would work with something like puppetmaster?
     
  37. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Hi, Yes it should run fine, i'm using 2019.4 and 2020.1 without any problem.
    Try to re-import the asset again.

    Are you using another asset?



    Hi, i don't think so, or at least i would not recommend both assets working at the same time.
    From PuppetMaster Asset store page:
    "Advanced active ragdoll physics complete with ragdoll creation and editing tools"

    CCP is a capsule-based dynamic character controller. So, i think both worlds (PM and CCP) will be colliding with each other. You can contact the Puppet Master author, maybe he will confirm you this.


    Regards.


    Edit ----------------------------------------------
    Sorry i missed that.

    Do you mean the AI performance cost? The only difference between Human and AI is that a human is changing "CharacterActions" values based on input values. AI changes those values via code (AIBehaviours components).
    It will depend on the AI behaviour itself, for example my "Follow" behaviour uses the NavMesh data to find a path. On the other hand, my "Sequence" behaviour is just the component reading some struct values (the characters from the "Performance" scene use a Sequence behaviour).
     
    Last edited: Sep 20, 2020
  38. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    1. Both stepUp and stepDown put the character from pos A to pos B. The speed is just "interpolating" between those values frame by frame. And yes both should work.

    2. If you want to keep the exact same ladder climbing behaviour (demo component), then go to the NormalMovement state (or the state responsible for starting the transition), and check if the transition you want is valid. Remember that both stateA (the "from" state) and state B (the "to" state) need to validate the transition (if you see the code you'll know what i mean).

    (NormalMovement.cs , CheckExitTransition method)
    Code (CSharp):
    1. //...
    2. else if( CharacterActor.Triggers.Count != 0 )
    3. {                          
    4.  
    5.       //if( CharacterActions.interact.Started )   <--- Ignore this
    6.       //{
    7.            CharacterStateController.EnqueueTransition<LadderClimbing>();
    8.        //}
    9.  
    10. //...
    11. }
    12.  
    The LadderClimbing state will check if that trigger is its own trigger, that's why also the "to" state needs to validate this.

    To modify the ladder behaviour go to LadderClimbing.cs and check the "CheckExitTransition" (same as before). You'll notice that there is a "forceExit" bool that does exactly what it says (it goes from Ladder to NormalMovement). See the switch statement inside UpdateBehaviour (method), based on the current state + your particular condition (jump action), set this forceExit to true and that should do the trick.

    3. Currently my "LedgeHanging" state does not support dynamic objects, sorry. This is something i'll introduce for the CharacterActor component (it'll work just like a dynamic platform) since many users asked me for that.
     
    Last edited: Sep 19, 2020
  39. jvetulani

    jvetulani

    Joined:
    Dec 20, 2016
    Posts:
    55
    Ah, well it seems walking down stairs can be made to be real smooth, but going up won't get equally smooth no matter what settings I input.

    Ah, will have to fiddle with it more I see, that change just makes you stuck in ladder climbing forever. Cheers!

    Another thing:
    After putting the Character and all it's related objects under a parent object for cleanness I was getting Null Reference errors in the Ledge Hanging script, had to change line 359 in LedgeHanging.cs to

    Code (CSharp):
    1. characterBody = transform.parent.GetComponent<CharacterBody>();
    Otherwise it was looking for the component on the new parent object and throwing out errors.
     
    Last edited: Sep 20, 2020
  40. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447

    (Sorry for the bad quality gif)

    Yeah, that was just an example, you'll have to create your own logic (the forceExit variable in the switch), along with the enter and ext conditions. That state is just an example state to show some root motion in action.

    Thanks for letting me know that, i came across that exact same bug/problem. It's already fixed in 1.2.0.

    Regards.
     
  41. jvetulani

    jvetulani

    Joined:
    Dec 20, 2016
    Posts:
    55
    Yeah that is definitely not how it's behaving for me, it acts as if the value is set to 1 no matter which value I set for the step up speed, is there some other property that could be influencing it? Oh well, will have to figure that out I guess :).
    https://i.imgur.com/1VA9eKJ.mp4

    EDIT:
    Ok, found the culprit - it was "Edge Compensation", makes sense I guess if it's using a square collider instead.


    And yeah, the getting on/off the ladder will require that the Player is pointed towards the ladder and actively walking towards it to work nicely - both when going up and down. Interrupting the state while on the ladder was easy enough and just as you pointed it by changing line 260 of LadderClimbing.cs to:

    Code (CSharp):
    1. else if( CharacterStateController.Animator.GetCurrentAnimatorStateInfo(0).IsName("Entry") || CharacterActions.jump.value == true)
     
    Last edited: Sep 20, 2020
    lightbug14 likes this.
  42. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Ohhh, i forgot about that, sorry! The edge compensation feature need to work with the step up/down speed as well.
    Thanks for letting me know that.
     
  43. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,459
    Hi, is it possible to make the package work with unity's new input system.
     
  44. bgyusddssdbui

    bgyusddssdbui

    Joined:
    Dec 8, 2019
    Posts:
    3
    Lol I came here to ask the same question. I'm sure it's possible but how hard is it?
     
  45. jvetulani

    jvetulani

    Joined:
    Dec 20, 2016
    Posts:
    55
    @lightbug14 has a tutorial on his site and a script for that you need to uncomment and place on a gameobject in the scene, as well as an asset with controls in there, it's fairly easy.
     
    lightbug14 likes this.
  46. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    72
  47. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Yes, the input system is really powerful in its current state, so there is no excuse not to do this (from my side).
     
    Broudy001 likes this.
  48. dylannorth

    dylannorth

    Joined:
    Dec 26, 2015
    Posts:
    9
    Hi I've purchased your asset and I'm enjoying working with it but I am trying to hook it up to an interactable trigger system that uses interfaces. Normally I would use OnTriggerEnter on the character and call the Interact method on all found interfaces but I see that there is a "OnTriggerEnterMethod" and "OnTriggerExitMethod" in CharacterActor but there are no script references to that method. Where should I reference that method so I can use your trigger managing system?
     
  49. noomieware

    noomieware

    Joined:
    Jun 18, 2019
    Posts:
    18
    Hi,

    using the CCP AI system, I set up an AI GO to follow my character. Which works initially. Converting this GO to a prefab and adding a second prefab instance (Setting follow target on the instance to my characters GO, as it is a scene reference), only the first prefab instance (the initial one I converted from) actually follows my character.
    The second one just stays at its position.

    What might cause that Issue? Thx
     
  50. nobluff67

    nobluff67

    Joined:
    Nov 3, 2016
    Posts:
    338
    I would not be running them at the same time. Your controller would be active and I only switch on puppetmaster when needed.

    I have come accross this issue before between controllers and puppetmaster, the normal procedure is as follows:

    1. Use character controller.
    2. Switch off character controller when puppetmaster needed.
    3. Switch on character controller when puppetmaster finished.
    So I guess my questions would be can you switch your controller on and off and change the rotation/position.

    e.g.

    1. controller on - character at pos 1,1,1 rot 10,10,10
    2. controller off
    3. controller on - character set to pos 2,2,2 rot 20,20,20