Custom Gravity System glitching when entering other Area3Ds

Using Godot Version: 4.4

Hello! I’m rather new to coding, and I’m attempting to create a custom gravity system. (I’m not using the built in one just so I have what’s needed to make fake gravity for the player and some other stuff in the future) I’m having an issue with the Rigidbody3Ds spinning uncontrollably and bouncing around when entering any Area3D minus the first one of the scene, the gravity does still seem to work however, minus the bug. I’ll attach my code below:

Gravity Actor/RigidBody3D - gravity_actor.gd:

extends RigidBody3D

var within_GVs : Array [GVData] #Gravity Volume Resource
func _process(delta: float) -> void:
	if not within_GVs.is_empty():
		var gravity_direct =- (global_position - within_GVs.front().gravity_pivot)
		apply_force(gravity_direct.normalized() * 1 * mass, position)

func _add_GV(GVData):
	within_GVs.append(GVData)
	print(str(within_GVs))
	
func _remove_GV(GVData):
	within_GVs.erase(GVData)
	print(str(within_GVs))

Gravity Volume/Area - gravity_volume.gd:




extends Area3D

##Gravity Volume Settings
@export var GravitySettings : GVData
var NearGravActors : Array[RigidBody3D] = []

func _ready() -> void:
	connect("body_entered", _gravity_entered)
	connect("body_exited", _gravity_exited)
	if GravitySettings == null:
		GravitySettings = GVData.new()
	GravitySettings.gravity_pivot = global_position

func _gravity_entered(body):
	NearGravActors.append(body)
	if body.get_script():
		body._add_GV(GravitySettings)
	
func _gravity_exited(body):
	NearGravActors.erase(body)
	if body.get_script():
		body._remove_GV(GravitySettings)

Addtionally, I was unsure how to grab the GVData out of within_GVs with the highest GVData.gravity_priority, so I’ve just used within_GVs.front() for the time. And lastly, thanks for reading this, and if you have any advice or thoughts on this code, please let me know if you want :+1: As I’m still quite new to programming :sweat_smile:

One potential problem: apply_force(...) is meant to be called every physics update, so basically in the physics_process(...).

I’ll look more closely at this later - seems fun :).

1 Like

Thank you, I actually forgot about _physics_process(...) :open_mouth: Still, even after changing that now, it continues what it did before for some reason. And again, oddly only for Area3D 2 and 3 (and whatever new ones I add beyond the first.)

code removed

And thanks! : ) It has been pretty fun despite some struggle along the way

So, I assume gravity_pivot property is the center of the gravity area. You might want to try apply_force(<force_scale>, <however you grab it>.gravity_pivot - global_position). So, to be more clear, it’s a vector from the global position of the rigid body to the center of gravity.

Edit: I confuse myself sometimes. You already have gravity_direct, so just try getting rid of the second parameter in the apply_force(...) function.

1 Like

Yep, that fixed it :+1: changing it to apply_force(gravity_direct.normalized() * 1 * mass) removes the spinning issue. I don’t know why, but, I just assumed adding , position was required. Thank you so much, I was looking though everything else thinking I mistyped or messed up something again :') (also, 1 was just the temporary placeholder of GVData.gravity_strength at the time)

Don’t forget that position (as opposed to global_position) is a position in relation to the parent, so if I’m right about what was happening, apply_force(...) was using a positing of the RigidBody in relation to the GravityActor, which never changed (meaning it was at (0.0, 0.0, 0.0), where, I imagine, was the first gravity area, that’s why it behaved normally).

Generally, you want the physical bodies (like RigidBody) to be on top of the object hierarchy, because the physics engine affects their and only their thansforms (position, orientation, etc).

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.