mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-02 11:28:19 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
165 lines
3.3 KiB
C#
165 lines
3.3 KiB
C#
namespace Sandbox;
|
|
|
|
/// <summary>
|
|
/// A hitbox that can be placed manually on a GameObject, instead of coming from a model
|
|
/// </summary>
|
|
[Expose]
|
|
[Title( "Hitbox" )]
|
|
[Category( "Game" )]
|
|
[Icon( "psychology_alt" )]
|
|
public sealed class ManualHitbox : Component, Component.ExecuteInEditor
|
|
{
|
|
internal Hitbox Hitbox { get; private set; }
|
|
|
|
HitboxSystem system;
|
|
GameObject _target;
|
|
|
|
/// <summary>
|
|
/// The target GameObject to report in trace hits. If this is unset we'll default to the gameobject on which this component is.
|
|
/// </summary>
|
|
[Property]
|
|
public GameObject Target
|
|
{
|
|
get => _target;
|
|
set
|
|
{
|
|
if ( _target == value ) return;
|
|
|
|
_target = value;
|
|
Rebuild();
|
|
}
|
|
}
|
|
|
|
public enum HitboxShape
|
|
{
|
|
Sphere,
|
|
Capsule,
|
|
Box,
|
|
Cylinder
|
|
}
|
|
|
|
[Property] public HitboxShape Shape { get; set; } = HitboxShape.Sphere;
|
|
[Property, HideIf( nameof( Shape ), HitboxShape.Box )] public float Radius { get; set; } = 10.0f;
|
|
[Property] public Vector3 CenterA { get; set; }
|
|
[Property, HideIf( nameof( Shape ), HitboxShape.Sphere )] public Vector3 CenterB { get; set; }
|
|
[Property] public TagSet HitboxTags { get; set; } = new();
|
|
|
|
protected override void OnAwake()
|
|
{
|
|
Scene.GetSystem( out system );
|
|
}
|
|
|
|
protected override void DrawGizmos()
|
|
{
|
|
if ( !Gizmo.IsSelected )
|
|
return;
|
|
|
|
if ( Shape == HitboxShape.Sphere )
|
|
{
|
|
Gizmo.Draw.LineSphere( CenterA, Radius );
|
|
}
|
|
|
|
if ( Shape == HitboxShape.Capsule )
|
|
{
|
|
Gizmo.Draw.LineCapsule( new( CenterA, CenterB, Radius ) );
|
|
}
|
|
|
|
if ( Shape == HitboxShape.Box )
|
|
{
|
|
Gizmo.Draw.LineBBox( BBox.FromPositionAndSize( CenterA, CenterB ) );
|
|
}
|
|
|
|
if ( Shape == HitboxShape.Cylinder )
|
|
{
|
|
Gizmo.Draw.LineCylinder( CenterA, CenterB, Radius, Radius, 16 );
|
|
}
|
|
}
|
|
|
|
protected override void OnDirty()
|
|
{
|
|
Rebuild();
|
|
}
|
|
|
|
protected override void OnEnabled()
|
|
{
|
|
Rebuild();
|
|
}
|
|
|
|
protected override void OnDisabled()
|
|
{
|
|
Hitbox?.Dispose();
|
|
Hitbox = null;
|
|
}
|
|
|
|
public void Rebuild()
|
|
{
|
|
if ( system is null )
|
|
return;
|
|
|
|
Hitbox?.Dispose();
|
|
Hitbox = null;
|
|
|
|
var body = new PhysicsBody( system.PhysicsWorld );
|
|
var tx = WorldTransform;
|
|
|
|
PhysicsShape shape = null;
|
|
|
|
var hitbox = new Hitbox( Target ?? GameObject, HitboxTags, body );
|
|
|
|
if ( Shape == HitboxShape.Sphere )
|
|
{
|
|
shape = body.AddSphereShape( CenterA * tx.Scale, Radius * tx.UniformScale );
|
|
}
|
|
else if ( Shape == HitboxShape.Capsule )
|
|
{
|
|
shape = body.AddCapsuleShape( CenterA * tx.Scale, CenterB * tx.Scale, Radius * tx.UniformScale );
|
|
}
|
|
else if ( Shape == HitboxShape.Box )
|
|
{
|
|
shape = body.AddBoxShape( CenterA, Rotation.Identity, CenterB * 0.5f );
|
|
hitbox.Bounds = new( CenterA, CenterB );
|
|
}
|
|
else if ( Shape == HitboxShape.Cylinder )
|
|
{
|
|
var axis = CenterB - CenterA;
|
|
var height = axis.Length;
|
|
var position = (CenterA + CenterB) * 0.5f;
|
|
var rotation = Rotation.LookAt( axis.Normal, Vector3.Up );
|
|
shape = body.AddCylinderShape( position, rotation, height, Radius );
|
|
hitbox.Bounds = new( CenterA, CenterB );
|
|
}
|
|
|
|
if ( shape is not null )
|
|
{
|
|
shape.Tags.SetFrom( GameObject.Tags );
|
|
|
|
body.Transform = tx.WithScale( 1 );
|
|
body.Component = this;
|
|
|
|
Hitbox = hitbox;
|
|
}
|
|
else
|
|
{
|
|
body.Remove();
|
|
}
|
|
}
|
|
|
|
public void UpdatePositions()
|
|
{
|
|
if ( Hitbox is null ) return;
|
|
|
|
Hitbox.Body.Transform = WorldTransform;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tags have been updated
|
|
/// </summary>
|
|
protected override void OnTagsChanged()
|
|
{
|
|
OnPropertyDirty();
|
|
}
|
|
|
|
}
|
|
|
|
|