Open ywmaa opened 2 years ago
I'd like to have a try at this one - I've pulled in and made a branch :)
I can't promise any talent, skills or a good solution, but I guess I can try, if I get anywhere close then offer it as a pull request?
My thoughts so far based on how I've done similar features in Unity:
Random thoughts:
I can't promise any talent, skills or a good solution, but I guess I can try, if I get anywhere close then offer it as a pull request?
Yes, any help is good, thanks in advance.
or manually tagged by the developer. I like the idea of it being automatic, then opting objects out as needed, as it would allow terrain to naturally be traversed..
Focus on Automatic system.
Is there any animation earmarked for this? I know mixamo has a couple, but I fear Adobe, so wanted to check! :)
I am already using a mixamo character and animations, so mixamo animations are now the most compatible. Plus the character and the animations are only demos.
Any system should consider that they can be switched.
I think it would be more fitting to make the player's collider move, and the animation follow it - i.e. not have the root motion
The philosophy of the Advanced-Movement-System-Godot Is to never use Root Motion, always move the capsule and try as much as possible to sync the animation to it with stuff like
Motion Matching.
Distance Matching.
Motion Warping.
These techniques are used in unreal engine, and they are what make animation looks really good in unreal.
Other tips :
The Advanced-Movement-System-Godot is inspired by
Advanced-Locomotion-System in Unreal Engine : https://youtu.be/ru1--3wP-F8?si=wocLp2z3MI4QuknN
You can see the dynamic mantling system in 3:50
Thank you so much for the outlining - it's incredibly helpful to catch the underlying philosophy and approach to the code before guessing and making a meal of it! :) I'll focus on the detection initially, so that the character movement has a concept of obstacles, height comparison etc. :)
I would like to point out, my stair solving solution somehow worked for high obstacles BUG OR FEATURE ? so I made a maximum climbing height, and I think I set it to 0.2 Meters or something.
if I would go through the climbing approach, I would do the detection, then use the MotionWarping Node (Available in the template too). the MotionWarping Node can be used to change the player position smoothly (Check Out the test in "fire" input, where the chaarcter starts kicking, in the code, you will see the use of motion warping), and while changing the player position smoothly to match the animation time, it should give the full feel of the character climbing.
The MotionWarping Node waits for the animtion to execute the function, in the kicking case I named the function "kick_target", this means I need to go to the kicking animation, and the exact time the kicking hits the target, and execute the function.
Anyway, if you find all of this confusing, you can focus on climbing detection only, and for me plugging these stuff is quite easy.
I would like to point out, my stair solving solution somehow worked for high obstacles BUG OR FEATURE ? so I made a maximum climbing height, and I think I set it to 0.2 Meters or something.
I'm leaning into feature territory, but not sure. 😂 I am tempted to look into the move_and_collide features in godot, at least to try and predict if it's possible for the player to climb up without clipping into things, hitting their head etc.
I'm at the stair solution in the code, and as you say, they're very similar solutions. I'm wondering whether to extend your existing work on the stairs by adding in a high ray (at head height) to assess if the obstacle is higher than stairs, but also not too high to mount?
I've annotated what I think is happening, and where I'm thinking the code could live. :)
var stair_top_collision = direct_state.intersect_ray(climb_ray_info)
#If so, the obstacle height is < stair height, so snap to top of stair?
if stair_top_collision:
if stair_top_collision.position.y - character_node.global_position.y > 0 and stair_top_collision.position.y - character_node.global_position.y < 0.15:
movement_state = Global.movement_state.grounded
is_moving_on_stair = true
character_node.position.y += stair_top_collision.position.y - character_node.global_position.y
character_node.global_position += Vector3(0, 0, 0.01).rotated(Vector3.UP,movement_direction)
else:
#Object ends above max_stair_climb_height - would this be a good place to add mantle?
await get_tree().create_timer(0.4).timeout
is_moving_on_stair = false
else:
await get_tree().create_timer(0.4).timeout
is_moving_on_stair = false
else:
#There is no obstacle
await get_tree().create_timer(0.4).timeout
is_moving_on_stair = false
I think you can just use the same script to just check if it is possible to mantle, so here :
#Object ends above max_stair_climb_height - would this be a good place to add mantle?
just add a variable can_mantle
in the whole script, and set it in this part of code to true if possible, else set it to false.
also to not rewrite the code for getting where the player should be snapped, you can save that too in another variable like
mantle_position
Then in mantle():
placeholder function that I left there, you implement the execution of mantle, so it works just like jump().
This allows us to call mantle()
if player presses Jump and it is possble to mantle, it will mantle instead of jumping.
Or while in Air it of course will favour mantling because anyway the player can't jump in Air.
Edit : typos
Thank you :) I'm looking at it now, and hopefully can make some progress - thanks for guiding me through all this, I'm hoping it's useful in the long run :)
Edit: can mantle now reliably gets called; it's a tiny bit unresponsive due to the timers etc, but calls on the white boxes :) Onto adding the mantle position, and a mantle function :)
Simple System for climbing relatively small obstacles like maximum 1 meter height climbing