Search Unity

  1. All Pro and Enterprise subscribers: find helpful & inspiring creative, tech, and business know-how in the new Unity Success Hub. Sign in to stay up to date.
    Dismiss Notice
  2. Dismiss Notice

Character Controller Pro

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

  1. artician

    artician

    Joined:
    Nov 27, 2009
    Posts:
    341
    Did you happen to find a solution to this? I'm also a PlayMaker-centric developer and ran into the same struct-related problems.
     
  2. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    Using Behaviour Designer I was able to setup a basic patrol for an enemy and have them chase and attack the player.
    Now the next step is for me to get the character controller to strip away the unnecessary animator states and extra features like crouch and dash and then somehow put the attack state and animation in hopefully without hassle.

    What's the best way to do that?
    My guess is to use the character in the "Character Scene" [Performance Demo Character?] and convert it into a prefab because it has no animations and most extras are stripped.
    Then in the Normal Movement component disable the crouch. There's no dash I think so I don't need to touch it unless it's hidden in there somewhere.
    There are no animations on that character so I would assume for safety I would still uncheck the "override animation controller" setting and then I should be ready to go right?

    Then what steps would I need to begin to get my custom inputs and animations working smoothly with it without breaking anything for example I would add so on mouse click they attack an enemy and have them animate the upper part of their body only so they can attack while in air and on the floor are there any extra steps I need to consider because of the CCP or is this easier than I think?

    Bit of fun here you can see the enemy AI video I have:
    https://1drv.ms/v/s!AjhzZ7qjdmSBhBkWk2LjIBixHsfq
     
    Last edited: May 10, 2021
  3. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    33
    Hi @lightbug14,

    I'm having an issue with getting my character strafing around a target. The camera is a fixed perspective, I have the player rotating to continually face the target without issue, but I want the movement to always be relative to the camera. That is as the rotate around the target the player needs to change the input direction. Eg when they are below the target they would push w to move towards, when they are on the left of the target they would push d to move towards it, etc.

    Any help you can provide would be good.
     
  4. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    To get your movement based around the camera in the "states" game object you will see a character state controller component and on it you will see in big writing the Movement Reference Parameters. Drag the Camera into the external reference and your movement should now be based on the camera. If you want your movement to be based on a different object like your strafe target then drag your strafe target into that slot and now your movement should be based around it.

    Is that what you were looking for?
     
  5. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    33
    @SilverStorm, I've tried both of those, and neither are working for me. I'm sure I'm missing something but can't see what presently. If I set the strafe target should it be based on the direction between the player and the target or the current rotation of the strafe target?
     
  6. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    I will just throw a mash of stuff at you maybe it will help otherwise you can wait for Lightbug to answer.

    Your movement should be based on the strafe targets transform either local transform or global transform.

    You can see a tutorial on how to rotate around something here but I'm not sure if it will apply to the CCP here:

    In that example your movement should be based on input direction so left input would move it on the X minus while right input would move it on the X plus and similar for Y axis if you are jumping or in the air.

    There is also more if that doesn't help as there is an example scene you can check out in CCP called the Zero Gravity scene that may have what your looking for because the character can move all crazy in the air up and down and you can rotate the view, strafe etc.
    And extra tip if you want to convert a transform from local to vertical for the camera they use TransformDirection in the scripting API.
     
  7. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    33
    Thanks, I think I need to use the Character option on the CharacterStateController but then modify that input value by the direction of the camera, or use the camera as external then modify that by the character direction.

    Just haven't got it working yet.
     
  8. Mythran

    Mythran

    Joined:
    Feb 26, 2013
    Posts:
    71
    Hello,
    How would one into auto-crouch by detecting the height above is less than 2.0f, or top of collider is hit?
     
  9. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    33
    Depends on how often you'll use it. If its only a few times, I just have a trigger collider in the few locations. Otherwise I'd probably check from the fop of the collider
     
  10. Mythran

    Mythran

    Joined:
    Feb 26, 2013
    Posts:
    71
    Code (CSharp):
    1.  
    2. private void OnTriggerEnter(Collider other)
    3. {
    4.     RaycastHit hit;
    5.     if (Physics.Raycast(startPoint, startPoint + Vector3.up, out hit, Mathf.Infinity))
    6.     {
    7.                 float height = hit.point.y - startPoint.y;
    8.  
    9.                 if (height > 0.8f && height < 1.0f)
    10.                 {
    11.                         crouch = true;
    12.                 }
    13.      }
    14. }
    15.  
    or

    Code (CSharp):
    1. {
    2. RaycastHit hit;
    3.     if (Physics.Raycast(playerFeet, playerFeet + Vector3.up, out hit, Mathf.Infinity))
    4.     {
    5.            float height = hit.point.y - playerFeet.y;
    6.  
    7.            if (height > 1.5f && height < 2.0f)
    8.            {
    9.                   crouch = true;
    10.            }
    11.      }
    12. }
    Well i was asking more for a code snippet to see if it can be as simple as this...
    But thanks.
     
    Last edited: May 13, 2021
  11. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    33
    Hi,

    Is there a way to go back to the previous state without know what it was? Eg I have a state that I want to go into then back to the previous one not to a default one.
     
    Last edited: May 20, 2021
  12. Mythran

    Mythran

    Joined:
    Feb 26, 2013
    Posts:
    71
    Yes it is possible, 15:50 starts the implementation of the previous state.
    Just call the previous state instead of calling a specific state.


    Regards
     
    SilverStorm likes this.
  13. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    33
    If I were to write my own I could, but was looking for a way to do it within the ccp statemachine.
     
  14. Mythran

    Mythran

    Joined:
    Feb 26, 2013
    Posts:
    71
    Sorry then. Seemed a generic question.
     
  15. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    33
    All good, will see what lightbug says
     
  16. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    292
    Hi,

    Add this to the CharacterStateController.cs file:
    Code (CSharp):
    1.     public void EnqueueTransition<T>() where T : CharacterState
    2.     {
    3.         CharacterState state = GetState<T>();
    4.  
    5.         if( state == null )
    6.             return;
    7.      
    8.         transitionsQueue.Enqueue( state );
    9.     }
    10.  
    11.     // New stuff -------------------------------------------------------------
    12.     public void EnqueueTransition( CharacterState state )
    13.     {
    14.         if( state == null )
    15.             return;
    16.      
    17.         transitionsQueue.Enqueue( state );
    18.     }
    19.  
    20.     public void EnqueueTransitionToPreviousState()
    21.     {
    22.         EnqueueTransition( PreviousState );
    23.     }

    That's interesting. You can achieve this by using the PhysicsComponent API (SphereCast, CapsuleCast, Overlap, etc) from the CharacterActor. However, i think this would need to be integrated inside the actor (some sort of autoSize feature or something).

    At the moment you can access the CharacterCollisions class (responsible for physics queries ) and then call CheckBodySize:
    Code (CSharp):
    1. public bool CheckBodySize( Vector3 size , Vector3 position , HitInfoFilter hitInfoFilter )
    2. {
    3. ...
    However, this will only tell you if the character is overlapping with something or not, it wont say anything about the target height, which means that you would need to iterate over and over trying different sizes (not the best solution).
     
  17. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    Hello Lightbug I have gone through quite a far with your package and now I have something to show! Attached in the zip is a video of some movement and combat with an enemy.

    I also have some questions, since you've updated your plugin and I'm using it what's the safest way to update it without breaking things. My package should be 1 month old by now.

    Lastly what is the best way to knockback my hero a little bit using the CCP say when an enemy attacks him he should get slightly pushed back? Would Rigidbody stuff like impulse work-meaning I would then need to add a rigidbody to the CCP which might break something or does the CCP have a custom integration for knockback?:

    Update: I've noticed on play a rigidbody is attached to the player magically, is this ok to call methods on like impulse?
     

    Attached Files:

    Last edited: May 24, 2021
    lightbug14 and Broudy001 like this.
  18. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    292
    Nice! glad to see the project is growing.

    The best way to evaluate this is (1) by knowing how the asset is versioned and (2) by reading the release notes.
    My way of versioning the package is based on risk.
    - "Fix/patch" updates are pretty safe, meaning that you won't experience issues.
    - "Feature" updates can introduce a few important changes, normally this involves console errors (API changes) but nothing extremely different (2 min changing stuff and you will probably be ready to go, it depends on the update).
    - "Major" updates really change the package (like a "v2" version of it).


    I don't recommend this since there are properties that are being controlled by the character actor (physics material, drag, angular drag, etc). It is true that you can change the mass, the friction, use joints, that's ok. However, there is no guarantee that everything is going to work (compared to a vanilla RB).
    Also this component is trying to predict a lot of things, so "velocity" (prior to the physics simulation) is what this controller use. Impulses and forces doesn't manifest in any way (at least Unity doesn't expose this to us), so they normally get completely ignored by the actor.
    There is a way to use similar functions, just get the RigidbodyComponent component (from CharacterActor) and call them from there. For example:
    Code (CSharp):
    1. CharacterActor.RigidbodyComponent .AddForce( ... );
    These methods translate forces into velocity (the result should be pretty much the same).
     
    SilverStorm likes this.
  19. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    What do you think would be the best way to make the player get knocked back based on the enemies facing direction. So if the enemy is looking at the player the player will be knocked back backwards.

    Using that code in the fixed update is creating strange results.
    The player will not move at all if the value for example on the x is below 50.
    Making is above 50 the player moves about 2 metres away.
    When the player is in the air he moves triple the distance which doesn't seem right....
     
    Last edited: May 28, 2021
  20. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    292
    It depends on the the knocked back (KB) effect that you want. You can produce a "natural" KB based on the current acceleration/deceleration settings (from NormalMovement). For example, if you character deceleration is too high (e.g. mud material) impulses won't last long. On the other hand, if this deceleration value is super low (e.g. ice) the KB effect will last "forever".
    This is one way to do it. You can also produce that KB manually by specifying a certain duration + initial velocity (the dash effect works in a similar way). This ignores any acceleration/deceleration settings, since you are controlling the velocity frame by frame.


    I think the stable state might be affecting your character, especially if the KB direction is not projected onto the ground plane. Stable characters don't have any vertical velocity (this stuff is handled internally by the actor). You can try to call ForceNotGrounded before applying that Force/Impulse, just to see if the results are consistent. This is why producing a jump requires a ForceNotGrounded call, all that vertical velocity will be lost if the character remains stable.
     
  21. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    The kind of KB I am looking for is a very simple one where the player gets hit by an enemy and is launched back a small amount say 50cm. It should be a universal effect that doesn't take into account your speed or environment. They usually get KB based on the enemy's forward facing direction to push you away from them or it could be a random direction push away. The effect should work the same whether you are in the air or on the ground. It is a straight line knockback rather and not a launch in the air kind.

    The Dash example is a great example of the kind of knockback because it freezes the player for a bit and that's cool. So I was thinkig to have that kind of effect but keeping the player looking at the enemy as he is pushed back whether on land or air. If he is pushed back while in the air we can continue gravity or we can freeze it until the knockback finishes whatever is better.
    Lastly I recall that in the demo there are wind forces that affect the player on that spinny thing so I'll look into that too.
    While it's not mandatory most platformers have an effect which will kick the player backwards if the get hit by an enemy or come into contact with a dangerous obstacle-it's a very basic implementation but it's pretty cool.
    Since your controller interferes with the usual rigidbody and physics commands that Unity has implemented it forces me to ask you to create some clear example code if possible and post it here so that others can utilize this with the CCP.

    Is that a reasonable request?
    *The knockback should not allow the player to control the character during it's duration which is usually half a second or less.
     
    Last edited: May 29, 2021
  22. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    I have another question regarding how to kill the player and also kill the CCP from processing so that player can focus on the Game Over menu or lose a life and respawn.
    This is my current code to stop the player from moving, jumping and rotating.
    This works fine but I'd like your input in cases changing these values would break anything elsewhere in the CCP.

    Does the CCP have a simple bool call or anything like that to do what I'm trying to do or will what I have do fine for killing the player and general control?

    if (Health <= 0)
    {
    Player_Audiosource.PlayOneShot(playerdeathsfx, 1);
    IsAlive = false;
    Animator_Reference.SetBool("Is Alive", false);
    CharacterStateLink.GetComponent<NormalMovement>().verticalMovementParameters.canJump = false;
    CharacterStateLink.GetComponent<NormalMovement>().planarMovementParameters.baseSpeedLimit = 0;
    CharacterStateLink.GetComponent<NormalMovement>().planarMovementParameters.canRun = false;
    CharacterStateLink.GetComponent<CharacterStateController>().ExternalReference = null;
    CameraReference.GetComponent<Camera3D>().enabled = false;
    }

    The current code will stop his speed, stop his ability run and jump and it stops his ability to rotate his body and stops the camera's ability to rotate. In theory I reverse this and everything should be up and ok (he comes back to life).

    The only issue is warnings that the character external reference cannot be empty lol.
     
    Last edited: Jun 4, 2021
  23. willrhodes

    willrhodes

    Joined:
    Mar 2, 2018
    Posts:
    3
    Has anyone run into any problems with using a Cinemachine Collider with this asset? I'm having an issue where whenever the Cinemachine Collider hits something, my character becomes ungrounded/unstable, even when just standing perfectly still. I'm just using the NormalMovement state from the Demo for now.
     
  24. Broudy001

    Broudy001

    Joined:
    Feb 12, 2020
    Posts:
    33
    None that I've noticed so far, but I'm not using normal movement state
     
  25. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    It's been a week and there's not been a response to any questions. Hope @lightbug14 is ok.

    *Note: I'm trying to make the player bounce on a trampoline and this issue also ties into the last post about knockback as that also is not working right but these are connected issues.

    I think there may be a bug with this package where collisions are not registered properly.
    It's very simple in the characters script just call the oncollisionenter or ontrigger enter which looks for a tag for the object that you collided with and have it print a debug log telling you that you collided with it like so:

    if (other.gameObject.tag == "Trampoline" && GetComponent<CharacterActor>().IsGrounded == true)
    {
    Debug.Log("We hit the collision object");
    }
    My issue is depending on the version of the CCP it will either not register the collision at all or causes issues only registering whenever it feels like or only the sides of the object I hit.

    In general I am having a lot of trouble figuring out how to detect if the CCP has landed on the surface of an object with it's feet. I have given a tag but obviously that code is detecting the sides of the CCP and not the bottom or top.
    I cannot find anything in the reference documentation regarding if the feet of the CCP has hit an collision object. Furthermore OnTriggerEnter is only working when the character jumps off the object and not onto it (Works better in newer update but only some of the time registers).

    So I'm getting really annoyed here I cannot proceed further with the CCP until these problems are addressed it's clearly a bug since the update has changed some of how it works but it's still bugged.

    Another issue Is that I'm not using the Normal Movement parameters I am using my own but I am getting constant warnings that I don't have the animation parameters It's asking for.
    I had to disable the public override void PreCharacterSimulation( float dt ) method in order to stop the errors. I don't get why it's demanding these off me since I have set the override animation controller to be false.
     
    Last edited: Jun 10, 2021
  26. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    292
    I've been very active (the email is the official support channel). In fact, i'm replying now because you've sent me an email ;)
    I'm fine thanks.

    No error, the collider is not touching the ground (OnCollisionEnter won't be called at all). This is why you have a ground trigger option in the inspector. You can use this to trigger events from external components (e.g. jump pad from OnTriggerEnter). If you need to do the same thing from the character pov then use CharacterActor public properties.


    Here you have the API reference: https://lightbug14.github.io/lightb...troller_pro_1_1_core_1_1_character_actor.html
    And this is from the documentation:
    https://lightbug14.gitbook.io/ccp/f...or/collision-properties#collision-information

    You can use if( IsGrounded && !WasGrounded){...}, or maybe use the event OnGroundedStateEnter, or maybe asking for the GroundObject properties (transform. rigidbody, collider, etc. ). Do you need this information before or after the physics simulation?

    This public field overrides your current runtime animator controller with a new one. However, this doesn't mean your Animator should stop getting updates from the state (e.g. one big animator + multiple states updating data).
    If you don't need these parameters then ignore/remove them. You can either remove the method (like you did) or remove the parameters (fields).

    It is working for me. If you think this is not working as expected then report a bug (to my email of course, then upload it here if you want). I would need:
    - step-by-step instructions on how to reproduce the issue.
    - version of the asset.
    - relevant scene elements if needed (or maybe a unitypackage).
    - extra info (always help).

    What Physics calculations exactly? The controller is not doing physics calculations at all, it is just creating a displacement vector from an input velocity, and doing physics queries in order to predict movement (modifying an existing input velocity). Physics calculation (= defining that input velocity) is something you (the user) needs to do.
    Collision detection/response (+messages/events) is handled by Unity.

    Well, mainly because:
    1. This is not the place to report bugs. Also i didn't receive any messages related with this,so maybe this is happening only to you (due to scene settings, character properties, code, or whatever). If you want to share X bug with others then it is perfectly fine, but remember that the email goes first.
    2. Is this an issue or not? Maybe the result you are getting is expected in a way. By "expected" i don't mean it is good for your particular project.
     
    Last edited: Jun 11, 2021
    SilverStorm likes this.
  27. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    658
    No worries I will start sending emails, I will do my best to record a gameplay footage and show you my setup and code so we can track this down.
     
    lightbug14 likes this.
  28. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    292
    That would be great, thanks.
     
  29. ml785

    ml785

    Joined:
    Dec 20, 2018
    Posts:
    32
    Hi,
    How do you think this asset would do for getting a "hookshot" ability to work?
    Like this (First 5 seconds preview it):


    Do you think a hookshot ability would work with CCP? If I bought CCP, I would have to follow a way different method to get hookshot working with CCP than than just copying a random YouTube video's Rigidbody-based code, right?

    I am just trying to gain an understanding of how the process would be to add hookshot to CCP. Thank you
     
    Last edited: Jun 13, 2021
  30. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    292
    Hi @ml785 ,
    You can add any kind of joint to the character. One thing to consider is that the character (especially a "stable" character) will still execute its internal tasks such as projecting velocity, sticking to the floor, follow a platform, maintaining the rotation, etc (see the video). For this particular case, your character will be unstable (not grounded) while using the gun, so i think it will behave just like the one in the video.

    Here is a little video i made (the values are wrong, sorry for that).

     
    ml785 likes this.
unityunity