I’m not rly too experienced with Godot that much, but I can try to remake Sonic physics, if I even have the time. can ya help me turn sum of this base code into something that resembles Sonic physics?
extends CharacterBody2D
@export var speed = 1200
@export var jump_speed = -1800
@export var gravity = 4000
@export_range(0.0, 1.0) var friction = 0.1
@export_range(0.0 , 1.0) var acceleration = 0.25
func _physics_process(delta):
velocity.y += gravity * delta
var dir = Input.get_axis("walk_left", "walk_right")
if dir != 0:
velocity.x = lerp(velocity.x, dir * speed, acceleration)
else:
velocity.x = lerp(velocity.x, 0.0, friction)
move_and_slide()
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_speed
if you can, plzz let me know, thx
It would be better to use move_toward (with a much higher acceleration) instead of lerp, but other than that recommendation I’m not sure you’ve explain what makes something resemble sonic physics. Is there anything you are particularly dissatisfied with? What happens in game and what do you expect to happen? How do those two questions line up?
Alright i’ll get on that right away, but mainly I was asking how I can add Sonic styled terrain collision, air speed, loop-de-loops, rolling homing attack, and spindash
Okay, here’s the new code:
extends CharacterBody2D
@export var speed = 360
@export var jump_speed = -420
@export var gravity = 960
@export var friction = 2.68
@export var acceleration = 1.68
func _physics_process(delta):
velocity.y += gravity * delta
var dir = Input.get_axis("ui_left", "ui_right")
if dir != 0:
velocity.x = move_toward(velocity.x, dir * speed, acceleration)
else:
velocity.x = move_toward(velocity.x, 0.0, friction)
move_and_slide()
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = jump_speed
What about Sonic’s slope detection? What methods do you recommend?
Tried that, and also tampered with my code:
extends CharacterBody2D
@export var speed = 360
@export var jump_speed = -420
@export var gravity = 960
@export var friction = 2.68
@export var acceleration = 1.68
@export var skid= 6.68
@export var acceleration_value=1.68
@export var is_skidding=false
func _physics_process(delta):
velocity.y += gravity * delta
var dir = Input.get_axis("ui_left", "ui_right")
if dir != 0:
velocity.x = move_toward(velocity.x, dir * speed, acceleration_value)
if (dir==1 and velocity.x < 0) or (dir==-1 and velocity.x > 0):
is_skidding=true
else:
is_skidding=false
if is_skidding:
acceleration_value = skid
else:
acceleration_value = acceleration
else:
velocity.x = move_toward(velocity.x, 0.0, friction)
move_and_slide()
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = jump_speed
Max angle is 180, snap length is 16 pixels. What I’m trying to ask is, how can I get Sonic to rotate with the slope, both the collision and the sprite?
Maybe swap out the CharacterBody2D entirely for a perfect circle rigidbody2d for the duration of the looping, using detection areas to trigger the swap?
You need to know the impulse to give to the rigidbody2d then, I have no clue how to compute that.
Honestly… IDRK if I even wanna do that… btw my collision shape is a rectangle, and plus, the rigid body 2d isn’t really that good for making platformers, and I want to keep using the character body, even thru the loops… maybe I could do that when sonic’s rolling…
Well, I’m sure my advice here won’t be the best, but sometimes a little out of the box extreme measure thinking will sharpen your sight on a viable possibility.
Another thing I sometimes hack is just not invoke move_and_slide at all during a certain state and simply make my character follow a fixed Path2D.. like rails
I decided to use a convex shape for my character body, and make sure it had the best of both worlds; no random rotation jitters on the floor, or in-between slope angles. It actually works REALLY good. Thank you for helping me think outside the box here, it really helped.
good to know it worked.
And here’s a hint for some of the trickier terrain collision: just force it on-rails. Most of the 3D games lock the character into the trajectory of a spline. Whenever you think sonic’s running direction detached from where you told him, that’s the stage turning into a train until the gravity-defying bit (loop-de-loop, upside down, twist-and-turn, wall-run) is over.
I actually might need some help coding the gravity-defying part, because I got a test circle in my level that could be part of the defying gravity part… would you recommend I use a raycast to detect the angle of the ground?
Wouldn’t an Area2D to indicate the loop start+end be simpler? (last one I’m doing
)
As long as we’re just sparring. I do not pretend to know any better, just out of the boxing.
Had to COMPLETELY rewrite the code… was doing it with Gemini (hope y’all can forgive me) and it tilted sideways and plummeted south pretty quick.
Here’s the new code:
extends CharacterBody2D
var speed = 360.0
var jump_speed = -420.0
var accel=170
var decel=270
var fastd=470
# Get the gravity from the project settings so you can sync with rigid body nodes.
var gravity = 960
var skidbool=false
func _physics_process(delta):
# Add the gravity.
velocity.y += gravity * delta
# Handle Jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_speed
# Get the input direction.
var direction = Input.get_axis("ui_left", "ui_right")
if direction !=0:
velocity.x = move_toward(velocity.x,speed*direction,accel*delta)
else:
velocity.x = move_toward(velocity.x,0,decel*delta)
move_and_slide()
if (direction<0 and velocity.x>0) or (direction>0 and velocity.x<0):
skidbool=true
else:
skidbool=false
if skidbool:
velocity.x=move_toward(velocity.x,0,fastd*delta)
What do you recommend so that the player’s collision AND sprite rotate along the ground normal?
Just let me know gng
I recommend starting with something simpler than Sonic.