NokiMo
tarodev
tarodev

patreon


2D Controller v3 (Major release!)

Edited: 08/12/24

Greetings!

I've re-written the controller from the ground up to address some major problems which plagued v2. You'll find this controller much easier to implement and use within your games.

Major changes:
It now includes a Physics Simulator, which orchestrates time and fixed time between players and physics movers (like platforms). This ensures frame-perfect coordination between active bodies. The simulator will be created automatically for you and can be ignored.

Secondly, I have come up with an unconventional, but I think superior way of building characters. You can check it out by playing with the Character Size dropdown on the Player Stats asset. This setup allows for much smoother step and slope mechanics.

Other upgrades:

Things to note:

Setup:

I've included a welcome/setup window when you first install the package. You can find it again via the top menu 'Tarodev Controller/Setup Window'. There you'll find an autoconfigure button which will set the required layers for the controller to function. Be sure to set your layers correctly on the 'Player Stats' asset.

The unitypackage is great for dropping the controller in to any project as a lean package. The 'Full Controller Project' is good to open as its own fresh project as a reference. It has everything setup (input system, proper layer configuration, etc.) from the get-go, so you can cross-reference.

2D Controller v3 (Major release!)

Comments

Hi, thanks for this amazing controller!! Is this project under MIT license?

Samuel Tang

Thats just a naming convention, usually for private variables you use underscores

MrVastayan

Thanks for the Update! I also noticed the character doesn't get nudged to the side when you hit the edge of the platforms with your head anymore.

Dmytro

P.P.P.S.: I wonder if it's possible to make 2D controller component-based. Something like you have core component with basic actions and you can add components for optional actions. Not sure how to resolve dependencies and connections between components though. Like sticking to a wall you cannot move on X-axis but you can jump and the jump will not be vertical but at an angle. Maybe something like setting priority parameter for specific axis on component. So that e.g. wall logic will override walk/run logic.

MenasEru

P.P.S.: Extending my thoughts. I looked through asset store and there are few 2D kits that look and feel good (50$+ price range), there are some for 20$ or less that are decent. Still I like how your implementation works. It's dynamic, configurable in physics and feel and snappy. Just a thought.

MenasEru

Hey Tarodev! If you gonna make a new version of controller can I propose to separate common/core and optional platformer actions. With some room for extension. Not sure how better to do it though. The cool thing and the goal would be possibility for extension and ease of hooking new states (input -> game logic -> animation). For core - basic action: idle, walk, jump. For optional - toggable actions: attack with variations (and maybe chaining), aerial attack variations, crouch attack, run, dash to the side, dash down, dash up, roll, slide, crouch, crouch walk, jump anticipation, fall , land, climb ladder idle, climb ladder movement, wall hit, wall idle, wall climb (e.g. NES Ninja Gaiden), wall sliding, wall dismount, wall jump, go stairs down, go stairs up, ledge grab, ledge climb. Idea not to implement all optional states, only some (e.g. basic without in-between states) and allow ease of extension (with minor existing code changes). P.S.: I really like the feel and physics of your controller.

MenasEru

I think you can change AllowDash and AllowWalls in PlayerStats from your script. PlayerStats is publicly exposed in PlayerController attached to the Player.

MenasEru

You can remove squishyness. In "Visual" set "Squish" values to 0.

MenasEru

Hi! Is there a way i could edit the player stats through my own script? I'd like to lock some of the movement skills until certain points in the game.

loky cara

Decided to check this out and made a few improvements. You have a few issues caused by the _airborneCollider disabling on landing (such has MovementEffectors not working if you jump into them, because the disabling collider is triggering OnTriggerExit2D). I figure a good solution is to have triggers like these on their own trigger/effector layer and have the _airborneCollider ignore callbacks from that layer, but that requires some code since you've set HideFlags. You're the dev though and I've only looked at this for an hour. How would you go about it?

CoraBlue

Can you explain to me better how to implement this system in a project from scratch?

Valcinei Nei

Are you planning to fix the bottom part of the stairs? It glitches through the platform if you keep holding down.

Mert Tuğkan Uluşal

if anyone has this issue but with the moving platforms instead, i fixed it by adding this to the platform scripts: private void OnDestroy() => PhysicsSimulator.Instance.RemovePlatform(this);

Pats

Is there a way to turn off variable jump height and have one height no matter how long you press space?

Ethan Roychoudhry

Is there a regular, "non-squishy" version of the character animation controller?

Valid Name

Apparently I'm also a novice with writing in Patreon (the post didn't reflect my full thoughts). Is there a way for me to make adjustments using the inspector for the Player Prefab? Is there a benefit to making it (and other components) uneditable in the inspector?

Finesseful J

Hi I'm new to Unity but this has gone a long way into helping me understand some of it's parts. I do have a couple questions for Rigidbody and the colliders I'm unable to edit them in the inspector.

Finesseful J

I noticed that there were underscores in a lot of your variable names, is there a practical reason for this and if so do you recommend using underscores in my variable names?

gamerperson

Time.fixedDeltaTime is a constant and will always return the value you have set in your project's Time settings. You should really only ever use fixedDeltaTime when you need to read this value for a calculation like slow-mo. If you're after an accurate time-elapsed since the last fixed frame, use deltaTime which will in all stable cases be equal to fixedDeltaTime in FixedUpdate and variable in Update.

(Tarodev) Matthew Spencer

Shouldn't we use fixedDeltaTime in FixedUpdate in PhysicsSimulator? Sorry if someone already asked this.

TheJeff

P.P.S.: Resolved it. Added "if (!InputEnabled) _speed.x = 0;" to ApplyMovement(). InputEnabled is handled outside the controller in player damage logic. Thank you very much for pointing into right direction with PlayerForce.Decay. Btw. Love your tutorial videos and participation in Blathornprod.

MenasEru

P.S.: I tried PlayerForce.Decay. It's a bit better (player "jumps" up noticeable) but the issue with horizontal movement cancelling recoil away from the enemy still there. I'll try to fiddle with the code a bit and if not successful will try moving to V3.

MenasEru

I did some modifications to V2 and kinda tied with game logic this is why I was avoiding upgrade. I think I'll try changing to V3 in the end.

MenasEru

This was one of the areas I improved in V3 with transient forces, which are applied separately to input. It's a little gross in v2, but have you tried apply a decaying force? There's a public method on the controller to do so. I highly recommend upgrading if you can

(Tarodev) Matthew Spencer

Hi Tarodev! I need your help. I'm still using V2 controller and implementing player recoil (jump away) when he's hit by an enemy (like in original Ninja Gaiden). I added following to PlayerController: public void HandleDamaged(Vector2 recoilNormal) { // recoilNormal = Vector2(1;1) // playerRef._HitRecoilForce = 15 ApplyVelocity(recoilNormal * playerRef._HitRecoilForce, PlayerForce.Burst); // Trigger animation and lock animation state Damaged?.Invoke(); } It works well - the player is getting recoiled away. The issue is - if there was movement input before recoil - it negates recoiling. Player doesn't "jump" away from enemy . I added disabling input in Update() but it doesn't resolve the issue. protected virtual void Update() { if (!InputEnabled) return; GatherInput(); } Can you help or advice what can cause this?

MenasEru

I'm trying to put this into a pixel game but it seems to flicker and moves weirdly. how can it be made pixel accurate?

MORPHOICΞ

Removing gravity while grounded provides more accurate ground normal tracing 😊

(Tarodev) Matthew Spencer

Hi Tarodev, great controller - thanks. I had a question. In ToggleGrounded, gravityScale is toggled between 0 and GRAVITY_SCALE. Is this actually needed in your example? (or is it there to make the controller more universal). Thanks T

Tom and Peter

Hey, ive not found a function to make the player fall from one way platforms so i made this solution. private void FallFromPlatform() { if (_groundHit) { if (_groundHit.collider.CompareTag("JumpOverPlatform")) { Collider2D platform; if (_frameInput.JumpHeld && _frameInput.Move.y < -0.4f) { platform = _groundHit.collider.GetComponent(); platform.enabled = false; _rb.AddForce(Vector2.down * 700f); DOTween.Sequence().AppendInterval(0.7f).AppendCallback(() => platform.enabled = true); } } } } Can be improved of course.

Matheus Camargo

No reason actually. I'll convert it over the next time I play with it.

(Tarodev) Matthew Spencer

Hi, Is there a reason you went back to using the animation transition tree instead of handling it in code like in V2? It seemed really clean.

324fdgrw

Ah, I may have forgotten to remove the player from the simulator on destroy. I'll add it in the next patch

(Tarodev) Matthew Spencer

Really love the asset overall. Really smooth movement. One issue, I cannot seem to reload the scene. The PhysicsSimulator keeps trying to access the destroyed Player object. Any tips?

Arnaud Ferreri

I just became a Patreon and do have some minor questions/suggestions. In terms of a suggestion I did be curious if you can add the pushing and destruction of objects as well as to accelerate the down wards momentum when holding the crouch button in the air. My only question I am having is that some of the tiles in the tileset have different colors like the climbable orange tiles. Now I worked a lot in 3D with Unity but never in 2D and can't seem to find out where I am supposed to change the color of these tiles or how I can paint tiles with their own respective colors love some advice/help with that!

Fortnite Guides

10/22/2023 Update: Utility methods added to facilitate loading/saving character state, as well as repositioning and toggling the player. If the controller is acting unpredictable on your terrain, you can now change the 'Position Correction Mode' to 'Immediate' in player stats. I've also added a rough terrain generator to the demo scene for you to test the modes.

(Tarodev) Matthew Spencer

P.S.: Btw. It was really interesting to look into code. I learned a bunch of new things and really liked the idea with player input handling and cooldowns.

MenasEru

It's a good point with the docs. Not fun to do, but very helpful. :) Some less experienced developers may struggle - there is a kind of high entrance point (you need to know new input system, you need to have a good understanding of frame-by-frame logic, scary lambdas and actions, etc.). What difficulties I encountered and would help me start faster: Basic: -Short list of features: move (and physics idea), jump, double jump, wall slide, wall jump, ladder, speed affecter, etc. -Would be nice to know there are toggable features. -How to assign custom character visuals (animations, change collider, toggle or change trails, etc.) Additional, nice to haves: -How to remap keys and how to create new keymaps (modifying input asset, adding new keymaps to PlayerInput struct and GatherInput(), one-line description that after this new keymaps can be used in PlayerController. -Would be nice to have short list of things to do when creating your character. E.g. Step 1 - Create/duplicate stats SO. Step 2 - ...

MenasEru

Cool! Thank you for clarifying! It's actually good that attack was removed since implementations vary.

MenasEru

When I wrote that, I was intending to also place the visual/animation variables on the scriptable stat's object, so it was merely a temporary step which turned permanent (as I didn't put visual on stats). For this release I've removed a lot of the fat to just leave the control logic, which means no attack.

(Tarodev) Matthew Spencer

That is awesome!!! I'll definitely try V3 version after I finish with mini-game I'm working now. I'm only slightly confused - I looked at "Full Controller Project" code for V3 controller and could not find attacking logic. Did I miss it somewhere? Though that's not important for now honestly. I was modifying V2 controller for mini-game mentioned above and noticed that player attack speed/cooldown defined in two places: ScriptableStats.cs -> public int AttackFrameCooldown = 15; PlayerAnimator.cs -> [SerializeField] private float _attackAnimTime = 0.25f; Just was curious - was there a reason not to have single source of data? Or I didn't fully get the logic? My assumption is: 15 frames on 60 FPS is 0.25 seconds. Thanks again for awesome controller! I really like how it feels and it hooked up with custom assets without issue.

MenasEru

We'll continue this in discord~

(Tarodev) Matthew Spencer

Sick

Vampire Heart

Yep just moving over that collider hole. It happens more often when I use a higher slope value.

Zicore

How is that being triggered exactly? Are you jumping or is it happening when you go over that hole in the terrain?

(Tarodev) Matthew Spencer

Any idea how i can stop the controller from yeeting my character through the air? https://i.imgur.com/GNAQ9qB.gif

Zicore

Just added the full project to downloads :) I'll attempt to do up some docs at some stage

(Tarodev) Matthew Spencer

Very very interesting! I suggest you add some support resources: - downloadble copy of final part of the above video - very brief doc on which elements need be swapped to migrate

Simone Avogadro

For sure, and I won't lie I was at the part of making it work with springs and slippy slopes so this is a boon coming in just at the right time. I'll show you the end result

maxim daigle

Well, that sucks :D But it should be extra quick this time now you know what you're doing!

(Tarodev) Matthew Spencer

I had just finished porting the v2 to a 3D controller!

maxim daigle


Related Creators