Bullet.cs
using Sandbox;
using Sandbox.Diagnostics;

public sealed class Bullet : Component, Component.ITriggerListener
{
	[Property]
	public int VelocityMultiplier { get; set; } = 10;

	[Property]
	public float Damage { get; set; } = 10;

	[Property]
	public GameObject Owner { get; set; }

	[Property]
	public GameObject Weapon { get; set; }

	protected override void OnFixedUpdate()
	{
		GetComponent<Rigidbody>().SmoothMove( WorldPosition + (Vector3.Forward * VelocityMultiplier).RotateAround( Vector3.Zero, WorldRotation ), 0.02f, Time.Delta );
	}

	void ITriggerListener.OnTriggerEnter( GameObject other )
	{
		if ( other.Parent == Owner ) return;

		var damageable = other.GetComponentInParent<IDamageable>();

		if ( damageable is not null )
		{
			damageable.OnDamage( new DamageInfo()
			{
				Damage = Damage,
				Attacker = Owner,
				Position = WorldPosition,
				Weapon = Weapon,
			} );
		}

		DestroyGameObject();
	}
}