A weapon Component for a shooter that handles firing input, raytracing from the camera, playing a pistol sound, and applying impulse to rigidbodies hit by the shot.
using Sandbox;
using System.Linq;
public sealed class ShooterWeapon : Component
{
[Property] public string WeaponName { get; set; } = "Pistol";
[Property] public float DamageForce { get; set; } = 800f;
[Property] public float FireRate { get; set; } = 0.25f;
[Property] public float Range { get; set; } = 2000f;
private TimeSince _timeSinceLastShot;
protected override void OnUpdate()
{
if ( Input.Down( "attack1" ) && _timeSinceLastShot >= FireRate )
{
Shoot();
_timeSinceLastShot = 0;
}
}
private void Shoot()
{
var cam = Scene.Camera;
if ( cam == null ) return;
Vector3 startPos = cam.Transform.Position;
Vector3 forwardDir = cam.Transform.World.Forward;
var tr = Scene.Trace.Ray( startPos, startPos + forwardDir * Range )
.IgnoreGameObjectHierarchy( GameObject )
.Run();
Sound.Play( "rust_pistol.shoot", Transform.Position );
if ( tr.Hit && tr.GameObject != null )
{
// 1. Проверяем напрямую точное попадание в Rigidbody
if ( tr.Body != null )
{
tr.Body.ApplyImpulseAt( tr.EndPosition, forwardDir * DamageForce );
return;
}
// 2. Ищем Rigidbody на текущем объекте или у его родителей
var targetBody = tr.GameObject.Components.Get<Rigidbody>( true )
?? tr.GameObject.Components.GetInAncestors<Rigidbody>();
if ( targetBody != null )
{
targetBody.ApplyImpulse( forwardDir * DamageForce );
}
}
}
}