How to Create a Bullet in Godot
High Level Plan
Apply an impulse to a RigidBody. When the body has travelled far enough (or if enough time has passed), delete it.
Scene Tree
Create a new scene, call it GodotBullet
. Here is what the node tree should look like for this scene:
- RigidBody2D
- CollisionShape2D
- Sprite
Scripting
Attach a script to the RigidBody2D
node of the GodotBullet
scene. Call the script GodotBullet.cs
.
Create a few public fields in your GodotBullet
class to allow clients to customize certain aspects of the bullet:
// File: GodotBullet.cs
public class GodotBullet: RigidBody2D{
// Public Fields
public float MaxDistance = 800; // How far (in pixels) the bullet will travel before it is destroyed
public float MaxSeconds = 1; // How long (in seconds) before the bullet is destroyed
public float ImpulseMag = 1200; // How much impulse to give the bullet when it is launched
}
Create a private field that will allow us to track how far the bullet has travelled (so that we can destroy it when it has travelled far enough):
// File: GodotBullet.cs
public class GodotBullet: RigidBody2D{
// ...
private Vector2D origianlPos;
// ...
}
Create a LaunchBullet
method, which the client can call to…well…launch the bullet (the bullet will be stationary until this method is called):
// File: GodotBullet.cs
public class GodotBullet: RigidBody2D{
// ...
public void LaunchBullet(){
this.originalPos = this.Position; // save the position the bullet was launched from
// start a timer that will delete the bullet when it has lived long enough
Timer timer = new Timer();
timer.WaitTime = this.MaxSeconds;
timer.OneShot = true;
timer.connect("timeout",this,nameof(OnTimeToDie));
timer.Start();
this.ApplyCentralImpulse(this.Transform.x.Normalized() * this.ImpulseMag); // apply an impulse in the same direction that the bullet is facing
}
// ...
}
Implement the OnTimeToDie
method:
// File: GodotBullet.cs
public class GodotBullet: RigidBody2D{
// ...
private void OnTimeToDie(){
this.QueueFree();
}
// ...
}
Every physics frame, we need to check if the bullet has travelled far enough, if so, we delete it. Thus, we need to implement physics frame for this class:
// File: GodotBullet.cs
public class GodotBullet: RigidBody2D{
// ...
public override void _PhysicsProcess(float delta){
float distanceTravelled = this.Position.DistanceTo(this.originalPos);
if (distanceTravelled > this.MaxDistance)
this.QueueFree();
}
// ...
}
How to Use the Bullet
The client can use the bullet by instancing the GodotBullet
scene, positioning/orienting the bullet however they want, and then calling its LaunchBullet()
method.
PackedScene bulletScene = GD.Load<PackedScene>("res://GodotBullet.tscn");
GodotBullet bullet = (GodotBullet)bulletScene.Instance();
bullet.Position = new Vector2D(200,200);
bullet.Rotation = Mathf.Deg2Rad(40);
bullet.LaunchBullet();
The Final Product
Click anywhere to spawn a bullet.