A Scene component that handles player "sight" and blinking UI. It finds UI components (eyelids and blink meter), manages a blink timer and animation, scans scene Renderers for objects tagged scp173 inside the camera frustum, plays a scare sound and marks those GameObjects as seen via broadcast RPCs, and throttles scare events.
using Sandbox;
using Sandbox.ui.eyelids;
using Sandbox.ui.blink_meter;
using System.Collections.Generic;
using System.Linq;
public class Sight : Component
{
CameraComponent c;
eyelids Eyelids;
blink_meter Blink_Meter;
GameObject UI;
SoundEvent Scare;
protected override void OnStart()
{if (IsProxy) return; c = Scene.Camera;
UI = Scene.Directory.FindbyName("UI");
Eyelids = UI.GetComponent<eyelids>();
Blink_Meter = UI.GetComponent<blink_meter>();
Scare = ResourceLibrary.Get<SoundEvent>("prereqs/sound/effects/scare/scare.sound");}
bool CanSee = true;
TimeUntil TimeUntil_Blink = 4;
bool CanScare = true;
protected override void OnUpdate()
{ if (IsProxy) return;
Blinking(); This();
}
async void Blinking()
{ Blink_Meter.w = (TimeUntil_Blink / 4 * 100).Clamp(0, 100);
if (Input.Pressed("b") || TimeUntil_Blink)
{ if (!CanSee) return; CanSee = false;
for (float i = Eyelids.o; i < 1; i += .3f)
{
Eyelids.o += .3f;
Eyelids.o = Eyelids.o.Clamp(0, 1);
await Task.Delay(1);
} await Task.Delay(50); TimeUntil_Blink = 4;
for (float i = Eyelids.o; i > 0; i -= .3f)
{
Eyelids.o -= .3f;
Eyelids.o = Eyelids.o.Clamp(0, 1);
await Task.Delay(1);
}
CanSee = true; }
}
void This()
{
var Renderers = new List<Renderer>(Scene.GetAll<Renderer>());
for (int i = Renderers.Count - 1; i >= 0; i--)
{if (!Renderers[i].Tags.Has("scp173"))
{Renderers.RemoveAt(i); continue;}}
var Frustum = c.GetFrustum();
foreach (var r in Renderers)
{
if (Frustum.IsInside(r.GameObject.GetBounds(), false) && CanSee)
{
if (!r.GameObject.Tags.Has("seen") && CanScare)
{GameObject.PlaySound(Scare); Throttle();}
Tags_Add(r.GameObject, "seen"); continue;
} Tags_Remove(r.GameObject, "seen");
}
}
async void Throttle()
{
CanScare = false;
await Task.Delay(10000);
CanScare = true;
}
[Rpc.Broadcast]
public void Tags_Add(GameObject go, string t)
{go.Tags.Add(t);}
[Rpc.Broadcast]
public void Tags_Remove(GameObject go, string t)
{go.Tags.Remove(t);}
}