using System; using BlockSpace.Voxels; using UnityEngine; [DisallowMultipleComponent] public sealed class GetRotationBehavior : NodeBehavior { private bool evaluating; private void Start() { Recompute(); } private void Update() { Recompute(); } public override void OnInputValueChanged(string inputPortName, BSValue value) { Recompute(); } private void Recompute() { if (Node == null) { return; } if (evaluating) { ClearOutputsForCurrentTarget(); return; } evaluating = true; try { BSValue inputValue = GetInputValue("Group"); if (inputValue.Kind == BSValueKind.Player) { RecomputePlayer(inputValue.AsPlayerId()); } else if (base.IsAuthoritative) { if (!TryGetInputGroup("Group", out var group) || group == null) { ClearOutputsSynced(); return; } Vector3Int vector3Int = GridRotationUtility.Unpack(group.packedRotation); SetOutputValueIfChanged("Yaw", BSValue.FromNumber((float)vector3Int.y * 90f)); SetOutputValueIfChanged("Pitch", BSValue.FromNumber((float)vector3Int.x * 90f)); SetOutputValueIfChanged("Roll", BSValue.FromNumber((float)vector3Int.z * 90f)); } } catch (Exception exception) { Debug.LogException(exception, this); ClearOutputsForCurrentTarget(); } finally { evaluating = false; } } private void RecomputePlayer(int playerId) { Transform transform = NodePlayerUtility.ResolveHeadTransform(NodePlayerUtility.ResolvePlayer(playerId)); if (transform == null) { ClearOutputsLocal(); return; } Vector3 eulerAngles = transform.rotation.eulerAngles; SetLocalOutputValueIfChanged("Yaw", BSValue.FromNumber(eulerAngles.y)); SetLocalOutputValueIfChanged("Pitch", BSValue.FromNumber(eulerAngles.x)); SetLocalOutputValueIfChanged("Roll", BSValue.FromNumber(eulerAngles.z)); } private void ClearOutputsLocal() { SetLocalOutputValueIfChanged("Yaw", BSValue.None); SetLocalOutputValueIfChanged("Pitch", BSValue.None); SetLocalOutputValueIfChanged("Roll", BSValue.None); } private void ClearOutputsSynced() { SetOutputValueIfChanged("Yaw", BSValue.None); SetOutputValueIfChanged("Pitch", BSValue.None); SetOutputValueIfChanged("Roll", BSValue.None); } private void ClearOutputsForCurrentTarget() { if (GetInputValue("Group").Kind == BSValueKind.Player) { ClearOutputsLocal(); } else if (base.IsAuthoritative) { ClearOutputsSynced(); } } }