That is really great help indeed! My kids have put a beach ball in there first level and it's a rigid body. It's great fun to interact with the ball but after a short time the ball is lost because it's pushed into the floor. We are gonna try the piece of code you provide so kindly.
Damn dude, its when i look at videos like this that i realize i know too little about Godot, i din't even know you could check for what you are colliding, neither getting theyr information, thx for the video man, you help thousands of people and that's sick, you're really talented and i really respect people like you, thx again :)
Fiddling with the properties and PhysicsMaterialOverride of my RigidBodies resulted in unexpected behaviour and after some questioning of my very understanding of physics, while temporary descending into madness, I can now safely say: Things make sense again. Thank you!
I found an issue here, when you try to stand on top of the rigidbodies, the kinematicbody is going to shake like hell. And if the rigidbody is on the kinematicbody, you cannot jump...
The reason that you cannot jump is that you are not standing on the ground you are standing on the rigid body which will not trigger the is_on_floor function
For those wanting to know how to do this in 3D, the code for the for loop looks like this, for index in get_slide_count(): var collision : KinematicCollision = get_slide_collision(index) var obj = collision.get_collider() if obj.is_in_group("bodies"): print(obj) collision.collider.apply_central_impulse(Vector3(inertia,0,0)) Only I don't have the vector3 correct for applying the impulse.
okay I figured it out, for index in get_slide_count(): var collision : KinematicCollision = get_slide_collision(index) var obj = collision.get_collider() if obj.is_in_group("bodies"): collision.collider.apply_central_impulse(Vector3(inertia * -collision.normal.x,inertia * -collision.normal.y,inertia * -collision.normal.z))
Or just collision.collider.apply_central_impulse(-collision.normal * inertia) If you need some help on working with vectors, there's a really good doc here: docs.godotengine.org/en/latest/tutorials/math/vector_math.html
Where is the "index" coming from? I get an error that index isn't declared in the current scope. I'm trying to get an object "fly off" when the car hits it. Thought that making the object a rigidbody would already make it interactable. There are so few tutorials about this (for Godot in 3D) or only partial information, it really gets annoying not being able to do things that should be straightforward.
This only seems to work if the RigidBody is at rest or low velocity. In my case I have a bucket that's a KinematicBody2D and you have to catch eggs that are falling downwards, which are RigidBody2D. Setting infinite inertia to false only made things worse, the smallest impact catapults the eggs out to the moon. I tested what happens if the eggs are still and the bucket hits them, and then it works, but not if they fall into the bucket or they have high velocity. I also tried using much simpler collision shapes, just in case the complex shapes are the cause but it still happens with the simplest rectangular shapes. Not to mention the eggs also move the bucket around, which is not supposed to be happening. I want the eggs to have absolutely zero impact on the bucket, but I want the bucket to be able to carry the eggs around, and that only seems to work with infinite inertia, but then the eggs get stuck in the bucket's hitbox. Is there any solution at all to this? I mean this all seems so trivial, there must be something we can do? Edit: I tried continuous detection too, doesn't work.
Any idea why (with infinite inertial = false) that my player CAN push things around but only for a short duration thenevetyhing becomes immovable. Its like it starts with some inertia that dispates. Cant figure out where it comes from.
EDIT: NVM FIXED the rigid body does not move but I can go on top of it. my script extends KinematicBody2D export (int) var speed = 200 export (int) var jump_speed = -600 export (int) var gravity = 1000 export (float, 0, 1.0) var friction = 0.1 export (float, 0, 1.0) var acceleration = 0.25 export (int, 0, 200) var push = 100 var velocity = Vector2.ZERO func get_input(): var dir = 0 if Input.is_action_pressed("ui_right"): dir += 1 if Input.is_action_pressed("ui_left"): dir -= 1 if dir != 0: velocity.x = lerp(velocity.x, dir * speed, acceleration) else: velocity.x = lerp(velocity.x, 0, friction) func _physics_process(delta): get_input() velocity.y += gravity * delta velocity = move_and_slide(velocity, Vector2.UP, false, 4, PI/4, false) if Input.is_action_just_pressed("jump"): if is_on_floor(): velocity.y = jump_speed for index in get_slide_count(): var collision = get_slide_collision(index) if collision.collider.is_in_group("bodies"): collision.collider.apply_central_impulse(-collision.normal * push)
Thanks for this fantastic tip, its a (literal) game changer. I used it on my top down game and it works wonders, but i discovered it doesnt "spin" the object as it normally should, so after some (a ton) trial and error, i came up with this bit of code to solve that: (Just add it after the "apply_central_impulse" bit) var spin if collision.normal.y < 0 and abs(collision.normal.y) > abs(collision.normal.x): spin = -(collision.collider.get_global_position().x - get_global_position().x) elif collision.normal.y > 0 and abs(collision.normal.y) > abs(collision.normal.x): spin = collision.collider.get_global_position().x - get_global_position().x elif collision.normal.x < 0 and abs(collision.normal.x) > abs(collision.normal.y): spin = -(get_global_position().y - collision.collider.get_global_position().y) elif collision.normal.x > 0 and abs(collision.normal.x) > abs(collision.normal.y): spin = get_global_position().y - collision.collider.get_global_position().y collision.collider.apply_torque_impulse(spin) EDIT: Nevermind, this "works" but breaks as soon at the body completes a half rotation, i'll leave it anyways in case someone wants to continue or i come up with a solution
the code made a mistake here. central impulse is not effective for this problem. use apply_impulse() instead. you can take the exact collision point for the rigid body and kinematic body and use it like this _apply_impulse(collision_location,innertia * collision_normal)
Hey man! Love your work! I wanted to ask, can you make a tutorial on how to implement dialogue in godot? How to branch out choices, and how to call a function within the dialogue, you know, stuff like that?
Great video. Works perfectly. One question I have: how can you get this working for point2d nodes? I'm able to set up point2d nodes and they interact with rigid bodies as expected. By when a kinematic rigid body interacts with them they don't react.
oh my friggin jeeeeeez...I've spent the last few days trying to find out why my space ship will move my darn asteroids around like they're nothing, but everything I tried I couldn't figure out why I wasn't detecting a collision the other way around...all I needed to do was add a ", false" aaarrrgghh!! I'm glad I finally found this, but holy crap that was staring me in the face this WHOLE time too hahaha, I was ike "nahhh, I'll leave the infinite inertia boolean set to false, I don't think THAT'S the problem, it's not even showing a collision!" oh my f'n g....wow...ok...steam let loose....rant over...I'm very thankful I found this video, my google-fu failed me immensely on this one.
oh wow, now looking through the docs I see why I missed it. I'm using move_and_collide, which in the docs doesn't give any info about infinite inertia. I didn't look at the arguments for move_and_slide being I wasn't using that....and THAT'S where infinite inertia is explained in the docs. a "see 'infinite inertia in move_and_slide" would have been nice to see so I didn't miss that...grr
great tutorial! i have a question tho, when lets say i hit a ball(rigid2d) with my kinematic and the ball bounces and hit me back,my kinematic moves a bit,why is that happen? thank you.
Compared to other engines, this still seem glitchy in my opinion. I love godot, free and easy to use, but its physics gives me headaches sometimes. Better off writing a physics simulation in 2D. I also noticed that when I push one rigidbody and then 2 rigidbodies, their combined mass remains the same as if I moved just one rigidbidy.
its because the "solution " is not very effective. what he should have done is apply some more code to calculate realistic innertia instead of having a static one. and make sure the kinematic body can also retrive innertia from rigid body objects so it does not stand still when something hits it at a high velocity. also the impulse is applied at the center which is flat out wrong. it should be applied at the collision point not the center of the rigid body object.
@@ali32bit42 Hi Ali, seems like you know what your taslking about, I see the same glitchy issues and are looking for an example done the right way. I'm not a programmer, so don't know how to program it, but I need it for a game i'm thinking of. Would you be able to help?
These videos have been a great help as I try to learn Godot! I have a question that isn't related to the video however. I'm working on creating a 2D game, but for stylistic purposes, putting it in a 3D environment. I want my character's arm to point at the cursor, but the easy way of doing that in 2D doesn't work in 3D. I've tried to figure it out myself, and it seems the answer has to do with raycasting, and folks have some code snippets I could grab, but I just can't wrap my head around it. Any chance of doing a video on finding the cursor location in a 3D space and getting a 3d object to look at it? Keep up the good work.
@KidsCanCode For some reason after some time where I have been pushing around my cube it almost seems "fall into place" so that I can no longer move it around. I'm working in 3D and it is usually when I get the cube right up against a corner or if I jump on it. Any ideas why that would happen?
Hello, nice tutorial. Would you mind getting even more deep on this topic, like for example how to hold a rigid body, making it follow the kinematic body, and then how to hit it, applaying force, like for example a soccer player getting the ball, dribling with it without losing it and then being able to kick the ball in a desired direction?
i like the tip about infinite inertia but the solution is a bit too basic for more advanced games designs. for more complex movement styles where max velocity can vairy alot between actions it might not work or be really inacccurate, fast moving characters wont have enough force and slow moving ones might have too much. what i would do it keep track of the velocity which is possible by comparing the last locaton with the current location each frame using delta time as the T (you can use the velocity for move_and_slide function too but this might help if you calculate velocity in a strange manner). then use the velocity to calculate a more accurate innertia for the kinematic body which will also use a "mass" number to be more realistic. after that i would not use central impulse to add force to the rigid body and instead apply the impulse at the collision point which is more accurate and will ensure colliding with a corner for example rotates the boxes more accurately . i would also try to take some physics data from the rigid body objects themselves to ensure my kinematic body can also react to colliding with other objects. as sometimes godot does not apply rigid body collisions in an accurate manner which is partially causing the whole collision problem since rigid body objects cant "fight back" the kinematic body. overall the best solution for this problem is a bit more complex but its what you need to do in order to have the most perfect system.
Hi Ali, seems like you know what your taslking about, I see the same issues and are looking for an example done the right way - No glitching. I'm not a programmer, so don't know how to program it, but I need it for a game i'm thinking of. Would you be able to help?
@@christiansktt6903 hi . i recommand doing some research on the real life physics of inertia and the formulas involved. look for a formula that can convert velocity and mass to inertia for impact. you can use the get_last_slide_collision() function to get data for which objects you have collided with. then you must get the velocity and point of impact for each object that you have collided with and then after that you must get the nodes that you have collided with and store them in an array then use a "for each" loop to quickly check for rigid body objects in the array . then for each rigid body in the collision array you must calculate the correct innertia using the velocity and mass of your kinematic body then send a signal to the rigid body object and trigger their _apply_impulse() function with the force of inertia and location of the impact for the function input. sorry if its confusing . the process is a bit complicated
That's a great comment here. Do you have any suggestions where I can learn about solutions to the rigid bodies "fighting back" the kinematic bodies? I see this issue a lot, especially with solid bodies, which rotate. Thanks
@@dmr12jmy i have been researching this myself. the subject is a little heavy with math but if you look up something like "rigid body collision response" you will find a bunch of articles that show how to do it . there was also newtons law of restitution which if you understand well you can implement yourself. i dont have the link but a document from chris hecker has more info about it
Is there some way to detect collision of 2 static bodies? By some function maybe? I try to find something about this for 2 days along, but can't find anything usable.
Static bodies by definition don't move, so they can't collide. They don't detect collisions because the purpose of them is to be lightweight, non-moving objects with no functionality other than to provide a body *other* objects can collide with.
@@Kidscancode sure, in stage of gameplay it's normal, but i think may it be some way to play around this and detect somehow collision of 2 static body or they collision shapes manualy by some function? I don't want they can move, only detects if they intersect each other. Basicaly i trying to make some level generation by placing modelled rooms, but i stucked at moment when they placed in other rooms.
@@Kidscancode sure, but i found solution: there are class "PhysicsDirectSpaceState" with methods collide_shape and intersect_shape which accepts "PhysicsShapeQueryParameters" which accepts shape from CollisionShape (not sure, but only convex). Anyway right now i can't use it, output is different from i expected, so i need to figure out what exact goes wrong. One problem is that it detect collision with own static body, but it's not big problem, second problem is wrong collision detection. I make a test scene where i try to intersect cube and prism, suddenly Query result show collision with cube where i dont expect it, but if move prism away - detection stops (only own Static body left).
@@Kidscancode i fix a problem with wrong position - i just use get_world at mesh (because i see it earlier somewhere), but needed use just get_world as get_tree - alone
I changed apply_central_impulse to apply_impulse so my rigidbodies would spin if you hit them on an edge: collision.collider.apply_impulse(collision.position, (-collision.normal * inertia)) ...but I get weird behaviour where SOMETIMES the impulse is applied correctly, but sometimes the impulse is in the opposite direction. I.e. the rigidbody moves back towards the kinematic body that hit it. Edit: it turns out 'sometimes' is whenever a contact is reported as a little red square when 'visible collision shapes' is turned on under the debug menu.
So... If I'm not jumping and the ball falls on my head, the collision.normal.y returns 1, but if I AM jumping, it returns less than 1... That's why just multiplying it by the inertia, it will return a lower value when there's player movement at the time of the collision.
It should work the same. Maybe you're applying too much downward force, so the rigid body sees the kinematic as really "heavy". Maybe there's a problem with your collision shapes, or the thickness of your floor. You'll need to experiment on your particular setup.
@@Kidscancode I was just checking all the things you mentioned and I had another vector for falling and i edited it too, so now it works. Thank you so much! :-)
Hey, my script isn't working I cant push the objects although the script is the same! pls help!
4 года назад
I guess you forgot the add the rigidbody to the a group. If you select the rigidbody than you will find the groups menu in the Node tab. I hope this was your problem.
Hello, first off this and all the other videos have helped immensely. I am working on a top down game and have put 'false' for the infinite inertia in the move and slide method. My player interaction with the rigid bodies works great except for when I push from the top. When my Player collides with the rigid body from the north side moving down it seems like all these other vectors are being applied. I have gone into project settings and turned gravity off everywhere there is an option too. I would like to understand why this is happening. If anyone can help I would greatly appreciate it.
Okay so I went into the script for my RigidBody and created the integrate_forces method. From there I just clamped the linear_velocity. After that I just set the mode to Character to keep it simple and my problem seems to be solved.
it's just a function he made containing the usual "if Input.get_action_pressed("game_left") direction = Vector2.LEFT" stuff. He did that to clean up code from user's controls and separate it from physics processes
The following link doesn't work: "It’s assumed that you have at least some general programming experience. If you’re completely new to programming, click HERE for tips on how to get started."