🔍 s&box Package Code Search
Search C# source code, UI razor templates, shaders, and configs across s&box packages.
🔗 Raw Facepunch API Link: https://public.facepunch.com/sbox/code/search/1/?ident=duccsoft.libfreecam&take=20
Showing code results for query:
*
(6 total matches found)
Game
library
using System;
namespace Duccsoft;
public partial class Freecam
{
/// <summary>
/// Invoked whenever a freecam is enabled. The argument is the freecam that was enabled.
/// </summary>
public static event Action<Freecam> OnFreecamStart;
/// <summary>
/// Invoked whenever a freecam is disabled. The argument is the freecam that was disabled.
/// </summary>
public static event Action<Freecam> OnFreecamEnd;
/// <summary>
/// Removes all listeners from the static events of this class. Used by
/// <see cref="CameraEventCleanupSystem"/> to tidy things up between play sessions.
/// </summary>
public static void ClearInvocationLists()
{
OnFreecamStart = null;
OnFreecamEnd = null;
}
}
Game
library
global using Sandbox; global using System.Collections.Generic; global using System.Linq;
Game
library
namespace Duccsoft;
/// <summary>
/// Enables the use of AnalogMove and AnalogLook to control the position and rotation
/// of the main camera of the scene.
/// </summary>
[Title( "Freecam" )]
[Category( "Camera" )]
[Icon( "control_camera" )]
public sealed partial class Freecam : Component
{
/// <summary>
/// How many units per second the camera will move at normal speed.
/// </summary>
[Property] public float Speed { get; set; } = 300f;
/// <summary>
/// A factor applied to movement speed whenever the crouch button is held.
/// </summary>
[Property] public float LowSpeedFactor { get; set; } = 0.25f;
/// <summary>
/// A factor applied to movement speed whenever the run button is held.
/// </summary>
[Property] public float HighSpeedFactor { get; set; } = 2.5f;
/// <summary>
/// If true, prevents the player from looking higher than directly up or lower
/// than directly down. Prevents the camera from going upside-down and doing loop-de-loops.
/// </summary>
[Property] public bool ClampPitch { get; set; } = true;
/// <summary>
/// If true, the freecam will use a <see cref="CharacterController"/> to handle collisions.
/// If none exists already, one will be created.
/// </summary>
[Property] public bool UseCollision { get; set; } = true;
/// <summary>
/// The main scene camera. Will be refreshed each update.
/// </summary>
private CameraComponent _camera;
/// <summary>
/// The current angle/rotation that we are looking at.
/// </summary>
private Angles _lookAngle;
/// <summary>
/// If <see cref="UseCollision"/> is true, this will be an instance of a <see cref="CharacterController"/>
/// on the same GameObject as this component.
/// </summary>
private CharacterController _controller;
protected override void OnEnabled()
{
OnFreecamStart?.Invoke( this );
}
protected override void OnDisabled()
{
OnFreecamEnd?.Invoke( this );
_controller?.Destroy();
_controller = null;
}
protected override void OnUpdate()
{
if ( _camera is null || !_camera.IsMainCamera )
{
_camera = Scene.Camera;
}
if ( !_camera.IsValid() )
return;
RotateMainCamera();
MoveMainCamera();
}
protected override void OnFixedUpdate()
{
UpdatePosition();
}
private void RotateMainCamera()
{
_lookAngle += Input.AnalogLook;
if ( ClampPitch )
{
_lookAngle.pitch = _lookAngle.pitch.Clamp( -89f, 89f );
}
_camera.Transform.Rotation = _lookAngle;
}
/// <summary>
/// Move the main scene camera to roughly the position of this GameObject.
/// </summary>
private void MoveMainCamera()
{
if ( UseCollision )
{
// Put the camera up in to the center of the CharacterController's collision cube.
_camera.Transform.Position = Transform.Position + Vector3.Up * 8f;
}
else
{
_camera.Transform.Position = Transform.Position;
}
}
/// <summary>
/// Use input to move this GameObject. If <see cref="UseCollision"/> is true, a <see cref="CharacterController"/>
/// will be used to ensure that this GameObject doesn't clip through anything it shouldn't.
/// </summary>
private void UpdatePosition()
{
EnsureCollision();
// Move using WASD or left thumbstick
var movement = Input.AnalogMove * Speed * GetSpeedFactor();
// Move relative to the direction the camera is facing.
movement *= _lookAngle;
if ( UseCollision )
{
_controller.Velocity = movement;
_controller.Move();
_controller.IsOnGround = false;
}
else
{
Transform.Position += movement * Time.Delta;
}
}
private void EnsureCollision()
{
if ( !UseCollision )
return;
_controller ??= Components.GetOrCreate<CharacterController>();
_controller.Radius = 8f;
_controller.Height = 16f;
}
private float GetSpeedFactor()
{
var speedFactor = 1f;
if ( Input.Down( CameraActions.MoveSlow ) )
{
speedFactor = LowSpeedFactor;
}
else if ( Input.Down( CameraActions.MoveFast ) )
{
speedFactor = HighSpeedFactor;
}
return speedFactor;
}
}
Game
library
namespace Duccsoft;
/// <summary>
/// On game shutdown, clears the invocation lists of the static events of <see cref="Freecam"/>.
/// This is to prevent duplicate event subscribers from piling up between play sessions.
/// </summary>
public class CameraEventCleanupSystem : GameObjectSystem
{
public CameraEventCleanupSystem( Scene scene ) : base( scene )
{
}
public override void Dispose()
{
base.Dispose();
Freecam.ClearInvocationLists();
}
}
Game
library
namespace Duccsoft;
public sealed partial class Freecam
{
/// <summary>
/// Holds whatever instance of <see cref="Freecam"/> may have been created by invoking <see cref="Toggle"/>.
/// </summary>
private static Freecam _conCmdInstance;
/// <summary>
/// Holds references to whatever <see cref="Freecam"/> instances were disabled by <see cref="Toggle"/>.
/// </summary>
private static HashSet<Freecam> _disabledFreecams = new();
[ConCmd("freecam", Help = "Toggle a mode where the camera can be moved and rotated freely.")]
public static void Toggle()
{
var camera = Game.ActiveScene?.Camera;
if ( !camera.IsValid() )
return;
// If we were already using the freecam ConCmd...
if ( _conCmdInstance?.Active == true )
{
// ...toggle it off by destroying its GameObject.
_conCmdInstance?.GameObject?.Destroy();
_conCmdInstance = null;
// Reenable whatever non-ConCmd freecam we might have previously disabled.
ReenablePreviousFreecam();
return;
}
// If there is an active freecam not created by this ConCmd, disable it.
DisableActiveFreecams();
// Make a new GameObject with a Freecam component.
CreateFreecam();
}
private static void DisableActiveFreecams()
{
// Find any freecams that are currently active...
var freecams = Game.ActiveScene.GetAllComponents<Freecam>();
if ( !freecams.Any() )
return;
foreach ( var freecam in freecams )
{
// ...and turn them off.
freecam.Enabled = false;
_disabledFreecams.Add( freecam );
}
return;
}
private static void ReenablePreviousFreecam()
{
// Clean out any invalid freecams (e.g. GameObject or component was deleted)
foreach( var freecam in _disabledFreecams.ToList() )
{
if ( !freecam.IsValid() )
{
_disabledFreecams.Remove( freecam );
}
}
// Find the first valid freecam we had previously disabled
var firstFreecam = _disabledFreecams.FirstOrDefault();
if ( firstFreecam is null )
return;
firstFreecam.Enabled = true;
_disabledFreecams.Remove( firstFreecam );
}
private static void CreateFreecam()
{
// There were no active freecams, so create one.
var freecamGo = new GameObject( true, "ConCmd Freecam" );
var camTx = Game.ActiveScene.Camera.Transform;
freecamGo.Transform.Position = camTx.Position;
_conCmdInstance = freecamGo.Components.Create<Freecam>();
_conCmdInstance._lookAngle = camTx.Rotation;
// Assume that if someone uses a ConCmd to freecam, they also want to noclip.
// Colliding with walls is more of an official "photo mode" or "spectator mode" kind of thing.
_conCmdInstance.UseCollision = false;
}
}
Game
library
namespace Duccsoft;
/// <summary>
/// Defines the action names that are used to control the <see cref="Freecam"/>.
/// </summary>
public static class CameraActions
{
public const string MoveFast = "run";
public const string MoveSlow = "duck";
}
Debug: View Raw JSON Response
{
"TotalCount": 6,
"Files": [
{
"Ident": "duccsoft.libfreecam",
"Path": "Code/Freecam.Events.cs",
"FileName": "Freecam.Events.cs",
"PackageType": "library",
"CodeKind": "Game",
"AssetVersionId": 56341,
"Code": "using System;\r\n\r\nnamespace Duccsoft;\r\n\r\npublic partial class Freecam\r\n{\r\n\t/// <summary>\r\n\t/// Invoked whenever a freecam is enabled. The argument is the freecam that was enabled.\r\n\t/// </summary>\r\n\tpublic static event Action<Freecam> OnFreecamStart;\r\n\t/// <summary>\r\n\t/// Invoked whenever a freecam is disabled. The argument is the freecam that was disabled.\r\n\t/// </summary>\r\n\tpublic static event Action<Freecam> OnFreecamEnd;\r\n\r\n\t/// <summary>\r\n\t/// Removes all listeners from the static events of this class. Used by\r\n\t/// <see cref=\"CameraEventCleanupSystem\"/> to tidy things up between play sessions.\r\n\t/// </summary>\r\n\tpublic static void ClearInvocationLists()\r\n\t{\r\n\t\tOnFreecamStart = null;\r\n\t\tOnFreecamEnd = null;\r\n\t}\r\n}\r\n"
},
{
"Ident": "duccsoft.libfreecam",
"Path": "Code/Assembly.cs",
"FileName": "Assembly.cs",
"PackageType": "library",
"CodeKind": "Game",
"AssetVersionId": 56341,
"Code": "global using Sandbox;\r\nglobal using System.Collections.Generic;\r\nglobal using System.Linq;\r\n"
},
{
"Ident": "duccsoft.libfreecam",
"Path": "Code/Freecam.cs",
"FileName": "Freecam.cs",
"PackageType": "library",
"CodeKind": "Game",
"AssetVersionId": 56341,
"Code": "namespace Duccsoft;\r\n\r\n/// <summary>\r\n/// Enables the use of AnalogMove and AnalogLook to control the position and rotation \r\n/// of the main camera of the scene.\r\n/// </summary>\r\n[Title( \"Freecam\" )]\r\n[Category( \"Camera\" )]\r\n[Icon( \"control_camera\" )]\r\npublic sealed partial class Freecam : Component\r\n{\r\n\t/// <summary>\r\n\t/// How many units per second the camera will move at normal speed.\r\n\t/// </summary>\r\n\t[Property] public float Speed { get; set; } = 300f;\r\n\t/// <summary>\r\n\t/// A factor applied to movement speed whenever the crouch button is held.\r\n\t/// </summary>\r\n\t[Property] public float LowSpeedFactor { get; set; } = 0.25f;\r\n\t/// <summary>\r\n\t/// A factor applied to movement speed whenever the run button is held.\r\n\t/// </summary>\r\n\t[Property] public float HighSpeedFactor { get; set; } = 2.5f;\r\n\t/// <summary>\r\n\t/// If true, prevents the player from looking higher than directly up or lower\r\n\t/// than directly down. Prevents the camera from going upside-down and doing loop-de-loops.\r\n\t/// </summary>\r\n\t[Property] public bool ClampPitch { get; set; } = true;\r\n\t/// <summary>\r\n\t/// If true, the freecam will use a <see cref=\"CharacterController\"/> to handle collisions.\r\n\t/// If none exists already, one will be created.\r\n\t/// </summary>\r\n\t[Property] public bool UseCollision { get; set; } = true;\r\n\r\n\t/// <summary>\r\n\t/// The main scene camera. Will be refreshed each update.\r\n\t/// </summary>\r\n\tprivate CameraComponent _camera;\r\n\t/// <summary>\r\n\t/// The current angle/rotation that we are looking at.\r\n\t/// </summary>\r\n\tprivate Angles _lookAngle;\r\n\t/// <summary>\r\n\t/// If <see cref=\"UseCollision\"/> is true, this will be an instance of a <see cref=\"CharacterController\"/>\r\n\t/// on the same GameObject as this component.\r\n\t/// </summary>\r\n\tprivate CharacterController _controller;\r\n\r\n\tprotected override void OnEnabled()\r\n\t{\r\n\t\tOnFreecamStart?.Invoke( this );\r\n\t}\r\n\r\n\tprotected override void OnDisabled()\r\n\t{\r\n\t\tOnFreecamEnd?.Invoke( this );\r\n\t\t_controller?.Destroy();\r\n\t\t_controller = null;\r\n\t}\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tif ( _camera is null || !_camera.IsMainCamera )\r\n\t\t{\r\n\t\t\t_camera = Scene.Camera;\r\n\t\t}\r\n\t\tif ( !_camera.IsValid() )\r\n\t\t\treturn;\r\n\r\n\t\tRotateMainCamera();\r\n\t\tMoveMainCamera();\r\n\t}\r\n\r\n\tprotected override void OnFixedUpdate()\r\n\t{\r\n\t\tUpdatePosition();\r\n\t}\r\n\r\n\tprivate void RotateMainCamera()\r\n\t{\r\n\t\t_lookAngle += Input.AnalogLook;\r\n\t\tif ( ClampPitch )\r\n\t\t{\r\n\t\t\t_lookAngle.pitch = _lookAngle.pitch.Clamp( -89f, 89f );\r\n\t\t}\r\n\t\t_camera.Transform.Rotation = _lookAngle;\r\n\t}\r\n\r\n\t/// <summary>\r\n\t/// Move the main scene camera to roughly the position of this GameObject.\r\n\t/// </summary>\r\n\tprivate void MoveMainCamera()\r\n\t{\r\n\t\tif ( UseCollision )\r\n\t\t{\r\n\t\t\t// Put the camera up in to the center of the CharacterController's collision cube.\r\n\t\t\t_camera.Transform.Position = Transform.Position + Vector3.Up * 8f;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\t_camera.Transform.Position = Transform.Position;\r\n\t\t}\r\n\t}\r\n\r\n\t/// <summary>\r\n\t/// Use input to move this GameObject. If <see cref=\"UseCollision\"/> is true, a <see cref=\"CharacterController\"/>\r\n\t/// will be used to ensure that this GameObject doesn't clip through anything it shouldn't.\r\n\t/// </summary>\r\n\tprivate void UpdatePosition()\r\n\t{\r\n\t\tEnsureCollision();\r\n\t\t// Move using WASD or left thumbstick\r\n\t\tvar movement = Input.AnalogMove * Speed * GetSpeedFactor();\r\n\t\t// Move relative to the direction the camera is facing.\r\n\t\tmovement *= _lookAngle;\r\n\t\tif ( UseCollision )\r\n\t\t{\r\n\t\t\t_controller.Velocity = movement;\r\n\t\t\t_controller.Move();\r\n\t\t\t_controller.IsOnGround = false;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tTransform.Position += movement * Time.Delta;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void EnsureCollision()\r\n\t{\r\n\t\tif ( !UseCollision )\r\n\t\t\treturn;\r\n\r\n\t\t_controller ??= Components.GetOrCreate<CharacterController>();\r\n\t\t_controller.Radius = 8f;\r\n\t\t_controller.Height = 16f;\r\n\t}\r\n\r\n\tprivate float GetSpeedFactor()\r\n\t{\r\n\t\tvar speedFactor = 1f;\r\n\t\tif ( Input.Down( CameraActions.MoveSlow ) )\r\n\t\t{\r\n\t\t\tspeedFactor = LowSpeedFactor;\r\n\t\t}\r\n\t\telse if ( Input.Down( CameraActions.MoveFast ) )\r\n\t\t{\r\n\t\t\tspeedFactor = HighSpeedFactor;\r\n\t\t}\r\n\t\treturn speedFactor;\r\n\t}\r\n}\r\n"
},
{
"Ident": "duccsoft.libfreecam",
"Path": "Code/CameraEventCleanupSystem.cs",
"FileName": "CameraEventCleanupSystem.cs",
"PackageType": "library",
"CodeKind": "Game",
"AssetVersionId": 56341,
"Code": "namespace Duccsoft;\r\n\r\n/// <summary>\r\n/// On game shutdown, clears the invocation lists of the static events of <see cref=\"Freecam\"/>.\r\n/// This is to prevent duplicate event subscribers from piling up between play sessions.\r\n/// </summary>\r\npublic class CameraEventCleanupSystem : GameObjectSystem\r\n{\r\n\tpublic CameraEventCleanupSystem( Scene scene ) : base( scene ) \r\n\t{ \r\n\t\r\n\t} \r\n\r\n\tpublic override void Dispose()\r\n\t{\r\n\t\tbase.Dispose();\r\n\r\n\t\tFreecam.ClearInvocationLists();\r\n\t}\r\n}\r\n"
},
{
"Ident": "duccsoft.libfreecam",
"Path": "Code/Freecam.Commands.cs",
"FileName": "Freecam.Commands.cs",
"PackageType": "library",
"CodeKind": "Game",
"AssetVersionId": 56341,
"Code": "namespace Duccsoft;\r\n\r\npublic sealed partial class Freecam\r\n{\r\n\t/// <summary>\r\n\t/// Holds whatever instance of <see cref=\"Freecam\"/> may have been created by invoking <see cref=\"Toggle\"/>.\r\n\t/// </summary>\r\n\tprivate static Freecam _conCmdInstance;\r\n\t/// <summary>\r\n\t/// Holds references to whatever <see cref=\"Freecam\"/> instances were disabled by <see cref=\"Toggle\"/>.\r\n\t/// </summary>\r\n\tprivate static HashSet<Freecam> _disabledFreecams = new();\r\n\r\n\t[ConCmd(\"freecam\", Help = \"Toggle a mode where the camera can be moved and rotated freely.\")]\r\n\tpublic static void Toggle()\r\n\t{\r\n\t\tvar camera = Game.ActiveScene?.Camera;\r\n\t\tif ( !camera.IsValid() )\r\n\t\t\treturn;\r\n\r\n\t\t// If we were already using the freecam ConCmd...\r\n\t\tif ( _conCmdInstance?.Active == true )\r\n\t\t{\r\n\t\t\t// ...toggle it off by destroying its GameObject.\r\n\t\t\t_conCmdInstance?.GameObject?.Destroy();\r\n\t\t\t_conCmdInstance = null;\r\n\t\t\t// Reenable whatever non-ConCmd freecam we might have previously disabled.\r\n\t\t\tReenablePreviousFreecam();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// If there is an active freecam not created by this ConCmd, disable it.\r\n\t\tDisableActiveFreecams();\r\n\t\t// Make a new GameObject with a Freecam component.\r\n\t\tCreateFreecam();\r\n\t}\r\n\r\n\tprivate static void DisableActiveFreecams()\r\n\t{\r\n\t\t// Find any freecams that are currently active...\r\n\t\tvar freecams = Game.ActiveScene.GetAllComponents<Freecam>();\r\n\t\tif ( !freecams.Any() )\r\n\t\t\treturn;\r\n\r\n\t\tforeach ( var freecam in freecams )\r\n\t\t{\r\n\t\t\t// ...and turn them off.\r\n\t\t\tfreecam.Enabled = false;\r\n\t\t\t_disabledFreecams.Add( freecam );\r\n\t\t}\r\n\t\treturn;\r\n\t}\r\n\r\n\tprivate static void ReenablePreviousFreecam()\r\n\t{\r\n\t\t// Clean out any invalid freecams (e.g. GameObject or component was deleted)\r\n\t\tforeach( var freecam in _disabledFreecams.ToList() )\r\n\t\t{\r\n\t\t\tif ( !freecam.IsValid() )\r\n\t\t\t{\r\n\t\t\t\t_disabledFreecams.Remove( freecam );\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Find the first valid freecam we had previously disabled\r\n\t\tvar firstFreecam = _disabledFreecams.FirstOrDefault();\r\n\t\tif ( firstFreecam is null )\r\n\t\t\treturn;\r\n\r\n\t\tfirstFreecam.Enabled = true;\r\n\t\t_disabledFreecams.Remove( firstFreecam );\r\n\t}\r\n\r\n\tprivate static void CreateFreecam()\r\n\t{\r\n\t\t// There were no active freecams, so create one.\r\n\t\tvar freecamGo = new GameObject( true, \"ConCmd Freecam\" );\r\n\t\tvar camTx = Game.ActiveScene.Camera.Transform;\r\n\t\tfreecamGo.Transform.Position = camTx.Position;\r\n\t\t_conCmdInstance = freecamGo.Components.Create<Freecam>();\r\n\t\t_conCmdInstance._lookAngle = camTx.Rotation;\r\n\t\t// Assume that if someone uses a ConCmd to freecam, they also want to noclip.\r\n\t\t// Colliding with walls is more of an official \"photo mode\" or \"spectator mode\" kind of thing.\r\n\t\t_conCmdInstance.UseCollision = false;\r\n\t}\r\n}\r\n"
},
{
"Ident": "duccsoft.libfreecam",
"Path": "Code/CameraActions.cs",
"FileName": "CameraActions.cs",
"PackageType": "library",
"CodeKind": "Game",
"AssetVersionId": 56341,
"Code": "namespace Duccsoft;\r\n\r\n/// <summary>\r\n/// Defines the action names that are used to control the <see cref=\"Freecam\"/>.\r\n/// </summary>\r\npublic static class CameraActions\r\n{\r\n\tpublic const string MoveFast = \"run\";\r\n\tpublic const string MoveSlow = \"duck\";\r\n}\r\n"
}
]
}