202 lines
7.5 KiB
C#
202 lines
7.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using RebootKit.Engine.Main;
|
|
using RebootKit.Engine.Network;
|
|
using RebootKit.Engine.Simulation;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.Universal;
|
|
using Logger = RebootKit.Engine.Foundation.Logger;
|
|
|
|
namespace RebootReality.jelycho.Feedbacks {
|
|
struct CameraShakeFeedback {
|
|
public Vector3 center;
|
|
public float radius;
|
|
public float intensity;
|
|
public float timer;
|
|
|
|
public static int GetMaxBytes() {
|
|
return sizeof(float) * 3 + sizeof(float) * 3;
|
|
}
|
|
}
|
|
|
|
public class FeedbacksManagerActor : Actor {
|
|
static readonly Logger s_Logger = new Logger(nameof(FeedbacksManagerActor));
|
|
|
|
[SerializeField] Volume m_Volume;
|
|
|
|
[SerializeField] float m_QuickAttackIndicatorDuration = 0.3f;
|
|
[SerializeField] float m_QuickAttackIndicatorPaniniAppearSpeed = 2.0f;
|
|
[SerializeField] float m_QuickAttackIndicatorChromaticAppearSpeed = 2.0f;
|
|
[SerializeField] float m_QuickAttackIndicatorPaniniDisappearSpeed = 2.0f;
|
|
[SerializeField] float m_QuickAttackIndicatorChromaticDisappearSpeed = 2.0f;
|
|
[SerializeField] float m_QuickAttackIndicatorPaniniIntensity = 0.1f;
|
|
[SerializeField] float m_QuickAttackIndicatorChromaticIntensity = 1.0f;
|
|
|
|
PaniniProjection m_PaniniProjection;
|
|
ChromaticAberration m_ChromaticAberration;
|
|
|
|
float m_QuickAttackTimer;
|
|
|
|
List<CameraShakeFeedback> m_ActiveCameraShakes = new List<CameraShakeFeedback>();
|
|
|
|
void Awake() {
|
|
if (!m_Volume.profile.TryGet(out m_PaniniProjection)) {
|
|
s_Logger.Error($"Failed to find PaniniProjection on volume: {m_Volume.name}");
|
|
}
|
|
|
|
if (!m_Volume.profile.TryGet(out m_ChromaticAberration)) {
|
|
s_Logger.Error($"Failed to find ChromaticAberration on volume: {m_Volume.name}");
|
|
}
|
|
}
|
|
|
|
//
|
|
// @MARK: Camera shake
|
|
//
|
|
public void ShakeCamera(Vector3 center, float radius, float intensity, float duration) {
|
|
if (!RR.IsServer()) {
|
|
s_Logger.Error("ShakeCamera can only be called on the server.");
|
|
return;
|
|
}
|
|
|
|
FeedbacksCameraShakeEvent ev = new FeedbacksCameraShakeEvent {
|
|
Feedback = new CameraShakeFeedback {
|
|
center = center,
|
|
radius = radius,
|
|
intensity = intensity,
|
|
timer = duration
|
|
}
|
|
};
|
|
SendActorEvent((byte) FeedbacksManagerActorEvents.CameraShake, ref ev);
|
|
}
|
|
|
|
public float GetShakeIntensityForPosition(Vector3 position) {
|
|
if (m_ActiveCameraShakes.Count == 0) {
|
|
return 0.0f;
|
|
}
|
|
|
|
float intensity = 0.0f;
|
|
|
|
foreach (CameraShakeFeedback feedback in m_ActiveCameraShakes) {
|
|
if (feedback.radius <= 0.0f) {
|
|
continue;
|
|
}
|
|
|
|
float distSquared = math.distancesq(feedback.center, position);
|
|
float radiusSquared = feedback.radius * feedback.radius;
|
|
|
|
if (distSquared > radiusSquared) {
|
|
continue;
|
|
}
|
|
|
|
float feedbackIntensity = Mathf.Lerp(0.0f,
|
|
feedback.intensity,
|
|
1.0f - (distSquared / radiusSquared));
|
|
intensity = Mathf.Max(feedbackIntensity, intensity);
|
|
}
|
|
|
|
return intensity;
|
|
}
|
|
|
|
//
|
|
// @MARK: Local only
|
|
//
|
|
public void ShowQuickAttackIndicator() {
|
|
m_QuickAttackTimer = m_QuickAttackIndicatorDuration;
|
|
}
|
|
|
|
//
|
|
// @MARK: Actor
|
|
//
|
|
protected override IActorData CreateActorData() {
|
|
return new NoActorData();
|
|
}
|
|
|
|
public override void OnClientTick(float deltaTime) {
|
|
for (int i = m_ActiveCameraShakes.Count - 1; i >= 0; i--) {
|
|
CameraShakeFeedback feedback = m_ActiveCameraShakes[i];
|
|
feedback.timer -= deltaTime;
|
|
|
|
if (feedback.timer <= 0.0f) {
|
|
m_ActiveCameraShakes.RemoveAt(i);
|
|
continue;
|
|
}
|
|
|
|
m_ActiveCameraShakes[i] = feedback;
|
|
}
|
|
|
|
m_QuickAttackTimer -= Time.deltaTime;
|
|
if (m_QuickAttackTimer <= 0.0f) {
|
|
float chromaticIntensity = m_ChromaticAberration.intensity.value;
|
|
chromaticIntensity = Mathf.MoveTowards(chromaticIntensity,
|
|
0.0f,
|
|
deltaTime * m_QuickAttackIndicatorChromaticDisappearSpeed);
|
|
m_ChromaticAberration.intensity.value = chromaticIntensity;
|
|
|
|
float paniniIntensity = m_PaniniProjection.distance.value;
|
|
paniniIntensity = Mathf.MoveTowards(paniniIntensity,
|
|
0.0f,
|
|
deltaTime * m_QuickAttackIndicatorPaniniDisappearSpeed);
|
|
m_PaniniProjection.distance.value = paniniIntensity;
|
|
} else {
|
|
float chromaticIntensity = m_ChromaticAberration.intensity.value;
|
|
chromaticIntensity = Mathf.MoveTowards(chromaticIntensity,
|
|
m_QuickAttackIndicatorChromaticIntensity,
|
|
deltaTime * m_QuickAttackIndicatorChromaticAppearSpeed);
|
|
m_ChromaticAberration.intensity.value = chromaticIntensity;
|
|
|
|
float paniniIntensity = m_PaniniProjection.distance.value;
|
|
paniniIntensity = Mathf.MoveTowards(paniniIntensity,
|
|
m_QuickAttackIndicatorPaniniIntensity,
|
|
deltaTime * m_QuickAttackIndicatorPaniniAppearSpeed);
|
|
m_PaniniProjection.distance.value = paniniIntensity;
|
|
}
|
|
}
|
|
|
|
protected override void OnActorEventClient(ActorEvent actorEvent) {
|
|
FeedbacksManagerActorEvents feedbackEvent = (FeedbacksManagerActorEvents) actorEvent.EventID;
|
|
|
|
switch (feedbackEvent) {
|
|
|
|
case FeedbacksManagerActorEvents.CameraShake: {
|
|
FeedbacksCameraShakeEvent ev = new FeedbacksCameraShakeEvent();
|
|
DataSerializationUtils.Deserialize(actorEvent.Data, ref ev);
|
|
|
|
if (ev.Feedback.timer > 0.0f) {
|
|
m_ActiveCameraShakes.Add(ev.Feedback);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
enum FeedbacksManagerActorEvents : byte {
|
|
None = 0x00,
|
|
CameraShake = 0x01,
|
|
}
|
|
|
|
struct FeedbacksCameraShakeEvent : IActorData {
|
|
public CameraShakeFeedback Feedback;
|
|
|
|
public int GetMaxBytes() {
|
|
return CameraShakeFeedback.GetMaxBytes();
|
|
}
|
|
|
|
public void Serialize(NetworkBufferWriter writer) {
|
|
writer.Write(Feedback.center);
|
|
writer.Write(Feedback.radius);
|
|
writer.Write(Feedback.intensity);
|
|
writer.Write(Feedback.timer);
|
|
}
|
|
|
|
public void Deserialize(NetworkBufferReader reader) {
|
|
reader.Read(out Feedback.center);
|
|
reader.Read(out Feedback.radius);
|
|
reader.Read(out Feedback.intensity);
|
|
reader.Read(out Feedback.timer);
|
|
}
|
|
}
|
|
} |