teleporting rigidbody when adding collision children to it
Asked Answered
S

4

0

So i have these boxes in my game that the player can move around and jump on top of. the player can also break these boxes in order to get the shape they want. how this works is that all the boxes are staticbodies that create a collision sibling with the same shape under the rigidbody3D parent. with this, i'm able to create all sorts of shape that all have proper physics and im able to access each box separately. now, i wanted to add a system where if the player broke the middle box between two boxes, the two boxes would get transported to different RB parents so that they dont react to the others movement. essentially, i made a code that when a box is broken, it would start a chain to all the attached boxes and give them a value. all the boxes that are conected will get the same value. with this, if all the boxes are still connected(i.e. have the same value), they would remain under the current parent, but if not, then the parent rigidbody3D will run this command on the boxes:
`extends RigidBody3D

var ready6 = false
var ready5 = false
var ready4 = false
var ready3 = false
var ready2 = false
var ready1 = false

@onready var Saver = get_node("/root/TestScdne/WorldBlocks")

var PHSAVER : PackedScene

var HighestGroup

Called when the node enters the scene tree for the first time.

func _ready():
PHSAVER = preload("res://Scenes/rb.tscn")

Called every frame. 'delta' is the elapsed time since the previous frame.

func process(delta):
if get_children() == null:
queue_free()
elif ready1 == true and ready2 == true and ready3 == true and ready4 == true and ready5 == true and ready6 == true:
ready1 = false
ready2 = false
ready3 = false
ready4 = false
ready5 = false
ready6 = false

	var ph1inst = PHSAVER.instantiate()
	var ph2inst = PHSAVER.instantiate()
	var ph3inst = PHSAVER.instantiate()
	var ph4inst = PHSAVER.instantiate()
	var ph5inst = PHSAVER.instantiate()
	var ph6inst = PHSAVER.instantiate()
	
	Saver.add_child(ph1inst)
	Saver.add_child(ph2inst)
	Saver.add_child(ph3inst)
	Saver.add_child(ph4inst)
	Saver.add_child(ph5inst)
	Saver.add_child(ph6inst)
	
	ph1inst.global_transform = global_transform
	ph2inst.global_transform = global_transform
	ph3inst.global_transform = global_transform
	ph4inst.global_transform = global_transform
	ph5inst.global_transform = global_transform
	ph6inst.global_transform = global_transform
	
	for b in get_children():
		if b is StaticBody3D:
			if b.GroupNumber == HighestGroup or b.GroupNumber == 0:
				b.GroupNumber = 0
				
			elif b.GroupNumber == 1:
				b.GroupNumber = 0
				b.get_parent().remove_child(b)
				b.physiccollblock.get_parent().remove_child(b.physiccollblock)
				ph1inst.add_child(b)
				ph1inst.add_child(b.physiccollblock)
			elif b.GroupNumber == 2:
				b.GroupNumber = 0
				b.get_parent().remove_child(b)
				b.physiccollblock.get_parent().remove_child(b.physiccollblock)
				ph2inst.add_child(b)
				ph2inst.add_child(b.physiccollblock)
			elif b.GroupNumber == 3:
				b.GroupNumber = 0
				b.get_parent().remove_child(b)
				b.physiccollblock.get_parent().remove_child(b.physiccollblock)
				ph3inst.add_child(b)
				ph3inst.add_child(b.physiccollblock)
			elif b.GroupNumber == 4:
				b.GroupNumber = 0
				b.get_parent().remove_child(b)
				b.physiccollblock.get_parent().remove_child(b.physiccollblock)
				ph4inst.add_child(b)
				ph4inst.add_child(b.physiccollblock)
			elif b.GroupNumber == 5:
				b.GroupNumber = 0
				b.get_parent().remove_child(b)
				b.physiccollblock.get_parent().remove_child(b.physiccollblock)
				ph5inst.add_child(b)
				ph5inst.add_child(b.physiccollblock)
			elif b.GroupNumber == 6:
				b.GroupNumber = 0
				b.get_parent().remove_child(b)
				b.physiccollblock.get_parent().remove_child(b.physiccollblock)
				ph6inst.add_child(b)
				ph6inst.add_child(b.physiccollblock)

#if Input.is_action_just_pressed("debug"):
#	print(ready1)
#	print(ready2)
#	print(ready3)
#	print(ready4)
#	print(ready5)
#	print(ready6)
#	print(" ")
#	for b in get_children():
#		if b is StaticBody3D:
#			
#			print(b.GroupNumber)

`
the "physiccollblock" refers to the collision sibling of the box that are always in the same position and rotation.phsaver is this rigidbody with this script attached to it. and this code works, almost. see for yourselves(my game is third person btw):


although the two pair of boxes get disconnected after destroying the middle box; there is a slight issue as you can tell from the second pic. instead of falling down from where it was, the top pair gets teleported slightly off center before falling on top of the bottom pair and collapsing since it wasn't centered. and this is very annoying. no matter what i do, when the boxes get disconnected, they teleport a small distance in a random direction from where they were before they act normally again. as you can see i have even set the transform of the new rigidbodies to be equal to that of the previous parent, but for some reason, when the boxes are added to it as children, it teleports around a bit, sometimes clipping with the floor. i suspect it has something to do with this bit of code here, specifically either the location of the new rigidbody, or the method that i use to add the boxes to it. but i honestly can't see the issue with my code and why that would cause it to teleport.
any solution or insight to what might be causing this is veryy appreciated! i know its not that game breaking but with bigger boxes, its super off-putting, plus i would feel guilty for leaving that in the game.

thank you for your time and have a nice day!

Sarmiento answered 5/2 at 13:22 Comment(0)
A
1

Sarmiento instead of falling down from where it was, the top pair gets teleported slightly off center before falling on top of the bottom pair and collapsing since it wasn't centered.

You can try a different physics and see if the behavior changes:

The code preferably should be formatted like this:

``` 
code
``` 
Amphichroic answered 5/2 at 13:55 Comment(0)
S
0

Amphichroic oops, sorry about the code its my first time on the forums.

ill try these to see if they work. thanks!

Sarmiento answered 6/2 at 6:21 Comment(0)
S
0

Amphichroic ok, wow. so i installed the godot jolt physics engine and it worked flawlessly! the teleportation is almost completely gone and although it still moves up by a centimeter, the main issues i had with it are fixed; including the clipping with the floor. ill have to read up more on jolt but for now, this is awesome. massive thanks to you!!

Sarmiento answered 6/2 at 6:51 Comment(0)
S
1

so, its been a month since this post and i have learned some more about the issue and want to add this here incase it helps someone.
the reason for this bug happening is something called "position correction", where , obviously, it offsets the object's position slightly.
the reason why jolt fixes the issue is becuase jolt , i assume, has a lower position correction rate at 20%. still not off completly but better than default. if you go to jolt 3d settings under the physics branch, you can lower the position correction to 0%, completly fixing this issue and giving precise positions with no offset at all.

hope this helps!!

Sarmiento answered 2/3 at 14:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.