Topic was automatically imported from the old Question2Answer platform.
Asked By
Dayls
Hello. In my top down 2D project when I create logs that player can shift(something like in Zelda 2D), I make Gravity Scale to 0. In order for gravity to “pull” the log to the surface, as if along the Z axis, which is not in Rigidbody2D. That is, when I set the GravityScale to 0 so that the log does not roll from top to bottom across the screen, it turns out that with this parameter, the mass and weight do not affect anything and the log is in zero gravity. Therefore, I had a question, how to make the gravity of Rigidbody2D work in the TopDown project?
Your halfway there with the zero g but you’ll need to code in thr friction of the “floor” yourself.
Friction is a force proportional to velocity and in the opposite direction, the scale depends if the log is on ice low friction or mud high friction.
EDIT: see an example implentation below:
Thank you. I will try to find a way to do this
Dayls | 2021-06-10 10:08
Sorry for second question. But could you suggest me how to make this (if you know) please. Because I just haven’t really figured out Godot yet, and how to do things like that
Dayls | 2021-06-11 14:37
Add this script to your rigid body, it would be even simplier but add_central_force() behaves in an unusual manner and previous forces need clearing on the next frame. This acts like the damper (I just came across) but in your own script you could tweak the friction depending on what your object is on top of:
extends RigidBody2D
export(float) var mu_static = 0.8 # friction coefficients
export(float) var mu_moving = 0.5 # pushing something moving is easier
# mu depends on what material the object is on, so use area detectors and change
# this values depending on ice or mud
export(float) var move_strength = 50
var applied_forces: Vector2 = Vector2(0, 0)
func add_force_for_frame(force: Vector2):
# add_force adds a permanent force, for a temporary one we need to wipe it
# by undo the force next frame, just keep track of forces applied
applied_forces += force
self.add_central_force(force)
func _ready() -> void:
# no world gravity pushing the object down (in the +y) direction
# we are top down so gravity is acting into the screen (in +z) but the
# "ground" normal force is canceling it out
self.gravity_scale = 0
func _physics_process(delta: float) -> void:
add_force_for_frame(-applied_forces) # wipe out previous forces
# arrows keys apply force to move it
# could equally have a different body which pushes it
if Input.is_action_pressed("ui_right"):
self.add_force_for_frame(move_strength * Vector2(1, 0))
if Input.is_action_pressed("ui_left"):
self.add_force_for_frame(move_strength * Vector2(-1, 0))
if Input.is_action_pressed("ui_up"):
self.add_force_for_frame(move_strength * Vector2(0, -1))
if Input.is_action_pressed("ui_down"):
self.add_force_for_frame(move_strength * Vector2(0, 1))
# this bit applies the damping force
# minus is there because friction resists the direction of motion
# friction depends on the m * g of the object (in this case the weight)
if self.linear_velocity.length() == 0:
self.add_force_for_frame(- self.weight * mu_static * self.linear_velocity.normalized())
else:
self.add_force_for_frame(- self.weight * mu_moving * self.linear_velocity.normalized())
# no worries about collisions as they add their own forces in opposition to these ones
darkshadow | 2021-06-13 12:55
Thank you! It works perfectly !
Dayls | 2021-06-15 11:20
Hello! I need your help. The script works well and everything, but I have a problem. I want to simulate a tank ~45T. and I want it to stop fast when I release the button. But I can only achieve that with friction coefficient around 20, but that’s not really correct cause it can’t be greater that 1. Could you advice something?