Collide And Slide - *Actually Decent* Character Collision From Scratch

Поделиться
HTML-код
  • Опубликовано: 4 июн 2024
  • How to make actually decent collision for your custom character controller. Hopefully you find this helpful and people will finally stop saying "jUsT uSe DyNaMiC rIgIdBoDy!!!1!!11!!"
    Chapters:
    00:00 - Intro
    01:09 - Algorithm
    05:11 - Implementation
    Improved Collision detection and Response (Fauerby Paper):
    www.peroxide.dk/papers/collis...
    Improving the Numerical Robustness of Sphere Swept Collision Detection (Linahan Paper):
    arxiv.org/ftp/arxiv/papers/12...
    Motion graphics made with motioncanvas.io/
    Intro music:
    Woody Path (Eastward OST)
    Music provided by #uppbeat:
    uppbeat.io/t/kem/reborn
    License code: M8NYNY1BFZVQQIKR
    ---------------------------------------------------------------------
    Main channel: @poke_
    Twitter: / poke_bd
    Twitch: / poke_bd
    Support me on Ko-fi: ko-fi.com/poke_bd
    #unity #collision
  • НаукаНаука

Комментарии • 312

  • @cauhxmilloy7670
    @cauhxmilloy7670 9 месяцев назад +147

    It is nice to see push back on the annoying trend of internet replies which promote not trying and just generally being dumb. Making things from scratch, or making your own version of something, is very powerful. It's really at the heart of engineering, understanding, and creative expression. Thank you very much for promoting people to not just accept the status quo. Reinventing wheels isn't bad when available wheels suck. Instant like and subscribe.

    • @poke_gamedev
      @poke_gamedev  9 месяцев назад +42

      Yep. So much wrong with many of the resources available to beginner game devs. I literally just responded to another comment saying "tHiS iS cOmMoN kNoWlEdGe" and that the video is pointless. So even this guy who DOES know the "right" way doesn't want it to be shared for some reason!!! So much dismissal and gatekeeping all around.

    • @Gabriel-no6wv
      @Gabriel-no6wv 7 месяцев назад +1

      E.X.A.C.T.L.Y

    • @user-og6hl6lv7p
      @user-og6hl6lv7p 4 месяца назад +1

      @@poke_gamedev Tbf, the reason so much misinfo is being spread is precisely due to the lack of gatekeeping. People who aren't passionate about solving problems enter the field and just copy-paste code and tell people to do the same. There's nothing wrong with letting people in who are interested, but those who do not fundamentally care should probably be pushed away.

    • @lanchanoinguyen2914
      @lanchanoinguyen2914 3 месяца назад

      Yes but it's far from making game engine.

    • @kevinquintana3085
      @kevinquintana3085 Месяц назад

      ​@@user-og6hl6lv7pyup but we have then two problems here gatekeeping and copy-pasters, gatekeeping prevents knowledge to be shared and as an extra we need to deal with the flexing, copy-pasters spreads the black box way of thinking should I say ¿? Also the Swept AABB algorithm from gamedev page doesn't works

  • @Sophed
    @Sophed 10 месяцев назад +139

    This is unreasonably underrated, incredibly high quality content. Keep it up man

    • @BleachWizz
      @BleachWizz 9 месяцев назад +1

      the video literally starts with a tale i've been trough. I've been looking up to specifics on the collide and slide in video form for a while man...

    • @appleseedgames6934
      @appleseedgames6934 2 месяца назад

      @@BleachWizz I don't understand why you didn't just use a rigidbody controller this whole time, literally the same but better. Seems there's 4.9k people who should've just used Google to learn what a rigidbody is lmao

  • @kasperfauerby7389
    @kasperfauerby7389 8 месяцев назад +47

    I'm happy to see you found my old paper useful! Not quite sure I follow the reasoning behind normalizing and re-adjusting the length of the projected vector in the sliding part, but this has been discussed in the comment section already ;) Great presentation and great video though!

    • @DrazkurHW
      @DrazkurHW 8 месяцев назад

      ah I picked that up as well, glad I was not the only one

    • @enriquebp6070
      @enriquebp6070 7 месяцев назад

      Do you like Frank gambale?

    • @ghostbusterz
      @ghostbusterz 6 месяцев назад +3

      Basically, when you project the velocity vector onto the vector (or plane) of the wall, it's length is only as long as the velocity vector *in the direction along the wall.* If he normalizes it, converting it to a unit vector (with length of 1), and then scales it by the length of the original velocity vector, he retains the full movement of the velocity vector but in a direction along the wall instead of into it.

    • @1234macro
      @1234macro 3 месяца назад +1

      @@ghostbusterz It's more accurate to keep the rejection vector as-is. By normalizing and subsequently scaling, the object will always move at full speed when grinding against a wall because the surface normal will almost never be perfectly perpendicular to the object velocity.

    • @ghostbusterz
      @ghostbusterz 3 месяца назад +2

      @@1234macro In video games we don't always want accuracy. It would be more physically accurate but that's not always what's most important for a given game's design.

  • @shadowofcat
    @shadowofcat 9 месяцев назад +11

    bro came out of literally nowhere and made one of the most helpful and high quality ive seen in a very long time

  • @yuichikita6018
    @yuichikita6018 10 месяцев назад +104

    For Godot users: This is said in the documentation but, if you ever want to do this in Godot (with that I mean don't want to use the built in move_and_slide function), the engine provides the method move_and_collide() that does the collision casting + the movement, and the Vector2/3.slide() function to calculate the reaction movement.

    • @foxto100
      @foxto100 10 месяцев назад +15

      also, the move_and_slide, and move_and_collide both handle Collison overlapping so it will push out of a clipped surface.

    • @mohamedmoh5789
      @mohamedmoh5789 9 месяцев назад +2

      Wait , isn't the move_and_slide_on_slops function supposed to do this work for us ?

    • @yuichikita6018
      @yuichikita6018 9 месяцев назад +9

      ​@@mohamedmoh5789 I meant if you want to implement the movement yourself. Which is better if you want to have more control over the physics of the game.

    • @user-og6hl6lv7p
      @user-og6hl6lv7p 4 месяца назад

      Doesn't work so good unfortunately. It sort of breaks and introduces horrid jitters if you introduce complex geometry.

    • @mikemhz
      @mikemhz 3 месяца назад

      @@user-og6hl6lv7p What about when using the Jolt physics plugin?

  • @poke_gamedev
    @poke_gamedev  10 месяцев назад +146

    Update 2: Ok so Unity is currently imploding... I was working on refactoring and adding stair detection, but I might take a detour and learn Godot now lol
    As someone in the comments pointed out, maintaining full velocity on slopes is not very physically accurate, so I thought I should clarify that all the fancy scaling I'm doing is specifically meant for *character movement*, and should be ignored if using this code for a more general physics engine!
    Again, thanks for watching, and I hope you found this video helpful!

    • @uncleg1214
      @uncleg1214 9 месяцев назад

      And stairs?

    • @AgnisNeZvers
      @AgnisNeZvers 9 месяцев назад +6

      It looks like that extra scaling with dot product ends up simulating the thing you already would get by projected slide. Although, it gives a control if you want to maintain full velocity.
      Also, In the place of a situation with a next wall, there is also an opposite problem - overshooting a corner.

    • @kenonerboy
      @kenonerboy 9 месяцев назад +5

      That would convince me, if you didnt scale it again based on the angle between the wall and surface. You'd get that for free if you didnt scale the projected vector. Its also what happens irl minus the friction

    • @hi_its_jerry
      @hi_its_jerry 8 месяцев назад +1

      im ready for waves of godot tutorials 🤤

    • @fernandes_L
      @fernandes_L 8 месяцев назад

      I would like to see the next part with the stairs detection 😅

  • @albingrahn5576
    @albingrahn5576 10 месяцев назад +72

    good video! just wanted to point out that normalizing the vector at 4:00 only to multiply it by the dot product at 9:05 is unecessary since it reverses the normalization (it's like if you would multiply a number by 10 and then divide the result by 10, the second operation reverses the effects of the previous one). if you only want that "sliding along the wall" effect you can skip both steps to get the same result cheaper.

    • @rhedgeco
      @rhedgeco 9 месяцев назад +19

      Was gonna come to say this ^
      I believe that's also part of the original paper. The slower sliding along the wall when more perpendicular appears naturally as a result of projecting the movement vector along the normal plane.

    • @TheChucknoxus
      @TheChucknoxus 9 месяцев назад +4

      He makes a distinction between horizontal and vertical movement so no you do not get the same result

    • @kingbling7571
      @kingbling7571 9 месяцев назад

      U only move in horizontal tho

    • @official-obama
      @official-obama Месяц назад

      @@TheChucknoxus but why not just not do the scaling at all?

  • @Banaaani
    @Banaaani 10 месяцев назад +16

    I have roughly 5 years of pretty much daily experience with Unity and C#, and I still learned a lot in this video. Awesome stuff!

  • @jannagilleman4101
    @jannagilleman4101 10 месяцев назад +70

    here before this blows up

    • @lyn10gaming
      @lyn10gaming 10 месяцев назад +1

      Let's see how it goes

    • @alex.g7317
      @alex.g7317 9 месяцев назад

      Lettuce see how this goes

    • @macreator9497
      @macreator9497 9 месяцев назад +1

      Can i stand here with you

    • @unddev
      @unddev 9 месяцев назад

      yea

    • @blacklistnr1
      @blacklistnr1 9 месяцев назад

      here while this is blowing up

  • @jadephoenix5837
    @jadephoenix5837 9 месяцев назад +2

    Arguably one of the most well presented tutorials Ive ever seen. Fantastic job!

  • @Saidriak
    @Saidriak 9 месяцев назад +1

    So glad someone answers this question properly, a year or two ago I couldn’t find any help on the matter and came up with my own hacky but functional solutions

  • @kruth6663
    @kruth6663 9 месяцев назад +3

    This is easily one of the best videos about movement and collision I've seen on youtube.

  • @lorz9442
    @lorz9442 8 месяцев назад

    The explanations and production value of this video is off the charts! Awesome video :) thanks

  • @FractalWanderer
    @FractalWanderer 9 месяцев назад +4

    Dude, this is THE most underrated channel I've ever seen. Top notch content, will be using this, and I subscribed

  • @rhythmmmmm.
    @rhythmmmmm. 9 месяцев назад +8

    This video probably would have helped me out tremendously a few years ago. I self taught myself Unity and refused to use anything anyone else made, so I spent probably a good year perfecting the movement in my own game, trying as hard as I could to figure out the stuff you're describing in this video. I eventually did it with a slightly different method, and I don't regret it because it ultimately taught me so much about the way things work, between time, frames, how acceleration, velocity, friction, etc work, but it's good that nobody else will have to go through the hell that I did.
    The issue you have described around the 10:30 mark ended up with my character getting their head stuck on any negative angle ramp collision, and at a certain point, actually ended up making them able to walk up the ceiling like a spider. I don't remember what I did to fix it, but I'll have to check out the paper on it.

  • @gftk5566
    @gftk5566 9 месяцев назад +1

    Underrated. I see this is the first video in this channel so, no hopes are gone. Expect to pop off!

  • @TacoTechnica
    @TacoTechnica 9 месяцев назад +6

    Yes! Thank you for helping more game devs break out of their rigidbody crutches!

  • @dvzdev
    @dvzdev 8 месяцев назад

    This is incredible video quality! Needs to be seen by more people, hope you get the attrntion you deserve

  • @nokkturnaldev
    @nokkturnaldev 10 месяцев назад +2

    Absolutely fantastic! Please keep making videos.

  • @BulletsToBrainRatio
    @BulletsToBrainRatio 7 месяцев назад

    Thank you so much! I was looking for a solution when I was working on my own movement controller, and adding a speed boost would thrust me through geometry.

  • @yam-ingtonjr7606
    @yam-ingtonjr7606 10 месяцев назад +7

    such good visualization of vector math!

  • @iHeartGameDev
    @iHeartGameDev 8 месяцев назад +4

    Awesome video! Welcome to RUclips! Subbed 💛

  • @vitorcedrim6804
    @vitorcedrim6804 8 месяцев назад

    Thanks for the high quality content, keep going!!

  • @jamesclark2663
    @jamesclark2663 9 месяцев назад +6

    I've written many many character controllers over the years and this one is pretty top quality for how simple it is. In fact, it solves an issue I currently have which is that the controller I designed for my player is very fully featured but a bit too heavy-weight to use at scale. However, I needed a character controller that functioned similarly for NPCs. This little function saved me at least a day of tearing out chunks of some of my own controllers to get something that functioned well and was still resonably performance. Great video!

    • @ReimsForYou
      @ReimsForYou 9 месяцев назад +1

      And could you explain to me some things (I'm just a beginner, and in some places I may not understand). Does everything work purely on colliders, without using RidgedBody? I also didn’t understand where he got the variable "bounds" and "layerMask". I will be very grateful)

    • @jamesclark2663
      @jamesclark2663 9 месяцев назад

      @@ReimsForYou Yeah, there are a few minor things like I noticed too. The bounds are obtained from the collider(s) you would be using for your character - in most cases a single sphere or capsule, though in theory you could also use extend the bounds to include multiple colliders. In my case I'll probably go with a public Collider field in the MonoBehaviour that allows me to pass a reference to that collider. Then in Awake() I'll calculate the bounds and extend it by the skinWidth (the code for that is shown very early in the video). Then you can simply assign 'bounds' to 'MyCollider.bounds' within the CollideAndSlide function and it should just work. 'layerMask' is a similar deal. Just make it a public field and then you can assign whatever layers you want in the inspector. This code appears to move this object via its transform which implies that the collider would be a trigger and there would be no rigidbody attached. Likely in my case I'll end up attaching a rigidbody, marking it as kinematic, and keeping the collider as-is rather than making it a trigger and then moving the object via the Rigidbody's position value instead since I'll be needing physical interactions such as pushing other things around. Also, turning off the grabity for the rigidbody would be a good idea if you intend to use the built-in gravity this example provides.

    • @kingbling7571
      @kingbling7571 9 месяцев назад

      ​@@ReimsForYou he has a collider on the body (sphere collider in this eg). The collider has a variable called bounds you can access from collider.bounds as shown in the video. It is there for the Sphere Cast. As for layermask, you can set a specific layer for collision check when sphere casting say you want to check if your character is only colliding with a specific layer eg. Layer 8 ur layer mask value will be 2

  • @paomiank9796
    @paomiank9796 10 месяцев назад +3

    Thank you bro, your video is really helpful and easy to understand.

  • @PuckDev
    @PuckDev 10 месяцев назад +2

    Love this. Super useful 💪🏽

  • @simonsvoboda8849
    @simonsvoboda8849 10 месяцев назад +1

    Right on time. I was just doing collisions today (for my game-engine-less game). Guess I'll be rewriting it tomorrow after watching this video lol. Anyways, this is just what I was looking for and couldn't find. Thanks!

  • @andremarques4063
    @andremarques4063 9 месяцев назад +2

    Poke Dev, you are amazing. Poke Dev please continue posting videos.
    Just writing your name so the algorithm can push you up. Damm, this video was amazing. From the editing to the content, it was so nice to watch I was thinking I was watching a Million subscribers youtube channel.
    Keep it up and you are going to make it far!

  • @KronugiN
    @KronugiN 4 месяца назад

    This is exactly the thing I was working on myself and came as close as a hair's width to figuring out before switching to simply using velocity-based rigidbody controller. I didn't go as deep as reading an actual SCIENCE PAPER, though. Have been waiting for a continuation of this for quite a while and if you're still going to do this - it'd be incredibly interesting to see how you would solve stairs and slopes in a controller like this. Cheers!

  • @catfree
    @catfree 9 месяцев назад

    I like how this video teaches you why it does instead of only how it does

  • @thewowo
    @thewowo 9 месяцев назад +7

    Finally! Someone who understands my frustration with character controllers. Lack of interpolation between fixed update steps in the built-in one is by far the biggest drawback for me.
    Great video! I've never considered a recursive approach, I always go iterative.

  • @goodboi42
    @goodboi42 10 месяцев назад +1

    Fantastic video and explanation.

  • @LeftoverAtoms
    @LeftoverAtoms 9 месяцев назад +2

    This was life changing 😮

  • @blinkachu5275
    @blinkachu5275 10 месяцев назад +6

    Thank you
    I have been on the receiving end of the dismissal quite often, when to me, yes, I could use the premade CharacterController or Rigidbody that does "everything for me" but like... I don't learn from that. All I learn is how to control that specific component, not how a Character Controller *actually* functions. Not how Collision *actually* functions.
    Most these people couldn't make a game without the use of these tools. Which is fine, the tools are there so it's fine to use them, but I am tired of the dismissal when someone is genuinely interested into just learning "what's under the hood"

    • @poke_gamedev
      @poke_gamedev  10 месяцев назад +4

      Yeah, not to mention that in Unity, the built-in character controller is just... not very good lol. It's honestly one of the main things Unreal and Godot have over Unity, and is definitely why the "uSe DyNaMiC rIgIdBoDy" suggestion pops up so often. People know it sucks but can't be bothered to actually find a better way.

    • @blinkachu5275
      @blinkachu5275 9 месяцев назад +2

      @@poke_gamedevyou're so right. Not being able to do anything on any other axis than the up axis in Unity with the CharacterController is so weird, you'd think they would've fixed it by now

  • @davidmc971
    @davidmc971 9 месяцев назад +1

    Really nice overview! Even though I would personally keep the velocity decrease on hitting an edge instead of decreasing later on. Saw your pinned comment on this too. Thank you!

  • @3d_eric
    @3d_eric 21 день назад

    Great explaination! With the help of your video i implemented the algorithm in a custom godot character controller. Right now i only use a raycast, but i will transfer the logic to shape casts, which is the equivalent of the sphere cast in unity.

  • @jzeltman
    @jzeltman 10 месяцев назад +2

    great explanation

  • @t-ree
    @t-ree 10 месяцев назад +2

    Well done btw this video will blow up soon so remember me when you become famous ❤!

  • @1ballad
    @1ballad 10 месяцев назад +2

    nice video, this is probably gonna get boosted by the algorithm

  • @thatperson9478
    @thatperson9478 10 месяцев назад +10

    hit and run? nah, I prefer collide and slide.

  • @daytonode
    @daytonode 9 месяцев назад +4

    I was toying around with this a while back but I was having a miserable time finding good sources of information for it, as comprehensive as this anyway. How are you able to find all this information so easily? I even consider myself pretty good at googling.

  • @user-sk4fx2tk1x
    @user-sk4fx2tk1x 6 месяцев назад

    THIS IS AWESOME

  • @Saandy_
    @Saandy_ 7 месяцев назад

    Great stuff!

  • @Josephryanbanks
    @Josephryanbanks 9 месяцев назад +1

    Great vid man

  • @anda9169
    @anda9169 9 месяцев назад +1

    Truly underrated

  • @Wishbone_Games
    @Wishbone_Games 9 месяцев назад

    Man this is such a well made video, genuinely got better quality than me-whos been doing yt for a year, on your 2nd video????? You are going places

  • @mementomori7160
    @mementomori7160 7 месяцев назад +1

    It's funny how I tried to make a character controler on my own quite a while ago and was smart enough to came up with this, but stupid(inexperienced) enough to fuck up when coding it, your vid makes me want to come back to that project and try again

  • @tianqigao869
    @tianqigao869 9 месяцев назад +1

    awesome!

  • @monkeydgoofy8074
    @monkeydgoofy8074 10 месяцев назад +1

    aight man your amazing video earned you a new subscriber

  • @T0MA5
    @T0MA5 8 месяцев назад

    would love to see more videos like this

  • @falconegaming
    @falconegaming 5 месяцев назад

    I can't seem to figure out why it drags going uphill at times, but the video taught me a lot.

  • @Bloodthirst
    @Bloodthirst 9 месяцев назад +3

    Good stuff , one thing i want to note is that i see you're using .normalized a lot even when the magnitude is already computed before-hand , since vec.normalized == (vec / vec.magnitude) i'd highly recommend getting the magnitude once and just dividing by it if you need a normalized vector (or even better keep "1 / magnitude" and multiply by it instead since division is slower than mul) , that way you avoid using Sqrt again for every normalized call

  • @TortillaDev
    @TortillaDev 10 месяцев назад +2

    Great video

  • @zetty8977
    @zetty8977 9 месяцев назад +1

    The only video to appear on the subject that actually looks at the real problem, and everything you showed us in this video is exactly what I came to as a conclusion in my own testing over the past 2 years back and forth.
    Everyone else, just says use Rigidbodies or the built-in char controller, as you clearly showed as well.
    I have a slight different approach to mine, but the resulting vectors and movment is exacly the same, besides some trigonometry approaches to corner collisions.
    Another slight issue I have found with this, using raycasts, is that it more often than not sets itself inside the geometry of the world, thus the raycast does not report any hits for that collider. But I guess that the skin width solves that problem fairly okay-ish.

  • @CamrunThomas
    @CamrunThomas 9 месяцев назад +2

    Very good i like this alot

  • @egodreas
    @egodreas 8 месяцев назад +2

    I totally agree that simply employing a built-in character controller by default is not to be encouraged. That being said, now that everyone is transitioning to Godot, we should all just use the _move_and_slide_ method on the _CharacterBody_ node...

  • @willlogs
    @willlogs 9 месяцев назад +1

    Good video. Keep it up brother.

  • @buu_mm6784
    @buu_mm6784 10 месяцев назад +1

    very nice

  • @tdif3197
    @tdif3197 7 месяцев назад

    This is a great video, but i gotta say the way you formatted your spherecast conditional lines is pretty insane haha

  • @electroncat
    @electroncat 10 месяцев назад +2

    194 Subs? How, this has great video quality.

  • @322ss
    @322ss 9 месяцев назад

    Thanks! Editing must have taken a good while - neat visualizations.

  • @yaafl817
    @yaafl817 5 месяцев назад

    I remember searching for this when first studying game dev years ago, it was incredibly infuriating the amount of trash replies you'd find. Thanks for this, I wish this video was around when I first started

  • @Splatball
    @Splatball 10 месяцев назад +3

    Well well well if it isn't the exact video I was attempting to find two months ago. I'm pretty sure normalizing the redirected vector and multplying by the magnitude is the piece I was missing and looking for someone to tell me.
    Nice job on this video, it's high quality.

    • @poke_gamedev
      @poke_gamedev  10 месяцев назад +1

      Yes, there was shockingly little info about it online! When I found Fauerby's paper I knew I had to make a video.

    • @Splatball
      @Splatball 10 месяцев назад +1

      @@poke_gamedev Something you might want to consider in future content is that parameters like "gravityPass" both presuppose that the game will have gravity and don't adequately explain what the effect of that parameter is. It requires the reader to fully read the method body before being able to use the method which is not always what you want from a premade solution. Something like "shouldSlideOnSlopes" might be easier to use.

    • @poke_gamedev
      @poke_gamedev  10 месяцев назад +1

      I agree it could be more descriptive, however the way I wrote the function was as a private method to be called inside a larger character controller class. So in my case, someone using the character controller class wouldn't have any reason (beyond curiosity) to know the exact implementation for collision, as this method wouldn't even be exposed to them.

    • @Zicrus
      @Zicrus 10 месяцев назад +4

      NO, please don't do that part! It doesn't make any sense to normalize and rescale it, and just leads to the problem at 8:50. That part in the video is just wrong, so please don't copy it. In real life it does lose magnitude, so it is not a problem.

  • @DerAua
    @DerAua 10 месяцев назад +1

    Subbed. And: thank you!

  • @theashbot4097
    @theashbot4097 10 месяцев назад +4

    I was making a custom physics engine for unity. I gave up on it because the collisions and the slopes just did not work. I did not delete the code just in case I needed part of it because I added a lot to it. I saw this video and I was like "Hmm this looks interesting." so I watched it then I added the code to my project, and it did not work. the reason why is because I had the old code and this new code running at the same time. but I got it to work after about 30 min of trying. THANK YOU! for the video!

    • @clonkex
      @clonkex 10 месяцев назад

      "did not delete the code" if you're not using version control, you should be. Seriously, it's worth the pain of learning (and actually with GitHub Desktop it's not even much pain)

  • @ccl1195
    @ccl1195 6 месяцев назад +1

    I appreciate your approach and also your general calling out of the people so quick to act as if they know what they're talking about, all across Unity. For as many people as you mention, there are plenty of little "script-bros" who will yell "lol don't use rigidbody at all!" when you ask for help with your dynamic rigidbody player controller. When you ask them why, you usually hear something like "lol I don't even use the physics system much."
    Anyway, I was wondering if you have any helpful information about crushing that horrible, classic "Unity jitter" when using a first person dynamic rigidbody controller. I've come a long way with mine, but it's by no means perfect. "lol just interpolate the rigidbody bro" is not something that "just works." I've done a few different things along the way, but I'd like to know if you have helpful insights around this, or would like to make a video on it if you do.
    Thanks.

  • @billymays8864
    @billymays8864 10 месяцев назад +2

    how does this have barely attention bro, this vid is extremely useful

    • @KaitouKaiju
      @KaitouKaiju 9 месяцев назад

      It's not exactly a light watch

  • @auraxarr
    @auraxarr 5 месяцев назад

    Incredible video, mister Poke, thanks a lot for helping me with dealing with the wall Im bashing against last half a year :) A thing that looks unclear to me - at 07:48 you showed your test sphere moving down at any slope but how is that possible by that moment without gravity checks applied yet? In my backpedalling case my capsule just floats in the air which is fine to my opinion because I (as well as you in the video) only apply XZ movement :) thanks again!

  • @Not8bou3
    @Not8bou3 10 месяцев назад +4

    I just started working on my physics engine, thank you for this great explanation!

    • @poke_gamedev
      @poke_gamedev  10 месяцев назад +3

      Glad it was helpful!

    • @Zicrus
      @Zicrus 10 месяцев назад +2

      A small thing to keep in mind if you want to use this for a more general physics engine, is that the thing at 4:04 where they rescaled the vector is not physically accurate. You should just leave it as is with the shorter length. Then you also don't need to do what they did at 8:50, which they only did to compensate for the rescaling earlier.
      Those things in the video really only apply to character physics specifically, since it handles walking up or down slopes inaccurately, which feels better in some situations.

    • @Not8bou3
      @Not8bou3 10 месяцев назад

      @@Zicrus
      yeah thanks, This will only be helpful for CharacterBody and KinematicBody structures. I should make a move and slide function for them to make it easier for game devs. But for other physical structures like RigidBody I’m using more accurate approaches for collision responses.

  • @saniel2748
    @saniel2748 8 месяцев назад

    That's a good explanation. Though when I tried to implement this a year ago I eventually gave up and replaced my own solution with Kinematic Controller asset which became free, convenietly
    It really gets just so much more darn complicated when you start working with stairs, slopes and edge cases. Maintaining "skin width" is probably the most annoying part as PhysX won't correctly do CapsuleCast if you already touch the wall, so you have to maintain little distance

  • @matt64bit
    @matt64bit 8 месяцев назад

    Thanks for explaining the basics, I tried tackling this problem on my own but got stuck at the response, the character either stopped too far from the wall leaving a visible gap or for some reason completely passed through it, thanks for the video

  • @CreateGamez-tr4el
    @CreateGamez-tr4el 9 месяцев назад

    Exactly the Kinematic Character Controller, the one i'm using in my game, it's too complicated, but im trying my best to understand it

  • @MattSimon1
    @MattSimon1 Месяц назад

    The presentation is awesome. I wish I was just a bit smarter and understood this. Maybe one day.

  • @fruitfunfitness3584
    @fruitfunfitness3584 9 месяцев назад +8

    Instead of scaling the projected vector to be the same magnitude as the leftover velocity, and then scaling it again based on the angle to the perpendicular, can we not just use the projected vector as is? Will the projected vector naturally contain the desired perpendicular component if we wish to slow down our character? I've not implemented this myself yet, so it's a genuine question. Thanks.

    • @DrazkurHW
      @DrazkurHW 8 месяцев назад

      this was my thought. I haven't done the math but i believe it would give the same result and he's just taking an extra step for no reason. Although you could make the case that once you have the vector normalized you can tweak the on-wall velocity to your liking

  • @SinstixMain
    @SinstixMain 3 месяца назад +1

    I'm quite late to this but there is an issue with your implementation, in the sphere cast params, you should put the original velocity as the direction not the normalized version of it, this is to ensure that the cast covers the full distance you'll cover in that same frame, this is needed when moving at higher velocities so you don't tunnel into walls.
    Other than that, this video is amazing, I'm currently working on my collision handler for my character controller and this helped tremendously, can't thank you enough ♥

  • @K9Megahertz
    @K9Megahertz 4 месяца назад

    I think Kasper's stuff was inspired by Paul Nettle's stuff (actually, it was, just checked the references in Kasper's doc). I remember this stuff back then, did an implementation of it myself. I seem to recall one of the problems with Paul Nettle's implementation (and perhaps Kasper's original implementation) was that clipping the side of a ramp at a very shallow angle would clip through/get stuck. Imagine you wanted to go straight up the ramp was off to one side too far and just missed it. It's been 20+ years, so things may be a little fuzzy.
    I never followed through with an implementation of the improved version.
    I'll probably dig back into this topic again in the near future.

  • @Idalb0e
    @Idalb0e 10 месяцев назад +1

    Sweet

  • @AlexBlackfrost
    @AlexBlackfrost 10 месяцев назад +1

    Nice video, I'd love to see more about creating a custom cc. Are you developing a custom cc for your game?

    • @poke_gamedev
      @poke_gamedev  10 месяцев назад +4

      I am using it for a game, but it was honestly more of an exercise in finally figuring out the "correct" way to do it (and proving the "jUsT uSe DyNaMiC rIgIdBoDy" idiots wrong lol)

  • @the-guy-beyond-the-socket
    @the-guy-beyond-the-socket 10 месяцев назад +1

    Critically underrated

  • @lore3212
    @lore3212 5 месяцев назад

    AWESOME!!!
    It would be really great if you would upload a sample project so that I (or others) can analyze the code and understand it better
    Tomorrow i will try to implements this in my characterController! Thank you

  • @BarcelonaMove
    @BarcelonaMove 26 дней назад

    This shit is real, keep it coming!

  • @xEweman
    @xEweman 9 месяцев назад +1

    Awesome video man, mind telling me (or someone who knows) what do you use to create the animated slides and graphics?? Thanks!

    • @poke_gamedev
      @poke_gamedev  9 месяцев назад

      I used Motion Canvas!
      motioncanvas.io/

  • @MinibossMakaque
    @MinibossMakaque 9 месяцев назад +1

    Oh my god, why couldnt this video have existed years ago? As someone who tends to become obsessed with doing things the "correct" way, every time I've gone to make a game I get a bit of the initial setup done, then get fixated on the character controller for weeks, unhappy with most of what I see online.

    • @poke_gamedev
      @poke_gamedev  9 месяцев назад +2

      Yeah I've gotten stuck in the character controller rabbit hole like 5 times now lol

  • @lucasmontec
    @lucasmontec 9 месяцев назад +1

    If you just keep the projection of the velocity on the plane, without normalizing and scaling, you'll have a velocity that automatically increases with the angle of the plane to the velocity...

  • @Btmodz
    @Btmodz 9 месяцев назад +1

    good video

  • @Barldon
    @Barldon 9 месяцев назад +4

    The 'just use a dynamic rigid body' thing gets on my nerves too. Outside of all the reasons you wouldn't want to do that, number one is that applying forces directly through the physics system in order to code a character movement system is just so wrong and no matter which way you do it is going to end up being unintuitive in one way or another.
    I find the built in character controller to be 'fine' for my use cases, but a custom kinematic controller is undoubtedly the best and most flexible way to go about it (After all, I assume the built in controller is very similar to a kinematic controller behind the scenes). As far as I'm aware, that would be how it is done in a larger studio, and how it has been done in general for decades.

    • @poke_gamedev
      @poke_gamedev  9 месяцев назад +2

      Yeah, relying on the physics system with forces, friction, dampening, etc, for core mechanics like character movement has always given me "trying to drive a car by pushing it from behind" vibes. Not at all intuitive and certainly less predictable/reliable.

    • @FakeGuthix01
      @FakeGuthix01 9 месяцев назад

      How is using a rigid body and moving it through forces unintuitive? It's literally how things move in real life. Now there are a few "cheats" we need to use to make the physics respond the way players expect them to *feel* because Unity's physics engine is limited in fidelity, namely disabling gravity when grounded (basically assuming the normal force of the ground perfectly
      counter gravity ) and disabling friction when the player is giving movement input (assuming that kinetic friction is so low it might as well be 0). But otherwise I have found the rigidbody system to be fine for implementing Quake style movement that is used in countless first person games.
      Not trying to argue. I'm genuinely curious as to your reasons.

    • @Barldon
      @Barldon 9 месяцев назад +1

      @@FakeGuthix01 Nah I get it dw, it's all opinion too. To me it's unintuitive because it's not precise, I'm just giving it a force rather than actually controlling it's velocity precisely. When I'm designing something that needs to be as precise as a character controller, I want to work with the exact values rather than just applying forces and trying to feel out what's right. From a fundamental level, controlled movement is also not what physics rigidbody's are designed for (Hence why they provide the built in character controller to begin with), which causes additional issues. When you have to give your character spring-based floating to work around the issues of rigidbody's, you're fighting against the system that's not designed to do what you're asking it to do. And hey, if it works for you or if in your specific situation that's what you want and works better than other options then more power to you, everything unity offers is a tool you can choose how to use. I just think it's not great general advice to give to people.

    • @poke_gamedev
      @poke_gamedev  9 месяцев назад +1

      If you want your character to move at 5m/s, you could apply a force of ~5, figure out which ForceMode is correct, then realize you never actually reach top speed due to friction, then you want to change how fast you accelerate without changing the top speed, then you realize that instantaneous movement is basically impossible without completely mangling the physics material and rigidbody properties, etc, etc. And then at the end you still might not be moving at exactly 5m/s...
      Or you could go kinematic and just have a 'moveSpeed' variable with a value of 5 and it just works and you don't have to screw around endlessly with the physics system. You even mentioned workarounds in your question that could be avoided by using kinematic instead. Add in things like jumping, wall sliding, ledge grabbing, etc, and you eventually have a tangled mess of those physics system workarounds that could be accomplished easier without using the physics system at all.

  • @Splarkszter
    @Splarkszter 8 месяцев назад +1

    Ypur work is incredibly good!, thakn you so much for leaving this piece of education for free!!!
    Sadly unity became a greedy mess. R.I.P.

  • @timallanwheeler
    @timallanwheeler 9 месяцев назад +1

    Nice video! What do you use for your animations?

    • @poke_gamedev
      @poke_gamedev  9 месяцев назад +1

      Thanks! I used Motion Canvas
      motioncanvas.io/

  • @Diablokiller999
    @Diablokiller999 7 месяцев назад

    How would you implement this together with stairs?
    Thinking about sweeping the collider up a defined step height and forward 1 + 1/2 the radius of the collider on collision with a wall,, to check if it's a stair and walkable.
    Didn't try it out yet, but sounds reasonable to me.
    Any other ideas?

  • @pinuss
    @pinuss 5 месяцев назад +1

    Something is off. I followed the tutorial thoroughly and tried implementing the algorithm for a capsule shaped character. Collisions were fine on the surface, but when I had the character collide with tent shaped geometry (two stretched boxes tilting toward each other, and oriented so that the further inside you go, the lower the ceiling is), it started clipping through the tent, unless you head into the tent straight on. any horizontal movement is going to cause clipping. I figures it is with the skinWidth doing some goofy stuff like pushing the player away from the colliding object when the object is inside the skinWidth. can anyone help?
    Edit: Another thing that may proves this has something to do with skinWidth is when I set the skinWidth to something like 0.45f, then move at an angle that is almost paralel to the surface, instead of the moving the character a skinWidth distance away from the wall, it just slowly inches towards the wall, until it the distance between player and wall reaches the radius of the capsule cast (aka capsuleRadius - skinWidth), as if "snapDist = hit.distance - skinWidth" have very little effect. When looking and moving at the wall at an angle almost perpendicular, this behavior doesn't happen}
    Edit 2: Found out the hard way that just doing "snapDist = hit.distance - skinWidth" isn't correct at all. the closer to getting perpendicular to the surface's normal, the more you'd have to subtract from hit.distance. so here's the proposed solution:
    float bigHypotenuse = capsuleRadius / Mathf.Sin((90 - Vector3.Angle(hit.normal, -vel.normalized)) * Mathf.Deg2Rad);
    float smallHypotenuse = (capsuleRadius - skinWidth) / Mathf.Sin((90 - Vector3.Angle(hit.normal, -vel.normalized)) * Mathf.Deg2Rad);
    Vector3 snapToSurface = vel.normalized * (hit.distance - (bigHypotenuse - smallHypotenuse));
    where as bigHypotenuse is the length between the big capsule center (aka the capsule without any skinWidth) at the position where it is contacting the hit point, and the point where the velocity would hit if raycasted (very much oversimplified, my wording is very off). smallHypotenuse is the same but for the capsule with its radius - skinWidth.
    for some reason this would create jittering if skinWidth is too high, so if the whole purpose of skinWidth is to stop floating point inaccuracy, then setting it real small (like 0.0001f) would work. still could'nt figure out why it is jittery though.
    this solution still isn't perfect however, because the collider can still clip through the walls. I suspect this is because my implementation only work on the XZ plane, since I tried sketching it at a top down view
    private Vector3 CollideAndSlide(Vector3 pos, Vector3 vel, int depth, bool gravityPass)
    {
    if (depth > maxBounces)
    {
    return Vector3.zero;
    }
    if (vel.magnitude < minMoveDistance)
    {
    return Vector3.zero;
    }
    Vector3 botCenter = pos + transform.up * capsuleRadius;
    Vector3 topCenter = pos + transform.up * (capsuleHeight - capsuleRadius);
    float dist = vel.magnitude + skinWidth;
    RaycastHit hit;
    if (Physics.CapsuleCast(botCenter, topCenter, capsuleRadius - skinWidth, vel.normalized, out hit, dist, collidingLayers))
    {
    float snapDist = hit.distance - skinWidth;
    Vector3 snapToSurface = vel.normalized * snapDist;
    Vector3 leftover = vel - snapToSurface;
    leftover = Vector3.ProjectOnPlane(leftover, hit.normal);
    return snapToSurface + CollideAndSlide(pos + snapToSurface, leftover, depth + 1, gravityPass);
    }
    return vel;
    }

  • @tonylazuto9001
    @tonylazuto9001 9 месяцев назад +1

    This is good, and I tend to use similar techniques when writing CCs, but the big issue I always face is the collision detection, i.e. the spherecast. Specifically, if any geometry is inside the origin sphere at all, it will return messed up sphere hits for that collision. So if the character ends up clipping into anything, it won't be able to push itself back out correctly. I really need a way to get info about surfaces inside a given sphere. You can use an overlap sphere and then closestpoint on colliders, but it doesn't work with concave mesh colliders.

    • @poke_gamedev
      @poke_gamedev  9 месяцев назад

      I've only been able to find one edge-case so far where the collider can clip into a surface. But yeah, it is currently missing the ability to push out of overlapping objects.

    • @KelseyHigham
      @KelseyHigham 9 месяцев назад

      i test every position for collision before moving the player there. if the player starts a frame colliding, then they spawned inside a collider, and i allow them to fall through the floor until they start a frame *not* colliding.

    • @GistixSTHR
      @GistixSTHR 7 месяцев назад

      ​@@poke_gamedev You can use Physics.ComputePenetration to that end

  • @kiekiestudios
    @kiekiestudios 9 месяцев назад

    you dont need to acount for the direction your facing to slow your speed on a wall you could just leave the progected vector alone and not scale by the distance of the removed vector to get a very similar result

  • @alexandregingras6874
    @alexandregingras6874 9 месяцев назад +1

    I love you.

  • @imaginationscene
    @imaginationscene 9 месяцев назад

    this was in my suggested

  • @appleseedgames6934
    @appleseedgames6934 2 месяца назад

    Good work, you've just redesigned a rigidbody from the ground up...

  • @ANJ_gaming
    @ANJ_gaming 9 месяцев назад

    This video seems really useful and well done.. I just wish my coder brain was developed enough to understand it, lol. Bookmarked though!

  • @ianh3385
    @ianh3385 10 месяцев назад +3

    Any tips you’d give on finding papers like these?

    • @poke_gamedev
      @poke_gamedev  10 месяцев назад +1

      I stumbled upon these particular papers completely by accident with some googling for 'collide and slide algorithm' and such, but I'd recommend Google Scholar if you want to look specifically for academic papers on a topic!

  • @ligazetom
    @ligazetom 8 дней назад

    Regarding the preserving of speed independently of collision normal, is the dot product needed? Shouldn't the projection on the plane already take care of that.

  • @TwashMan
    @TwashMan 8 месяцев назад

    Been trying to implement this but i can't get it to work, the collision seems to be working but it's not sliding correctly. I tried to look over and make sure the code i wrote but couldn't find any differences. I'll try again tomorrow.

  • @brichearnaud5314
    @brichearnaud5314 3 дня назад

    I do have a genuine question: Why are you using _bounds.extents.x in your sphere/capsule cast for the radius ?
    Extents are world oriented in Unity, meaning that depending on the orientation of your collider (either dynamically or on start), you would get different values ?
    Amazing content nonetheless, thank you very much for this video!