Weapons/Projectile.cs
/// <summary>
/// A projectile. It explodes when it hits something.
/// </summary>
public class Projectile : Component, Component.ICollisionListener, IInstigator
{
[RequireComponent] public Rigidbody Rigidbody { get; set; }
[Sync( SyncFlags.FromHost )] public PlayerData Instigator { get; set; }
protected TimeSince TimeSinceCreated;
protected override void OnStart()
{
Tags.Add( "projectile" );
}
protected override void OnEnabled()
{
TimeSinceCreated = 0;
}
void ICollisionListener.OnCollisionStart( Collision collision )
{
if ( IsProxy )
return;
var player = collision.Other.GameObject.GetComponentInParent<Player>();
if ( Instigator.IsValid() && player.IsValid() && player.PlayerData == Instigator )
{
return;
}
OnHit( collision );
}
protected virtual void OnHit( Collision collision = default )
{
GameObject.Destroy();
}
/// <summary>
/// Tell the instigator their projectile hit, so they can do things like show a hitmarker
/// </summary>
protected void NotifyHit( IDamageable target, Vector3 point )
{
if ( !Instigator.IsValid() ) return;
var connection = Instigator.Connection;
if ( connection is null ) return;
using ( Rpc.FilterInclude( connection ) )
{
OnClientHit( target, point );
}
}
[Rpc.Broadcast]
protected virtual void OnClientHit( IDamageable target, Vector3 point )
{
HitMarker.CreateAt( point );
}
/// <summary>
/// Updates the current direction of the projectile
/// </summary>
/// <param name="direction"></param>
/// <param name="speed"></param>
public void UpdateDirection( Vector3 direction, float speed )
{
WorldRotation = Rotation.LookAt( direction, Vector3.Up );
Rigidbody.Velocity = WorldRotation.Forward * speed;
}
}