|
|
|
|
Reply From: |
TerChapone |
I’m obviously super-late, but this might help out others in the future. I had a similar problem and, for what’s probably the first time in my life, I came up with my own solution!
It shares a little with avencherus’s answer, but I admit I don’t fully understand his code, so I can’t point out the differences, other than that this is almost painfully simple.
Godot version 3.1.1 stable official.
Note: this is for when you aren’t using a RigidBody(2D) or even move_and_slide()
/move_and_collide()
, though who knows, you might be able to adapt it to fit those cases.
I use a vector, velocity
, and add it to position
after checking that it won’t put the object inside another collider.
The idea is that you cast a ray the length, and in the direction, of the velocity vector. If it hits something, it means you’ll be colliding in the next frame, so instead of position += velocity
, you get_collision_point()
and set position =
that (accounting for the object’s size, since position
is in its center; this is crucial, because raycasts also usually start from the center, and if you fail to do this it won’t work properly; if you’ve moved raycast origin, take that as the center).
Note 2: I’ve only tested this for gravity so far. This means I’ve only cast 1 ray, vertically. I’ll update the answer once I’ve done more work on my character controller.
Here’s the basic code. It’s what I got so far. I avoided putting in a lot of variable definitions, as they’re obvious and I wanted to it to be uncluttered.
extends KinematicBody2D
func _physics_process(delta):
# adding gravity
velocity.y += GRAVITY
# adding input movement
# ...
# raycasting
raycast.cast_to.y = height + velocity.y * delta
if raycast.is_colliding():
position = raycast.get_collision_point() - Vector2(0, height)
velocity.y -= GRAVITY
else:
position += velocity * delta
height
is $CollisionShape2D.shape.extents.y
, set in _ready()
. My sprite (and collision shape) is a square.
velocity.y -= GRAVITY
is to stop velocity.y
from increasing unceasingly, or else it will interfere with input movement later. Outright setting it to 0 messes things up, since our raycast depends on it.
For accuracy’s sake, you’ll need more than one ray, but the underlying code should be the same.
From my tests so far, this works when I’ve jacked GRAVITY
all the way up to 18000 — normally, it’s only 50 — but fails at 19000 and onward. Do keep in mind this is gravity, so it’s acceleration, meaning it boosts velocity.y
to ridiculous values in just milliseconds, as it increases by that amount every frame.
I don’t know what breaks things at this point, but I probably won’t investigate either, because I can’t see any use-case scenarios for it; except for space sims, I guess, but those are way above my level.
Was having the same problem and the same idea as you did (allthough I use an Area2D and use translate instead of directly editing position), maybe not as cleanly coded as you did but well done!
IngushXeva | 2019-08-01 14:50