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.
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;} }