components/attack.cs

Component attached to the player that handles melee attacks and first-person fist visuals. It finds the camera's fist renderer, toggles visibility based on first/third person, handles input to trace a short melee ray, applies damage to hit objects with a Health component, plays a punch sound, and sets animator bools on local and networked renderers via broadcast RPCs.

NetworkingFile Access
using Sandbox;
using System;

public class Attack : Component
{
	[Property] public SkinnedModelRenderer Model_Renderer {get;set;}
	[Property] public Player__Controller Player_Controller {get;set;}
	
	GameObject c;
	SkinnedModelRenderer VMDL;
	SoundEvent Punch;
	
	protected override void OnStart()
	{c = Scene.Camera.GameObject;
	VMDL = c.GetChild("fists").GetComponent<SkinnedModelRenderer>(true);
	Punch = ResourceLibrary.Get<SoundEvent>("prereqs/sound/effects/punch/punch.sound");}
	
	TimeUntil Next;
	Random random = new();
	
	protected override void OnUpdate()
	{
		if (IsProxy || Player_Controller.IsThirdPerson)
			VMDL.GameObject.Enabled = false;
		else VMDL.GameObject.Enabled = true;
		
		if (IsProxy)
			return;
		
		if (Input.Pressed("lmb") && Next)
		{ Next = .5f;
			var From = WorldPosition + Vector3.Zero.WithZ(Player_Controller.Offset);
			var To = From + c.WorldRotation * Vector3.Zero.WithX(64);
			
			SceneTraceResult Ray = Scene.Trace
			.Ray(From, To).WithTag("hider")
			.HitTriggersOnly().Run();
			
			if (Ray.Hit)
			{Ray.GameObject.GetComponent<Health>().Take(random.Next(25, 50));
			PlaySound(Ray.GameObject, Punch);}
			
			SkinnedModelRenderer_Set_Bool(Model_Renderer, "b_attack", true);
			VMDL.Set("b_attack", true);
		}
		
		if (Player_Controller.State == "run")
			VMDL.Set("move_bob", 1);
		else if (Player_Controller.State == "walk")
			VMDL.Set("move_bob", .5f);
		else if (Player_Controller.State == "idle")
			VMDL.Set("move_bob", 0);
		
		if (Player_Controller.State == "jump"
			|| Player_Controller.State == "fall")
			VMDL.Set("b_grounded", false);
		else VMDL.Set("b_grounded", true);
	}
	
	[Rpc.Broadcast]
	public void SkinnedModelRenderer_Set_Bool(SkinnedModelRenderer smr, string n, bool b)
	{smr.Set(n, b);}
	
	[Rpc.Broadcast]
	public void PlaySound(GameObject go, SoundEvent s)
	{go.PlaySound(s);}
protected override void OnDestroy() {if (!IsProxy) VMDL.GameObject.Enabled = false;} }