Godot Version
4.7.2
Question
I’m trying to basically simulate two solar systems moving towards each other, crashing, then moving away from each other in 3D. So the planets in each solar system are in circular orbits around the sun of the system. The suns in either system are moving towards each other in a straight line. Planets that hit the suns should not affect their motion, but when planets collide with suns or planets, they should change their direction of motion (so if they were moving clockwise on their orbit, they should now move anticlockwise). When the suns hit each other, they move in the opposite direction to their original motion so the entire two solar systems also change directions as a result.
I implemented that by making the suns and planets characterbody3d nodes with separate scripts for suns and planets and motion mode floating. I was able to create the motion I described, but my issue here is that when planets hit suns, they dont always deflect right away, sometimes the planet enters the sun even though it is supposed to collide with it. So i assumed the planet would detect collision right away, instead it passes through the sun a bit before detecting the collision and deflecting.
I put the planets on collision layer 1 and collision masks 1 and 2 while the suns are on collision layer 2 and collision mask 2. My thought process is that I want the planets to detect collision with the sun, but I dont want the sun to be affected by it, only by collision with another sun. When I tried to put the sun on the same collision layer, it moved in another direction, being affected by the collision with the planet, when I want it to keep moving in a straight line towards the other sun until colliding with it.
this is the physics process function for the suns:
func _physics_process(delta):
velocity.x += 0.5 * curr_acceleration * delta # the sun only moves on the x axis
# once the suns stopped after moving back from collision
if velocity.x == 0:
velocity.x = init_speed
curr_acceleration = sign(init_speed) * acceleration
has_collided = false
var collision = move_and_collide(velocity * delta)
if collision:
velocity = velocity.bounce(collision.get_normal())
if collision.get_collider().body_type == Global.BodyType.Sun and !has_collided:
velocity.x *= -1
curr_acceleration = sign(init_speed) * deceleration
has_collided = true
and for the planets:
func _physics_process(delta):
t += delta # how much time has passed
var collision = move_and_collide(velocity * delta)
if collision and t > 0.3:
velocity = velocity.bounce(collision.get_normal())
# state indicates whether it is moving clockwise or anticlockwise on its orbit
# get current angle and set it to starting angle
if state == 1:
angle = angle + ang_speed * t
else:
angle = angle - ang_speed * t
# change direction
state = 2 if state == 1 else 1
t = 0
# calculates the position of the planet based on the angle, position of the sun, and the radius of its orbit
if state == 1:
global_position.x = sun.global_position.x + radius * cos(angle + ang_speed * t)
global_position.y = sun.global_position.y + radius * sin(angle + ang_speed * t)
else:
global_position.x = sun.global_position.x + radius * cos(angle - ang_speed * t)
global_position.y = sun.global_position.y + radius * sin(angle - ang_speed * t)
i was wondering if anyone has any idea why the planet is passing through the sun a bit before detecting the collision and deflecting. I even tried playing around with safe margin but it didn’t help