working lasers

This commit is contained in:
2023-04-06 14:01:22 +02:00
parent 393d52feef
commit b4612b482f
55 changed files with 6286 additions and 18 deletions

View File

@@ -0,0 +1,81 @@
using NaughtyAttributes;
using UnityEngine;
namespace Station46.Modules.Laser.Scripts
{
public class Laser : MonoBehaviour
{
private const float MaxDistance = 1000;
public bool firing;
[BoxGroup("Internal")] [SerializeField] private Transform laserStart;
[BoxGroup("Internal")] [SerializeField] private LineRenderer laserLineRenderer;
private LaserReceiver CurrentReceiver
{
get => _currentReceiver;
set
{
if (value == null)
{
if (_currentReceiver)
{
_currentReceiver.Leave();
}
_currentReceiver = null;
}
else
{
if (_currentReceiver)
{
_currentReceiver.Leave();
}
_currentReceiver = value;
_currentReceiver.Hit();
}
}
}
private LaserReceiver _currentReceiver;
protected virtual void Start()
{
SetHitPosition();
}
protected virtual void Update()
{
laserLineRenderer.enabled = firing;
if (firing && Physics.Raycast(
laserStart.position,
transform.TransformDirection(Vector3.forward),
out var hit,
MaxDistance,
~0,
QueryTriggerInteraction.Ignore
))
{
SetHitPosition(hit.distance);
// check whether a receiver has been hit
var receiver = hit.transform.GetComponent<LaserReceiver>(); // may be null
if (receiver != CurrentReceiver)
{
CurrentReceiver = receiver;
}
}
else
{
SetHitPosition();
// hitting nothing
CurrentReceiver = null;
}
}
private void SetHitPosition(float distance = MaxDistance)
{
laserLineRenderer.SetPosition(1, Vector3.forward * distance);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4f534253f30947c3be8ac6e0924a9cde
timeCreated: 1631698595

View File

@@ -0,0 +1,6 @@
namespace Station46.Modules.Laser.Scripts
{
public class LaserEmitter : Laser
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 77f303a5ac191df499650cffd0903373
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
using System;
using UnityEngine;
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
namespace Station46.Modules.Laser.Scripts
{
public enum LaserEventType
{
Hit, Left
}
public static class LaserEventExtensions
{
public static string Description(this LaserEventType type, LaserReceiver receiver)
{
var action = type switch
{
LaserEventType.Hit => "hit",
LaserEventType.Left => "left",
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
return $"{receiver} was {action}";
}
}
public delegate void LaserEventHandler(LaserReceiver source, LaserEventType e);
public class LaserReceiver : MonoBehaviour
{
public event LaserEventHandler LaserEvent;
private int _hitCount;
/// <summary>
/// Use this when a laser has just been pointed at this.
/// </summary>
public void Hit()
{
if (_hitCount == 0)
{
OnLaserEvent(LaserEventType.Hit);
}
_hitCount++;
}
/// <summary>
/// Use this when a laser is no longer pointing at this.
/// </summary>
public void Leave()
{
if (_hitCount > 0)
{
_hitCount--;
}
if (_hitCount == 0)
{
OnLaserEvent(LaserEventType.Left);
}
}
private void OnLaserEvent(LaserEventType type)
{
Logger.Log(type.Description(this), LogType.PuzzleDetail);
LaserEvent?.Invoke(this, type);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c152de8a63080540ad136a98dd86dc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using UnityEngine;
namespace Station46.Modules.Laser.Scripts
{
[RequireComponent(typeof(LaserReceiver))]
public class LaserRedirector : Laser
{
private LaserReceiver _receiver;
private void Awake()
{
_receiver = GetComponent<LaserReceiver>();
_receiver.LaserEvent += (_, type) => firing = type == LaserEventType.Hit;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c9c178372010f034daf3f7ba81648a0e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: