probe rotation

This commit is contained in:
Mister_Nebula 2022-08-27 13:29:17 +01:00
parent 6c9bd967fb
commit 2b39f6b837
15 changed files with 332 additions and 12 deletions

Binary file not shown.

Binary file not shown.

View File

@ -247,7 +247,7 @@ internal class LightSensorPatches : QSBPatch
}
case LightSourceType.PROBE:
{
if (lightSource is QSBProbe qsbProbe)
if (lightSource is QSBSurveyorProbe qsbProbe)
{
var probe = qsbProbe;
if (probe != null &&
@ -350,7 +350,7 @@ internal class LightSensorPatches : QSBPatch
}
case LightSourceType.PROBE:
{
if (lightSource is not QSBProbe)
if (lightSource is not QSBSurveyorProbe)
{
var probe = Locator.GetProbe();
if (probe != null &&

View File

@ -15,7 +15,7 @@ namespace QSB.Player;
public partial class PlayerInfo
{
public GameObject ProbeBody { get; set; }
public QSBProbe Probe { get; set; }
public QSBSurveyorProbe Probe { get; set; }
public QSBFlashlight FlashLight => CameraBody == null ? null : CameraBody.GetComponentInChildren<QSBFlashlight>();
public QSBTool Signalscope => GetToolByType(ToolType.Signalscope);
public QSBTool Translator => GetToolByType(ToolType.Translator);

View File

@ -88,7 +88,7 @@ public static class QSBPlayerManager
public static (Flashlight LocalFlashlight, IEnumerable<QSBFlashlight> RemoteFlashlights) GetPlayerFlashlights()
=> (Locator.GetFlashlight(), PlayerList.Where(x => x.FlashLight != null).Select(x => x.FlashLight));
public static (SurveyorProbe LocalProbe, IEnumerable<QSBProbe> RemoteProbes) GetPlayerProbes()
public static (SurveyorProbe LocalProbe, IEnumerable<QSBSurveyorProbe> RemoteProbes) GetPlayerProbes()
=> (Locator.GetProbe(), PlayerList.Where(x => x.Probe != null).Select(x => x.Probe));
public static IEnumerable<ThrusterLightTracker> GetThrusterLightTrackers()

View File

@ -0,0 +1,32 @@
using QSB.Messaging;
using QSB.Player;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.Tools.ProbeTool.Messages;
internal class RotateProbeMessage : QSBMessage<(RotationType rotationType, Vector2 cameraRotation)>
{
public RotateProbeMessage(RotationType rotationType, Vector2 cameraRotation) : base((rotationType, cameraRotation)) { }
public override bool ShouldReceive => QSBWorldSync.AllObjectsReady;
public override void OnReceiveRemote()
{
var playerProbe = QSBPlayerManager.GetPlayer(From).Probe;
var rotatingCamera = playerProbe.GetRotatingCamera();
if (Data.rotationType == RotationType.Horizontal)
{
rotatingCamera.RotateHorizontal(Data.cameraRotation.x);
}
else if (Data.rotationType == RotationType.Vertical)
{
rotatingCamera.RotateVertical(Data.cameraRotation.y);
}
else
{
rotatingCamera.ResetRotation();
}
}
}

View File

@ -1,5 +1,9 @@
using HarmonyLib;
using QSB.Messaging;
using QSB.Patches;
using QSB.Tools.ProbeTool.Messages;
using QSB.Utility;
using UnityEngine;
namespace QSB.Tools.ProbeTool.Patches;
@ -37,4 +41,53 @@ internal class ProbeToolPatches : QSBPatch
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ProbeCamera), nameof(ProbeCamera.RotateHorizontal))]
public static bool RotateHorizontal(ProbeCamera __instance, float degrees)
{
if (__instance._id != ProbeCamera.ID.Rotating)
{
Debug.LogWarning("Tried to rotate a non-rotating ProbeCamera!", __instance);
return false;
}
__instance._cameraRotation.x += degrees;
__instance.transform.parent.localRotation = __instance._origParentLocalRotation * Quaternion.AngleAxis(__instance._cameraRotation.x, Vector3.up);
__instance.RaiseEvent(nameof(__instance.OnRotateCamera), __instance._cameraRotation);
new RotateProbeMessage(RotationType.Horizontal, __instance._cameraRotation).Send();
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ProbeCamera), nameof(ProbeCamera.RotateVertical))]
public static bool RotateVertical(ProbeCamera __instance, float degrees)
{
if (__instance._id != ProbeCamera.ID.Rotating)
{
Debug.LogWarning("Tried to rotate a non-rotating ProbeCamera!", __instance);
return false;
}
__instance._cameraRotation.y = Mathf.Clamp(__instance._cameraRotation.y + degrees, -90f, 0f);
__instance.transform.localRotation = __instance._origLocalRotation * Quaternion.AngleAxis(__instance._cameraRotation.y, Vector3.right);
__instance.RaiseEvent(nameof(__instance.OnRotateCamera), __instance._cameraRotation);
new RotateProbeMessage(RotationType.Vertical, __instance._cameraRotation).Send();
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ProbeCamera), nameof(ProbeCamera.ResetRotation))]
public static bool ResetRotation(ProbeCamera __instance)
{
if (__instance._id == ProbeCamera.ID.Rotating)
{
__instance._cameraRotation = Vector2.zero;
__instance.transform.localRotation = __instance._origLocalRotation;
__instance.transform.parent.localRotation = __instance._origParentLocalRotation;
new RotateProbeMessage(RotationType.Reset, __instance._cameraRotation).Send();
}
return false;
}
}

View File

@ -26,7 +26,7 @@ internal static class ProbeCreator
{
var REMOTE_Probe_Body = Object.Instantiate(GetPrefab());
var qsbProbe = REMOTE_Probe_Body.GetComponent<QSBProbe>();
var qsbProbe = REMOTE_Probe_Body.GetComponent<QSBSurveyorProbe>();
player.Probe = qsbProbe;
qsbProbe.SetOwner(player);

View File

@ -0,0 +1,92 @@
using UnityEngine;
namespace QSB.Tools.ProbeTool;
[RequireComponent(typeof(Animator))]
internal class QSBProbeAnimatorController : MonoBehaviour
{
private Animator _animator;
private QSBSurveyorProbe _probe;
[SerializeField]
private Transform _centerBone;
private Quaternion _startCenterBoneRotation = Quaternion.identity;
private Quaternion _targetCenterBoneRotation = Quaternion.identity;
private Quaternion _currentCenterBoneRotation = Quaternion.identity;
private float _rotationT;
private void Awake()
{
this._animator = base.GetComponent<Animator>();
this._probe = transform.parent.parent.parent.GetRequiredComponent<QSBSurveyorProbe>();
this._probe.OnLaunchProbe += this.OnProbeFire;
this._probe.OnAnchorProbe += this.OnProbeAnchor;
this._probe.OnRetrieveProbe += this.OnProbeReset;
}
private void Start()
{
this._probe.GetRotatingCamera().OnRotateCamera += this.OnRotateCamera;
base.enabled = false;
}
private void OnDestroy()
{
this._probe.OnLaunchProbe -= this.OnProbeFire;
this._probe.OnAnchorProbe -= this.OnProbeAnchor;
this._probe.OnRetrieveProbe -= this.OnProbeReset;
}
public Quaternion GetCenterBoneLocalRotation()
{
return this._centerBone.localRotation;
}
private void OnProbeFire()
{
this._animator.SetTrigger("Fire");
}
private void OnProbeAnchor()
{
this._animator.SetTrigger("Impact");
}
private void OnProbeReset()
{
this._animator.SetTrigger("Reset");
this._centerBone.localRotation = Quaternion.identity;
this._startCenterBoneRotation = Quaternion.identity;
this._targetCenterBoneRotation = Quaternion.identity;
this._currentCenterBoneRotation = Quaternion.identity;
this._rotationT = 0f;
base.enabled = false;
}
private void OnRotateCamera(Vector2 rotation)
{
this._startCenterBoneRotation = this._currentCenterBoneRotation;
this._targetCenterBoneRotation = Quaternion.AngleAxis(rotation.x, Vector3.up);
this._rotationT = 0f;
base.enabled = true;
}
private void LateUpdate()
{
this._rotationT += 10f * Time.deltaTime;
if (this._rotationT >= 1f)
{
this._rotationT = 1f;
this._currentCenterBoneRotation = this._targetCenterBoneRotation;
base.enabled = false;
}
else
{
float t = Mathf.Sqrt(Mathf.SmoothStep(0f, 1f, this._rotationT));
this._currentCenterBoneRotation = Quaternion.Lerp(this._startCenterBoneRotation, this._targetCenterBoneRotation, t);
}
this._centerBone.localRotation = this._currentCenterBoneRotation;
}
}

View File

@ -0,0 +1,94 @@
using UnityEngine;
namespace QSB.Tools.ProbeTool;
[RequireComponent(typeof(OWCamera))]
public class QSBProbeCamera : MonoBehaviour
{
[SerializeField]
private ProbeCamera.ID _id;
private OWCamera _camera;
private RenderTexture _snapshotTexture;
private NoiseImageEffect _noiseEffect;
private static OWCamera _lastSnapshotCamera;
private Quaternion _origLocalRotation;
private Quaternion _origParentLocalRotation;
private Vector2 _cameraRotation = Vector2.zero;
private QuantumMoon _quantumMoon;
private SandLevelController _sandLevelController;
public event ProbeCamera.RotateCameraEvent OnRotateCamera;
private void Awake()
{
_camera = this.GetRequiredComponent<OWCamera>();
_camera.enabled = false;
_noiseEffect = GetComponent<NoiseImageEffect>();
//this._snapshotTexture = ProbeCamera.GetSharedSnapshotTexture();
}
private void OnDestroy()
=> _snapshotTexture = null;
private void Start()
{
var astroObject = Locator.GetAstroObject(AstroObject.Name.QuantumMoon);
if (astroObject != null)
{
_quantumMoon = astroObject.GetComponent<QuantumMoon>();
}
}
public static OWCamera GetLastSnapshotCamera() =>
_lastSnapshotCamera;
public OWCamera GetOWCamera()
=> _camera;
public ProbeCamera.ID GetID()
=> _id;
public void SetSandLevelController(SandLevelController sandLevelController)
=> _sandLevelController = sandLevelController;
public bool HasInterference() =>
_id != ProbeCamera.ID.PreLaunch
//&& ((this._quantumMoon != null && this._quantumMoon.IsPlayerInside() != this._quantumMoon.IsProbeInside())
|| (_sandLevelController != null && _sandLevelController.IsPointBuried(transform.position));
//|| (Locator.GetCloakFieldController() != null && Locator.GetCloakFieldController().isPlayerInsideCloak != Locator.GetCloakFieldController().isProbeInsideCloak));
public RenderTexture TakeSnapshot()
{
_lastSnapshotCamera = _camera;
if (_noiseEffect != null)
{
_noiseEffect.enabled = HasInterference();
}
_camera.targetTexture = _snapshotTexture;
_camera.Render();
return _snapshotTexture;
}
public void RotateHorizontal(float cameraRotationX)
{
_cameraRotation.x = cameraRotationX;
transform.parent.localRotation = _origParentLocalRotation * Quaternion.AngleAxis(_cameraRotation.x, Vector3.up);
OnRotateCamera?.Invoke(_cameraRotation);
}
public void RotateVertical(float cameraRotationY)
{
_cameraRotation.y = cameraRotationY;
transform.localRotation = _origLocalRotation * Quaternion.AngleAxis(_cameraRotation.y, Vector3.right);
OnRotateCamera?.Invoke(_cameraRotation);
}
public void ResetRotation()
{
_cameraRotation = Vector2.zero;
transform.localRotation = _origLocalRotation;
transform.parent.localRotation = _origParentLocalRotation;
}
}

View File

@ -11,11 +11,11 @@ internal class QSBProbeEffects : MonoBehaviour
public OWAudioSource _anchorAudio;
public ParticleSystem _anchorParticles;
private QSBProbe _probe;
private QSBSurveyorProbe _probe;
private void Awake()
{
_probe = QSBWorldSync.GetUnityObjects<QSBProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
_probe = QSBWorldSync.GetUnityObjects<QSBSurveyorProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
if (_probe == null)
{
DebugLog.ToConsole($"Error - Couldn't find QSBProbe!", OWML.Common.MessageType.Error);

View File

@ -13,7 +13,7 @@ internal class QSBProbeLantern : MonoBehaviour
public OWEmissiveRenderer _emissiveRenderer;
public float _originalRange;
private QSBProbe _probe;
private QSBSurveyorProbe _probe;
private OWLight2 _light;
private float _fadeFraction;
private float _targetFade;
@ -23,7 +23,7 @@ internal class QSBProbeLantern : MonoBehaviour
private void Awake()
{
_probe = QSBWorldSync.GetUnityObjects<QSBProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
_probe = QSBWorldSync.GetUnityObjects<QSBSurveyorProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
if (_probe == null)
{
DebugLog.ToConsole($"Error - Couldn't find QSBProbe!", OWML.Common.MessageType.Error);

View File

@ -11,13 +11,13 @@ internal class QSBProbeSpotlight : MonoBehaviour
public float _fadeInLength = 1f;
public float _intensity;
private QSBProbe _probe;
private QSBSurveyorProbe _probe;
private OWLight2 _light;
private float _timer;
private void Awake()
{
_probe = QSBWorldSync.GetUnityObjects<QSBProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
_probe = QSBWorldSync.GetUnityObjects<QSBSurveyorProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
if (_probe == null)
{
DebugLog.ToConsole($"Error - Couldn't find QSBProbe!", OWML.Common.MessageType.Error);

View File

@ -4,7 +4,7 @@ using UnityEngine;
namespace QSB.Tools.ProbeTool;
public class QSBProbe : MonoBehaviour, ILightSource
public class QSBSurveyorProbe : MonoBehaviour, ILightSource
{
public delegate void SurveyorProbeEvent();
public delegate void RetrieveEvent(float retrieveLength);
@ -22,6 +22,9 @@ public class QSBProbe : MonoBehaviour, ILightSource
private GameObject _detectorObj;
private RulesetDetector _rulesetDetector;
private SingularityWarpEffect _warpEffect;
private QSBProbeCamera _forwardCam;
private QSBProbeCamera _reverseCam;
private QSBProbeCamera _rotatingCam;
private bool _isRetrieving;
private PlayerInfo _owner;
private bool _anchored;
@ -30,6 +33,21 @@ public class QSBProbe : MonoBehaviour, ILightSource
public RulesetDetector GetRulesetDetector()
=> _rulesetDetector;
public QSBProbeCamera GetForwardCamera()
{
return _forwardCam;
}
public QSBProbeCamera GetReverseCamera()
{
return _reverseCam;
}
public QSBProbeCamera GetRotatingCamera()
{
return _rotatingCam;
}
private void Awake()
{
_detectorObj = GetComponentInChildren<RulesetDetector>().gameObject;
@ -37,6 +55,23 @@ public class QSBProbe : MonoBehaviour, ILightSource
_warpEffect = GetComponentInChildren<SingularityWarpEffect>();
_warpEffect.OnWarpComplete += OnWarpComplete;
_isRetrieving = false;
var probeCameras = GetComponentsInChildren<QSBProbeCamera>();
for (var i = 0; i < probeCameras.Length; i++)
{
if (probeCameras[i].GetID() == ProbeCamera.ID.Forward)
{
_forwardCam = probeCameras[i];
}
else if (probeCameras[i].GetID() == ProbeCamera.ID.Reverse)
{
_reverseCam = probeCameras[i];
}
else if (probeCameras[i].GetID() == ProbeCamera.ID.Rotating)
{
_rotatingCam = probeCameras[i];
}
}
}
private void Start()
@ -127,6 +162,9 @@ public class QSBProbe : MonoBehaviour, ILightSource
case ProbeEvent.Unanchor:
_anchored = false;
_owner.ProbeActive = true; // just in case it was missed
_forwardCam.SetSandLevelController(null);
_reverseCam.SetSandLevelController(null);
_rotatingCam.SetSandLevelController(null);
OnUnanchorProbe();
break;
case ProbeEvent.Retrieve:
@ -165,6 +203,9 @@ public class QSBProbe : MonoBehaviour, ILightSource
_lightSourceVol.SetVolumeActivation(false);
gameObject.SetActive(false);
_isRetrieving = false;
_forwardCam.SetSandLevelController(null);
_reverseCam.SetSandLevelController(null);
_rotatingCam.SetSandLevelController(null);
}
public void OnStartRetrieve(float duration)

View File

@ -0,0 +1,8 @@
namespace QSB.Tools.ProbeTool;
public enum RotationType
{
Horizontal,
Vertical,
Reset
}