btan2 / q_move Goto Github PK
View Code? Open in Web Editor NEWQuake-like controller for Godot
License: GNU General Public License v3.0
Quake-like controller for Godot
License: GNU General Public License v3.0
GPL requires any software that uses this code to be released under a GPL compatible license. A more permissive license would be handy for game devs that would like to use your code, but not make their entire game open-source.
At the moment, the player character has infinite force and because of this, interactions with rigidbodies go horribly wrong.
In Half-Life 2, the player had a specific weight that restricted how much force it inflicted on physics objects and it allowed the player to push and stand on objects. The player would naturally slow down while pushing an object based on it's weight and when the object could not be pushed any further, the player momentum stops. This also allowed the player to stand on objects (i.e. Crates and boxes).
At the moment, the player has infinite weight and force so standing on an object would just crush the object into the floor and pushing objects don't slow the player down at all.
Please be aware that if the player moves onto steep ground that is surrounded by steep walls they are treated as falling.
This is undesirable in certain cases. Realistically, we expect to be able to place our legs on the opposing surfaces and hold ourselves steady. There are a few solutions which work with varying degrees of success e.g. creating a stable average plane from colliding walls, but the problem is that they often introduce jitters and can cause step detection to fail, which is unacceptable.
For now you may wish to use invisible walls to shield the player from moving into steep crevices as this issue is currently being worked upon.
Fall velocity and distance has been accounted for, so if the player is caught on a steep surface that is close to the ground their fall velocity will not accumulate and the controller will not erroneously punish the player for having fallen 500 feet. That being said, in the field of collision detection there are always circumstances where things don't go according to plan...
Something that is rather hidden these days is figuring out how to return every surface normal an object in 3D space is colliding with. move_and_slide
only returns normals the body slid against, so it never actually returns every normal the body has touched. When using DirectSpaceState
and shape casting, only get_rest_info
and intersect_raycast
can return collision normals and they too are only capable of returning collision normals from singular collision objects. In order to retrieve the collision normal of every colliding object, we need use intersect_shape
and loop through every collision object we hit, isolate it to an unused collision layer and then use get_rest_info
to test against the object. This ensures that only the colliding object we are interested in will be hit as opposed to the nearest collision object.
So below is a trace func which returns all of the planes a collision shape is touching, which may help solve the infinitely falling issue or perhaps any other problem you may be encountering.
Be aware that objects that are inside of other objects will also be detected if close enough to an encompassing object's surface.
It is best not to abuse this function too much as retrieving collision normals can be expensive, especially for geometry with thousands of tris.
func get_planes(start : Vector3, shape : Shape, mask : int, world : World):
var params = PhysicsShapeQueryParameters.new()
params.set_shape(shape)
params.set_collision_mask(mask)
params.exclude = [self]
params.transform.origin = start
var colliders = []
var planes = []
var results = world.direct_space_state.intersect_shape(params, MAX_INTERSECT)
if results.empty():
return planes
for r in results:
var cl = r.get("collider")
if colliders.find(cl) == -1: # don't add duplicates, slow
colliders.append(cl)
# make sure I_MASK const does not point to a collision layer occupied by other objects
params.set_collision_mask(I_MASK)
for c in colliders:
var original_layer = c.collision_layer
c.collision_layer = I_MASK
results = world.direct_space_state.get_rest_info(params)
if !results.empty():
planes.append(results.get("normal"))
c.collision_layer = original_layer # reset collision layer
return planes
# and then:
# var pos = thing.whatever.origin
# var planes = get_planes(pos, collision.shape, mask, get_world()
# for p in planes:
# if p[1] > MAX_SLOPE:
# #do something
Hey there!
Excelent project! Very smooth movement.
How hard would it be to further extend this โ to support water?
Considering that it's just air movement but with low or no gravity.
I've tried to create a static body without any layer and giving it the "WATER" group.
It's kind of working but you can't swim up or down, in the look direction.
And the player doesn't fall into body of water.
P. S. I'm rebuilding my game and this project would be great as a base!
Any plans to continue the work on this project?
IDK if this project is being actively worked on currently, but a Godot 4 update would be nice. I've had some issues myself porting this correctly.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.