I know this is a common question for this topic, but I have tried everything I have found online and I just don't know what I am doing wrong. I started with Godot a few days ago, and I'm making a small multiplayer tank game. I want to get the bullets to bounce off the wall in the other direction. ]()
extends CharacterBody3D
const SPEED = 20.0
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
position += transform.basis * Vector3(0, 0, -SPEED) * delta
var collision = move_and_collide(velocity * delta)
if collision:
print(collision.get_collision_count())
velocity = velocity.bounce(collision.get_normal())
This is the code I've used for trying to make it bounce off the wall, and although it does seem to collide with the walls, it just goes over it and past it. You can see it in the video here. Any ideas? Am I using the bounce() function in the wrong way? Or am I not doing enough?[See the video of the result here
I know this is a common question for this topic, but I have tried everything I have found online and I just don't know what I am doing wrong. I started with Godot a few days ago, and I'm making a small multiplayer tank game. I want to get the bullets to bounce off the wall in the other direction. ](https://imgur.com/a/k2IneCv)
extends CharacterBody3D
const SPEED = 20.0
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
position += transform.basis * Vector3(0, 0, -SPEED) * delta
var collision = move_and_collide(velocity * delta)
if collision:
print(collision.get_collision_count())
velocity = velocity.bounce(collision.get_normal())
This is the code I've used for trying to make it bounce off the wall, and although it does seem to collide with the walls, it just goes over it and past it. You can see it in the video here. Any ideas? Am I using the bounce() function in the wrong way? Or am I not doing enough?[See the video of the result here
These two lines can move the bullet:
position += transform.basis * Vector3(0, 0, -SPEED) * delta
This line moves the bullet (until it collides):
var collision = move_and_collide(velocity * delta)
Pick one.
Futhermore, the code that runs when there is a collision updates velocity
using bounce
... But the first line does not use velocity
(the direction is based on transform.basis
instead), so that line will continue moving the bullet in the same direction.
In fact, I suspect that your velocity
is zero. So only the first line is actually moving the bullet. And no collision is detected.
Thus, you want to give an initial value to the velocity
. For example:
func _ready() -> void:
velocity = global_transform.basis * Vector3(0, 0, -SPEED)
Here I'm using global_transform
, because velocity
is always in global space.
And use that velocity
to move the bullet, so that when you detect the collision, it actually changes direction.
My recommendation is to stick with move_and_collide
, since you want to react to the collition. The code would be like this:
func _ready() -> void:
velocity = global_transform.basis * Vector3(0, 0, -SPEED)
func _physics_process(delta: float) -> void:
var collision := move_and_collide(velocity * delta)
if collision != null:
velocity = velocity.bounce(collision.get_normal())
Notice here the line updating position
has been removed.
Alternatively, if you do not want move_and_collide
to move the bullet, then pass true
on the test_only
parameter (which is the second parameter of move_and_collide
).
In this case, you need to update the first line to use velocity
:
func _ready() -> void:
velocity = global_transform.basis * Vector3(0, 0, -SPEED)
func _physics_process(delta: float) -> void:
var collision := move_and_collide(velocity * delta, true)
if collision != null:
print(collision.get_collision_count())
velocity = velocity.bounce(collision.get_normal())
global_position += velocity * delta
As you might have guessed, here I'm using global_position
because velocity
is always in global space.
Finally, presumably you want the bullet to rotate. The simplest way to do that would be use look_at
after you update the velocity:
velocity = velocity.bounce(collision.get_normal())
look_at(global_position + velocity, up_direction)
Now, I believe that is correct, but if the result is that the bullet is looking backwards, you want to pass a true
to the third parameter of look_at
:
velocity = velocity.bounce(collision.get_normal())
look_at(global_position + velocity, up_direction, true)
That basically flips the orientation.