mass commit of laziness

This commit is contained in:
NotAKidoS 2025-12-28 20:30:00 -06:00
parent ce992c70ee
commit 6d4fc549d9
167 changed files with 5471 additions and 675 deletions

View file

@ -3,22 +3,6 @@
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
[RequireComponent(typeof(Camera))]
public class DepthTextureFix : MonoBehaviour
{

View file

@ -1,8 +1,6 @@
using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.InteractionSystem.Base;
using ABI_RC.Systems.InputManagement;
using UnityEngine;
using UnityEngine.Serialization;
namespace ABI_RC.Core.Player.Interaction
{

View file

@ -1,214 +1,214 @@
using ABI_RC.Core.Player.Interaction.RaycastImpl;
using ABI_RC.Core.Savior;
using ABI_RC.Systems.InputManagement;
using UnityEngine;
namespace ABI_RC.Core.Player.Interaction
{
public class CVRPlayerInteractionManager : MonoBehaviour
{
#region Singleton
public static CVRPlayerInteractionManager Instance { get; private set; }
#endregion Singleton
#region Serialized Fields
[Header("Hand Components")]
[SerializeField] private CVRPlayerHand handVrLeft;
[SerializeField] private CVRPlayerHand handVrRight;
[SerializeField] private CVRPlayerHand handDesktopRight; // Desktop does not have a left hand
[Header("Raycast Transforms")]
[SerializeField] private Transform raycastTransformVrRight;
[SerializeField] private Transform raycastTransformVrLeft;
[SerializeField] private Transform raycastTransformDesktopRight;
[Header("Settings")]
[SerializeField] private bool interactionEnabled = true;
[SerializeField] private LayerMask interactionLayerMask = -1; // Default to all layers, will be filtered
#endregion Serialized Fields
#region Properties
private CVRPlayerHand _rightHand;
private CVRPlayerHand _leftHand;
private CVRPlayerRaycaster _rightRaycaster;
private CVRPlayerRaycaster _leftRaycaster;
private CVRRaycastResult _rightRaycastResult;
private CVRRaycastResult _leftRaycastResult;
// Input handler
private CVRPlayerInputHandler _inputHandler;
// Interaction flags
public bool InteractionEnabled
{
get => interactionEnabled;
set => interactionEnabled = value;
}
#endregion Properties
#region Unity Events
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
// Create the input handler
_inputHandler = gameObject.AddComponent<CVRPlayerInputHandler>();
}
private void Start()
{
// Setup interaction for current device mode
SetupInteractionForDeviceMode();
// Listen for VR mode changes
MetaPort.Instance.onVRModeSwitch.AddListener(SetupInteractionForDeviceMode);
}
private void Update()
{
if (!interactionEnabled)
return;
// Process right hand
if (_rightRaycaster != null)
{
// Determine raycast flags based on current mode
CVRPlayerRaycaster.RaycastFlags flags = DetermineRaycastFlags(_rightHand);
// Get raycast results
_rightRaycastResult = _rightRaycaster.GetRaycastResults(flags);
// Process input based on raycast results
_inputHandler.ProcessInput(CVRHand.Right, _rightRaycastResult);
}
// Process left hand (if available)
if (_leftRaycaster != null)
{
// Determine raycast flags based on current mode
CVRPlayerRaycaster.RaycastFlags flags = DetermineRaycastFlags(_leftHand);
// Get raycast results
_leftRaycastResult = _leftRaycaster.GetRaycastResults(flags);
// Process input based on raycast results
_inputHandler.ProcessInput(CVRHand.Left, _leftRaycastResult);
}
}
private void OnDestroy()
{
// Clean up event listener
if (MetaPort.Instance != null)
MetaPort.Instance.onVRModeSwitch.RemoveListener(SetupInteractionForDeviceMode);
}
#endregion Unity Events
#region Public Methods
/// <summary>
/// Register a custom tool mode
/// </summary>
public void RegisterCustomToolMode(System.Action<CVRHand, CVRRaycastResult, InputState> callback)
{
_inputHandler.RegisterCustomTool(callback);
}
/// <summary>
/// Unregister the current custom tool mode
/// </summary>
public void UnregisterCustomToolMode()
{
_inputHandler.UnregisterCustomTool();
}
/// <summary>
/// Set the interaction mode
/// </summary>
public void SetInteractionMode(CVRPlayerInputHandler.InteractionMode mode)
{
_inputHandler.SetInteractionMode(mode);
}
/// <summary>
/// Get the raycast result for a specific hand
/// </summary>
public CVRRaycastResult GetRaycastResult(CVRHand hand)
{
return hand == CVRHand.Left ? _leftRaycastResult : _rightRaycastResult;
}
#endregion Public Methods
#region Private Methods
private void SetupInteractionForDeviceMode()
{
bool isVr = MetaPort.Instance.isUsingVr;
if (isVr)
{
// VR mode
_rightHand = handVrRight;
_leftHand = handVrLeft;
// VR uses the controller transform for raycasting
_rightRaycaster = new CVRPlayerRaycasterTransform(raycastTransformVrRight);
_leftRaycaster = new CVRPlayerRaycasterTransform(raycastTransformVrLeft);
}
else
{
// Desktop mode
_rightHand = handDesktopRight;
_leftHand = null;
// Desktop uses the mouse position for raycasting when unlocked
Camera desktopCamera = PlayerSetup.Instance.desktopCam;
_rightRaycaster = new CVRPlayerRaycasterMouse(raycastTransformDesktopRight, desktopCamera);
_leftRaycaster = null;
}
// Set the layer mask for raycasters
if (_rightRaycaster != null)
_rightRaycaster.SetLayerMask(interactionLayerMask);
if (_leftRaycaster != null)
_leftRaycaster.SetLayerMask(interactionLayerMask);
}
private static CVRPlayerRaycaster.RaycastFlags DetermineRaycastFlags(CVRPlayerHand hand)
{
// Default to all flags
CVRPlayerRaycaster.RaycastFlags flags = CVRPlayerRaycaster.RaycastFlags.All;
// Check if hand is holding a pickup
if (hand != null && hand.IsHoldingObject)
{
// When holding an object, only check for COHTML interaction
flags = CVRPlayerRaycaster.RaycastFlags.CohtmlInteract;
}
// Could add more conditional flag adjustments here based on the current mode
// For example, in a teleport tool mode, you might only want world hits
return flags;
}
#endregion Private Methods
}
}
// using ABI_RC.Core.Player.Interaction.RaycastImpl;
// using ABI_RC.Core.Savior;
// using ABI_RC.Systems.InputManagement;
// using UnityEngine;
//
// namespace ABI_RC.Core.Player.Interaction
// {
// public class CVRPlayerInteractionManager : MonoBehaviour
// {
// #region Singleton
//
// public static CVRPlayerInteractionManager Instance { get; private set; }
//
// #endregion Singleton
//
// #region Serialized Fields
//
// [Header("Hand Components")]
// [SerializeField] private CVRPlayerHand handVrLeft;
// [SerializeField] private CVRPlayerHand handVrRight;
// [SerializeField] private CVRPlayerHand handDesktopRight; // Desktop does not have a left hand
//
// [Header("Raycast Transforms")]
// [SerializeField] private Transform raycastTransformVrRight;
// [SerializeField] private Transform raycastTransformVrLeft;
// [SerializeField] private Transform raycastTransformDesktopRight;
//
// [Header("Settings")]
// [SerializeField] private bool interactionEnabled = true;
// [SerializeField] private LayerMask interactionLayerMask = -1; // Default to all layers, will be filtered
//
// #endregion Serialized Fields
//
// #region Properties
//
// private CVRPlayerHand _rightHand;
// private CVRPlayerHand _leftHand;
//
// private CVRPlayerRaycaster _rightRaycaster;
// private CVRPlayerRaycaster _leftRaycaster;
//
// private CVRRaycastResult _rightRaycastResult;
// private CVRRaycastResult _leftRaycastResult;
//
// // Input handler
// private CVRPlayerInputHandler _inputHandler;
//
// // Interaction flags
// public bool InteractionEnabled
// {
// get => interactionEnabled;
// set => interactionEnabled = value;
// }
//
// #endregion Properties
//
// #region Unity Events
//
// private void Awake()
// {
// if (Instance != null && Instance != this)
// {
// Destroy(gameObject);
// return;
// }
// Instance = this;
//
// // Create the input handler
// _inputHandler = gameObject.AddComponent<CVRPlayerInputHandler>();
// }
//
// private void Start()
// {
// // Setup interaction for current device mode
// SetupInteractionForDeviceMode();
//
// // Listen for VR mode changes
// MetaPort.Instance.onVRModeSwitch.AddListener(SetupInteractionForDeviceMode);
// }
//
// private void Update()
// {
// if (!interactionEnabled)
// return;
//
// // Process right hand
// if (_rightRaycaster != null)
// {
// // Determine raycast flags based on current mode
// CVRPlayerRaycaster.RaycastFlags flags = DetermineRaycastFlags(_rightHand);
//
// // Get raycast results
// _rightRaycastResult = _rightRaycaster.GetRaycastResults(flags);
//
// // Process input based on raycast results
// _inputHandler.ProcessInput(CVRHand.Right, _rightRaycastResult);
// }
//
// // Process left hand (if available)
// if (_leftRaycaster != null)
// {
// // Determine raycast flags based on current mode
// CVRPlayerRaycaster.RaycastFlags flags = DetermineRaycastFlags(_leftHand);
//
// // Get raycast results
// _leftRaycastResult = _leftRaycaster.GetRaycastResults(flags);
//
// // Process input based on raycast results
// _inputHandler.ProcessInput(CVRHand.Left, _leftRaycastResult);
// }
// }
//
// private void OnDestroy()
// {
// // Clean up event listener
// if (MetaPort.Instance != null)
// MetaPort.Instance.onVRModeSwitch.RemoveListener(SetupInteractionForDeviceMode);
// }
//
// #endregion Unity Events
//
// #region Public Methods
//
// /// <summary>
// /// Register a custom tool mode
// /// </summary>
// public void RegisterCustomToolMode(System.Action<CVRHand, CVRRaycastResult, InputState> callback)
// {
// _inputHandler.RegisterCustomTool(callback);
// }
//
// /// <summary>
// /// Unregister the current custom tool mode
// /// </summary>
// public void UnregisterCustomToolMode()
// {
// _inputHandler.UnregisterCustomTool();
// }
//
// /// <summary>
// /// Set the interaction mode
// /// </summary>
// public void SetInteractionMode(CVRPlayerInputHandler.InteractionMode mode)
// {
// _inputHandler.SetInteractionMode(mode);
// }
//
// /// <summary>
// /// Get the raycast result for a specific hand
// /// </summary>
// public CVRRaycastResult GetRaycastResult(CVRHand hand)
// {
// return hand == CVRHand.Left ? _leftRaycastResult : _rightRaycastResult;
// }
//
// #endregion Public Methods
//
// #region Private Methods
//
// private void SetupInteractionForDeviceMode()
// {
// bool isVr = MetaPort.Instance.isUsingVr;
//
// if (isVr)
// {
// // VR mode
// _rightHand = handVrRight;
// _leftHand = handVrLeft;
//
// // VR uses the controller transform for raycasting
// _rightRaycaster = new CVRPlayerRaycasterTransform(raycastTransformVrRight);
// _leftRaycaster = new CVRPlayerRaycasterTransform(raycastTransformVrLeft);
// }
// else
// {
// // Desktop mode
// _rightHand = handDesktopRight;
// _leftHand = null;
//
// // Desktop uses the mouse position for raycasting when unlocked
// Camera desktopCamera = PlayerSetup.Instance.desktopCam;
// _rightRaycaster = new CVRPlayerRaycasterMouse(raycastTransformDesktopRight, desktopCamera);
// _leftRaycaster = null;
// }
//
// // Set the layer mask for raycasters
// if (_rightRaycaster != null)
// _rightRaycaster.SetLayerMask(interactionLayerMask);
//
// if (_leftRaycaster != null)
// _leftRaycaster.SetLayerMask(interactionLayerMask);
// }
//
// private static CVRPlayerRaycaster.RaycastFlags DetermineRaycastFlags(CVRPlayerHand hand)
// {
// // Default to all flags
// CVRPlayerRaycaster.RaycastFlags flags = CVRPlayerRaycaster.RaycastFlags.All;
//
// // Check if hand is holding a pickup
// if (hand != null && hand.IsHoldingObject)
// {
// // When holding an object, only check for COHTML interaction
// flags = CVRPlayerRaycaster.RaycastFlags.CohtmlInteract;
// }
//
// // Could add more conditional flag adjustments here based on the current mode
// // For example, in a teleport tool mode, you might only want world hits
//
// return flags;
// }
//
// #endregion Private Methods
// }
// }

View file

@ -1,121 +1,121 @@
using ABI_RC.Core.Base;
using ABI_RC.Core.Player;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace NAK.SuperAwesomeMod.Components
{
public class CVRCanvasWrapper : MonoBehaviour
{
public bool IsInteractable = true;
public float MaxInteractDistance = 10f;
private Canvas _canvas;
private GraphicRaycaster _graphicsRaycaster;
private static readonly List<RaycastResult> _raycastResults = new();
private static readonly PointerEventData _pointerEventData = new(EventSystem.current);
private static Selectable _workingSelectable;
private Camera _camera;
private RectTransform _rectTransform;
#region Unity Events
private void Awake()
{
if (!TryGetComponent(out _canvas)
|| _canvas.renderMode != RenderMode.WorldSpace)
{
IsInteractable = false;
return;
}
_rectTransform = _canvas.GetComponent<RectTransform>();
}
private void Start()
{
_graphicsRaycaster = _canvas.gameObject.AddComponent<GraphicRaycaster>();
_camera = PlayerSetup.Instance.activeCam;
_canvas.worldCamera = _camera;
}
#endregion Unity Events
#region Public Methods
public bool GetGraphicsHit(Ray worldRay, out RaycastResult result)
{
result = default;
if (!IsInteractable || _camera == null) return false;
// Get the plane of the canvas
Plane canvasPlane = new(transform.forward, transform.position);
// Find where the ray intersects the canvas plane
if (!canvasPlane.Raycast(worldRay, out float distance))
return false;
// Get the world point of intersection
Vector3 worldHitPoint = worldRay.origin + worldRay.direction * distance;
// Check if hit point is within max interaction distance
if (Vector3.Distance(worldRay.origin, worldHitPoint) > MaxInteractDistance)
return false;
// Check if hit point is within canvas bounds
Vector3 localHitPoint = transform.InverseTransformPoint(worldHitPoint);
Rect canvasRect = _rectTransform.rect;
if (!canvasRect.Contains(new Vector2(localHitPoint.x, localHitPoint.y)))
return false;
// Convert world hit point to screen space
Vector2 screenPoint = _camera.WorldToScreenPoint(worldHitPoint);
// Update pointer event data
_pointerEventData.position = screenPoint;
_pointerEventData.delta = Vector2.zero;
// Clear previous results and perform raycast
_raycastResults.Clear();
_graphicsRaycaster.Raycast(_pointerEventData, _raycastResults);
// Early out if no hits
if (_raycastResults.Count == 0)
{
//Debug.Log($"No hits on canvas {_canvas.name}");
return false;
}
// Find first valid interactive UI element
foreach (RaycastResult hit in _raycastResults)
{
if (!hit.isValid)
{
//Debug.Log($"Invalid hit on canvas {_canvas.name}");
continue;
}
// Check if the hit object has a Selectable component and is interactable
GameObject hitObject = hit.gameObject;
if (!hitObject.TryGetComponent(out _workingSelectable)
|| !_workingSelectable.interactable)
{
//Debug.Log($"Non-interactable hit on canvas {_canvas.name} - {hitObject.name}");
continue;
}
//Debug.Log($"Hit on canvas {_canvas.name} with {hitObject.name}");
result = hit;
return true;
}
return false;
}
#endregion Public Methods
}
}
// using ABI_RC.Core.Base;
// using ABI_RC.Core.Player;
// using UnityEngine;
// using UnityEngine.EventSystems;
// using UnityEngine.UI;
//
// namespace NAK.SuperAwesomeMod.Components
// {
// public class CVRCanvasWrapper : MonoBehaviour
// {
// public bool IsInteractable = true;
// public float MaxInteractDistance = 10f;
//
// private Canvas _canvas;
// private GraphicRaycaster _graphicsRaycaster;
// private static readonly List<RaycastResult> _raycastResults = new();
// private static readonly PointerEventData _pointerEventData = new(EventSystem.current);
//
// private static Selectable _workingSelectable;
// private Camera _camera;
// private RectTransform _rectTransform;
//
// #region Unity Events
//
// private void Awake()
// {
// if (!TryGetComponent(out _canvas)
// || _canvas.renderMode != RenderMode.WorldSpace)
// {
// IsInteractable = false;
// return;
// }
//
// _rectTransform = _canvas.GetComponent<RectTransform>();
// }
//
// private void Start()
// {
// _graphicsRaycaster = _canvas.gameObject.AddComponent<GraphicRaycaster>();
// _camera = PlayerSetup.Instance.activeCam;
// _canvas.worldCamera = _camera;
// }
//
// #endregion Unity Events
//
// #region Public Methods
//
// public bool GetGraphicsHit(Ray worldRay, out RaycastResult result)
// {
// result = default;
//
// if (!IsInteractable || _camera == null) return false;
//
// // Get the plane of the canvas
// Plane canvasPlane = new(transform.forward, transform.position);
//
// // Find where the ray intersects the canvas plane
// if (!canvasPlane.Raycast(worldRay, out float distance))
// return false;
//
// // Get the world point of intersection
// Vector3 worldHitPoint = worldRay.origin + worldRay.direction * distance;
//
// // Check if hit point is within max interaction distance
// if (Vector3.Distance(worldRay.origin, worldHitPoint) > MaxInteractDistance)
// return false;
//
// // Check if hit point is within canvas bounds
// Vector3 localHitPoint = transform.InverseTransformPoint(worldHitPoint);
// Rect canvasRect = _rectTransform.rect;
// if (!canvasRect.Contains(new Vector2(localHitPoint.x, localHitPoint.y)))
// return false;
//
// // Convert world hit point to screen space
// Vector2 screenPoint = _camera.WorldToScreenPoint(worldHitPoint);
//
// // Update pointer event data
// _pointerEventData.position = screenPoint;
// _pointerEventData.delta = Vector2.zero;
//
// // Clear previous results and perform raycast
// _raycastResults.Clear();
// _graphicsRaycaster.Raycast(_pointerEventData, _raycastResults);
//
// // Early out if no hits
// if (_raycastResults.Count == 0)
// {
// //Debug.Log($"No hits on canvas {_canvas.name}");
// return false;
// }
//
// // Find first valid interactive UI element
// foreach (RaycastResult hit in _raycastResults)
// {
// if (!hit.isValid)
// {
// //Debug.Log($"Invalid hit on canvas {_canvas.name}");
// continue;
// }
//
// // Check if the hit object has a Selectable component and is interactable
// GameObject hitObject = hit.gameObject;
// if (!hitObject.TryGetComponent(out _workingSelectable)
// || !_workingSelectable.interactable)
// {
// //Debug.Log($"Non-interactable hit on canvas {_canvas.name} - {hitObject.name}");
// continue;
// }
//
// //Debug.Log($"Hit on canvas {_canvas.name} with {hitObject.name}");
//
// result = hit;
// return true;
// }
//
// return false;
// }
//
// #endregion Public Methods
// }
// }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,85 @@
using ABI_RC.Core;
using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.Player;
using ABI_RC.Core.Savior;
using ABI_RC.Systems.InputManagement;
using UnityEngine;
using UnityEngine.EventSystems;
namespace NAK.SuperAwesomeMod.Interaction;
[DefaultExecutionOrder(1000)]
public class CustomBaseInput : BaseInput
{
private Vector2 mousePositionCache;
#region Input Overrides
public override Vector2 mousePosition => Input.mousePosition;
public override bool GetMouseButton(int button)
=> button == (int)CVRHand.Right
? CVRInputManager.Instance.interactLeftValue > 0.75f
: CVRInputManager.Instance.interactRightValue > 0.75f;
public override bool GetMouseButtonDown(int button)
=> button == (int)CVRHand.Right
? CVRInputManager.Instance.interactLeftDown
: CVRInputManager.Instance.interactRightDown;
public override Vector2 mouseScrollDelta => Vector2.zero;
public override float GetAxisRaw(string axisName)
{
return axisName switch
{
"Mouse ScrollWheel" => CVRInputManager.Instance.scrollValue,
"Horizontal" => CVRInputManager.Instance.movementVector.x,
"Vertical" => CVRInputManager.Instance.movementVector.y,
_ => 0f
};
}
public override bool GetButtonDown(string buttonName)
{
return buttonName switch
{
"Mouse ScrollWheel" => CVRInputManager.Instance.scrollValue > 0.1f,
"Horizontal" => CVRInputManager.Instance.movementVector.x > 0.5f,
"Vertical" => CVRInputManager.Instance.movementVector.y > 0.5f,
_ => false
};
}
#endregion Input Overrides
private CVRHand lastInteractHand;
private void Update()
{
if (!MetaPort.Instance.isUsingVr)
{
mousePositionCache = Input.mousePosition;
return;
}
ControllerRay leftRay = PlayerSetup.Instance.vrRayLeft;
ControllerRay rightRay = PlayerSetup.Instance.vrRayRight;
if (leftRay._interactDown) lastInteractHand = leftRay.hand;
if (rightRay._interactDown) lastInteractHand = rightRay.hand;
Camera vrCamera = PlayerSetup.Instance.vrCam;
// transform the raycast position to screen position
Vector3 hitPoint = lastInteractHand == CVRHand.Left
? leftRay.HitPoint
: rightRay.HitPoint;
Vector3 screenPoint = vrCamera.WorldToScreenPoint(hitPoint);
screenPoint.x = Mathf.Clamp(screenPoint.x, 0, Screen.width);
screenPoint.y = Mathf.Clamp(screenPoint.y, 0, Screen.height);
mousePositionCache = new Vector2(screenPoint.x, screenPoint.y);
}
}

View file

@ -0,0 +1,67 @@
using UnityEngine;
using UnityEngine.EventSystems;
namespace NAK.SuperAwesomeMod.Interaction;
public class CustomInputModule : StandaloneInputModule
{
bool meow = false;
#region Unity Events
protected override void Start()
{
base.Start();
m_InputOverride = gameObject.AddComponent<CustomBaseInput>();
// Disable other event systems in the scene
DisableOtherEventSystems();
}
#endregion
#region Overrides
public override void Process()
{
CursorLockMode currentLockState = Cursor.lockState;
Cursor.lockState = CursorLockMode.None;
base.Process();
Cursor.lockState = currentLockState;
}
protected override MouseState GetMousePointerEventData(int id)
{
MouseState pointerEventData = base.GetMousePointerEventData(id);
MouseButtonEventData leftEventData = pointerEventData.GetButtonState(PointerEventData.InputButton.Left).eventData;
RaycastResult pointerRaycast = leftEventData.buttonData.pointerCurrentRaycast;
if (meow) leftEventData.buttonData.pointerCurrentRaycast = new RaycastResult();
return pointerEventData;
}
#endregion Overrides
#region Private Methods
private void DisableOtherEventSystems()
{
EventSystem thisEventSystem = GetComponent<EventSystem>();
EventSystem[] systems = FindObjectsOfType<EventSystem>();
foreach (EventSystem system in systems)
{
if (system.gameObject.name == "UniverseLibCanvas") continue;
if (system != thisEventSystem)
{
system.enabled = false;
}
}
}
#endregion Private Methods
}

View file

@ -1,9 +1,7 @@
using ABI_RC.Core.InteractionSystem.Base;
using ABI_RC.Core.UI;
using ABI.CCK.Components;
using NAK.SuperAwesomeMod.Components;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace ABI_RC.Core.Player.Interaction.RaycastImpl
@ -108,7 +106,8 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
// Check if there are pickups or interactables in immediate proximity
if ((flags & RaycastFlags.ProximityInteract) != 0)
{
ProcessProximityHits(ray, ref result); // TODO: Offset origin to center of palm based on hand type
Ray proximityRay = GetProximityRayFromImpl();
ProcessProximityHits(proximityRay, ref result);
if (result.isProximityHit)
return result;
}
@ -150,7 +149,7 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
int proximityHits = Physics.SphereCastNonAlloc(
ray.origin,
RAYCAST_SPHERE_RADIUS,
Vector3.up,
ray.direction,
_hits,
0.001f,
_layerMask,
@ -313,6 +312,7 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
result.hitInteractable = _workingInteractable;
hitValidComponent = true;
}
if (_workingGameObject.TryGetComponent(out _workingPickupable)
&& _workingPickupable.CanPickup
&& IsCVRPickupableWithinRange(_workingPickupable, hit))
@ -343,6 +343,7 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
#region Protected Methods
protected abstract Ray GetRayFromImpl();
protected abstract Ray GetProximityRayFromImpl();
#endregion Protected Methods
@ -375,10 +376,10 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
return hit.distance <= pickupable.MaxGrabDistance;
}
private static bool IsCVRCanvasWrapperWithinRange(CVRCanvasWrapper canvasWrapper, RaycastHit hit)
{
return hit.distance <= canvasWrapper.MaxInteractDistance;
}
// private static bool IsCVRCanvasWrapperWithinRange(CVRCanvasWrapper canvasWrapper, RaycastHit hit)
// {
// return hit.distance <= canvasWrapper.MaxInteractDistance;
// }
#endregion Utility Because Original Methods Are Broken
}

View file

@ -4,10 +4,24 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
{
public class CVRPlayerRaycasterMouse : CVRPlayerRaycaster
{
private readonly Camera _camera;
#region Constructor
public CVRPlayerRaycasterMouse(Transform rayOrigin, Camera camera) : base(rayOrigin) { _camera = camera; }
private readonly Camera _camera;
#endregion Constructor
#region Overrides
protected override Ray GetRayFromImpl() => Cursor.lockState == CursorLockMode.Locked
? new Ray(_camera.transform.position, _camera.transform.forward)
: _camera.ScreenPointToRay(Input.mousePosition);
protected override Ray GetProximityRayFromImpl() => Cursor.lockState == CursorLockMode.Locked
? new Ray(_camera.transform.position, _camera.transform.forward)
: _camera.ScreenPointToRay(Input.mousePosition);
#endregion Overrides
}
}

View file

@ -4,7 +4,44 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
{
public class CVRPlayerRaycasterTransform : CVRPlayerRaycaster
{
public CVRPlayerRaycasterTransform(Transform rayOrigin) : base(rayOrigin) { }
#region Proximity Grab
public const float ProximityGrabRadiusScaleDefault = 0.1f;
private float _proximityDetectionRadiusRelativeValue = ProximityGrabRadiusScaleDefault;
private float ProximityDetectionRadius => _proximityDetectionRadiusRelativeValue * PlayerSetup.Instance.GetPlaySpaceScale();
#endregion Proximity Grab
#region Constructor
public CVRPlayerRaycasterTransform(Transform rayOrigin, CVRHand hand) : base(rayOrigin) { _hand = hand; }
private readonly CVRHand _hand;
#endregion Constructor
#region Overrides
protected override Ray GetRayFromImpl() => new(_rayOrigin.position, _rayOrigin.forward);
protected override Ray GetProximityRayFromImpl()
{
Vector3 handPosition = _rayOrigin.position;
Vector3 handRight = _rayOrigin.right;
// Offset the detection center forward, so we don't grab stuff behind our writs
handPosition += _rayOrigin.forward * (ProximityDetectionRadius * 0.25f);
// Offset the detection center away from the palm, so we don't grab stuff behind our hand palm
Vector3 palmOffset = handRight * (ProximityDetectionRadius * 0.75f);
if (_hand == CVRHand.Left)
handPosition += palmOffset;
else
handPosition -= palmOffset;
return new Ray(handPosition, _hand == CVRHand.Left ? handRight : -handRight);
}
#endregion Overrides
}
}

View file

@ -1,8 +1,6 @@
using ABI_RC.Core.InteractionSystem.Base;
using ABI_RC.Core.UI;
using NAK.SuperAwesomeMod.Components;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace ABI_RC.Core.Player.Interaction.RaycastImpl
@ -19,6 +17,7 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
// Main raycast hit info
public RaycastHit hit;
public RaycastHit? waterHit; // Only valid if hitWater is true
public Vector2 hitScreenPoint; // Screen coordinates of the hit
// Specific hit components
public Pickupable hitPickupable;

View file

@ -1,5 +1,4 @@
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace ABI_RC.Core.Player.Interaction.RaycastImpl

View file

@ -0,0 +1,362 @@
using ABI_RC.Core.Base;
using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.Player;
using ABI_RC.Core.Savior;
using ABI.CCK.Components;
using MelonLoader;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace NAK.SuperAwesomeMod.UExplorer;
public class UEMenuHelper : MenuPositionHelperBase
{
#region Singleton
public static void Create()
{
if (Instance != null)
return;
_universeLibCanvas = GameObject.Find("UniverseLibCanvas");
if (_universeLibCanvas == null)
{
MelonLogger.Error(
"Failed to create UniverseLibCanvas"); // TODO: mod logger, casue https://github.com/knah/VRCMods/pull/227
return;
}
_explorerRoot = _universeLibCanvas.transform.Find("com.sinai.unityexplorer_Root").gameObject;
// Fix the canvas so it renders in the UI camera
// _universeLibCanvas.SetLayerRecursive(CVRLayers.UIInternal);
Transform menuParent = new GameObject("UEMenuParent").transform;
menuParent.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
menuParent.localScale = Vector3.one;
DontDestroyOnLoad(menuParent.gameObject);
Transform offsetTransform = new GameObject("UEMenuOffset").transform;
offsetTransform.SetParent(menuParent, false);
offsetTransform.localScale = Vector3.one;
Transform contentTransform = new GameObject("UEMenuContent").transform;
contentTransform.SetParent(offsetTransform, false);
contentTransform.localScale = Vector3.one;
Instance = menuParent.AddComponentIfMissing<UEMenuHelper>();
Instance.menuTransform = contentTransform;
// Instance._offsetTransform = offsetTransform; // Got in MenuPositionHelperBase.Start
// Apply the component filters done in worlds
// foreach (Component c in _universeLibCanvas.GetComponentsInChildren<Component>(true))
// SetupCollidersOnUnityUi(c);
CVRCanvasWrapper.AddForCanvas(_universeLibCanvas.GetComponent<Canvas>(), true);
Instance.ConfigureUECanvasRenderMode(RenderMode.WorldSpace);
}
public static UEMenuHelper Instance { get; private set; }
private static GameObject _universeLibCanvas;
private static GameObject _explorerRoot;
private static RenderMode _currentRenderMode = RenderMode.WorldSpace;
#endregion Singleton
#region Overrides
public override bool IsMenuOpen => _explorerRoot.activeInHierarchy;
public override float MenuScaleModifier => !MetaPort.Instance.isUsingVr ? 1f : 0.3f;
public override float MenuDistanceModifier => !MetaPort.Instance.isUsingVr ? 1.2f : 1f;
#endregion Overrides
#region Unity Events
private void Update()
{
if (Input.GetKeyDown(KeyCode.F9))
ToggleUeCanvasRenderMode();
}
#endregion Unity Events
#region Private Methods
private void ToggleUeCanvasRenderMode()
{
ConfigureUECanvasRenderMode(_currentRenderMode == RenderMode.WorldSpace
? RenderMode.ScreenSpaceOverlay
: RenderMode.WorldSpace);
}
private void ConfigureUECanvasRenderMode(RenderMode targetMode)
{
_currentRenderMode = targetMode;
var canvases = _universeLibCanvas.GetComponentsInChildren<Canvas>(true);
if (targetMode == RenderMode.WorldSpace)
{
foreach (Canvas canvas in canvases)
{
canvas.renderMode = RenderMode.WorldSpace;
canvas.worldCamera = PlayerSetup.Instance.activeCam;
}
_universeLibCanvas.transform.SetParent(menuTransform, false);
_universeLibCanvas.transform.localScale = Vector3.one * 0.0032f;
// Center the canvas on the menuTransform
CenterCanvasOnMenuTransform(_universeLibCanvas, menuTransform);
return;
}
foreach (Canvas canvas in canvases)
{
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.worldCamera = null;
}
_universeLibCanvas.transform.SetParent(null, false);
_universeLibCanvas.transform.localScale = Vector3.one;
}
private void CenterCanvasOnMenuTransform(GameObject canvasRoot, Transform parentTransform)
{
// Find all the rectTransforms under the canvas, determine their bounds, and center the canvas local position
// on the menuTransform
RectTransform canvasTransform = _explorerRoot.transform as RectTransform;
// get the extents of the rectTransform
Vector3[] corners = new Vector3[4];
canvasTransform.GetWorldCorners(corners);
// now center by offsettings its localPosition
Vector3 center = (corners[0] + corners[2]) / 2f;
Vector3 extents = (corners[2] - corners[0]) / 2f;
Vector3 offset = center - extents;
offset.z = 0f; // set z to 0 to avoid depth issues
canvasTransform.localPosition = offset;
MelonLogger.Msg($"Centered canvas on menuTransform: {canvasTransform.localPosition}");
}
private static bool IsFloatValid(float val)
=> (!float.IsNaN(val) && !float.IsInfinity(val));
private static void SetupCollidersOnUnityUi(Component c)
{
GameObject go = c.gameObject;
if (c is Button)
{
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
col.isTrigger = true;
var rectTransform = go.GetComponent<RectTransform>();
if (rectTransform)
{
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
0.05f / rectTransform.lossyScale.z);
if (!IsFloatValid(newSize.x))
newSize.x = 0.05f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.05f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.05f;
col.size = newSize;
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
}
}
if (c is Toggle)
{
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
col.isTrigger = true;
var rectTransform = go.GetComponent<RectTransform>();
if (rectTransform)
{
Vector3 newSize = new Vector3(Mathf.Max(rectTransform.sizeDelta.x, rectTransform.rect.width),
rectTransform.sizeDelta.y, 0.05f / rectTransform.lossyScale.z);
if (!IsFloatValid(newSize.x))
newSize.x = 0.05f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.05f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.05f;
col.size = newSize;
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
//Check Child if Size = 0
if (col.size.x + col.size.y == 0f && go.transform.childCount > 0)
{
var childRectTransform = go.transform.GetChild(0).GetComponent<RectTransform>();
if (childRectTransform != null)
{
newSize = new Vector3(
Mathf.Max(childRectTransform.sizeDelta.x, rectTransform.rect.width),
childRectTransform.sizeDelta.y, 0.1f);
if (!IsFloatValid(newSize.x))
newSize.x = 0.05f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.05f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.05f;
col.size = newSize;
col.center = Vector3.zero;
}
}
}
}
if (c is Slider)
{
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
var rectTransform = go.GetComponent<RectTransform>();
if (rectTransform)
{
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
0.05f / rectTransform.lossyScale.z);
if (!IsFloatValid(newSize.x))
newSize.x = 0.05f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.05f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.05f;
col.size = newSize;
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
}
col.isTrigger = true;
}
if (c is EventTrigger)
{
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
var rectTransform = go.GetComponent<RectTransform>();
if (rectTransform)
{
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
0.025f / rectTransform.lossyScale.z);
if (!IsFloatValid(newSize.x))
newSize.x = 0.05f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.05f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.05f;
col.size = newSize;
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
}
col.isTrigger = true;
}
if (c is InputField || c is TMP_InputField)
{
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
col.isTrigger = true;
var rectTransform = go.GetComponent<RectTransform>();
if (rectTransform)
{
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
0.05f / rectTransform.lossyScale.z);
if (!IsFloatValid(newSize.x))
newSize.x = 0.05f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.05f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.05f;
col.size = newSize;
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
}
}
if (c is ScrollRect)
{
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
col.isTrigger = true;
var rectTransform = go.GetComponent<RectTransform>();
if (rectTransform)
{
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
0.025f / rectTransform.lossyScale.z);
if (!IsFloatValid(newSize.x))
newSize.x = 0.025f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.025f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.025f;
col.size = newSize;
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
}
}
if (c is Dropdown)
{
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
col.isTrigger = true;
var rectTransform = go.GetComponent<RectTransform>();
if (rectTransform)
{
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
0.05f / rectTransform.lossyScale.z);
if (!IsFloatValid(newSize.x))
newSize.x = 0.05f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.05f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.05f;
col.size = newSize;
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
}
}
//Canvas
if (c is Canvas)
{
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
var rectTransform = go.GetComponent<RectTransform>();
if (rectTransform)
{
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
0.0125f / rectTransform.lossyScale.z);
if (!IsFloatValid(newSize.x))
newSize.x = 0.0125f;
if (!IsFloatValid(newSize.y))
newSize.y = 0.0125f;
if (!IsFloatValid(newSize.z))
newSize.z = 0.0125f;
col.size = newSize;
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
}
col.isTrigger = true;
}
}
#endregion Private Methods
}

View file

@ -1,15 +1,14 @@
using System.Reflection;
using ABI_RC.Core.Base;
using ABI_RC.Core.Base.Jobs;
using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.Player;
using ABI_RC.Core.Player.Interaction.RaycastImpl;
using ABI_RC.Core.Util.AssetFiltering;
using ABI.CCK.Components;
using HarmonyLib;
using MelonLoader;
using NAK.SuperAwesomeMod.Components;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace NAK.SuperAwesomeMod;
@ -33,13 +32,13 @@ public class SuperAwesomeModMod : MelonMod
BindingFlags.NonPublic | BindingFlags.Static))
);
// patch SharedFilter.ProcessCanvas
HarmonyInstance.Patch(
typeof(SharedFilter).GetMethod(nameof(SharedFilter.ProcessCanvas),
BindingFlags.Public | BindingFlags.Static),
postfix: new HarmonyMethod(typeof(SuperAwesomeModMod).GetMethod(nameof(OnProcessCanvas),
BindingFlags.NonPublic | BindingFlags.Static))
);
// // patch SharedFilter.ProcessCanvas
// HarmonyInstance.Patch(
// typeof(SharedFilter).GetMethod(nameof(SharedFilter.ProcessCanvas),
// BindingFlags.Public | BindingFlags.Static),
// postfix: new HarmonyMethod(typeof(SuperAwesomeModMod).GetMethod(nameof(OnProcessCanvas),
// BindingFlags.NonPublic | BindingFlags.Static))
// );
LoggerInstance.Msg("SuperAwesomeModMod! OnInitializeMelon! :D");
}
@ -53,29 +52,43 @@ public class SuperAwesomeModMod : MelonMod
private static void OnPlayerSetupStart()
{
CVRRaycastDebugManager.Initialize(PlayerSetup.Instance.desktopCam);
// CVRRaycastDebugManager.Initialize(PlayerSetup.Instance.desktopCam);
// UEMenuHelper.Create();
}
private static void OnShitLoaded(Component c, List<Task> asyncTasks = null, Scene? scene = null)
{
if (c == null)
if (!c)
return;
if (c.gameObject == null)
if (!c.gameObject)
return;
if (c.gameObject.scene.buildIndex > 0)
return;
if ((scene != null)
&& (c.gameObject.scene != scene))
if ((scene != null) && (c.gameObject.scene != scene))
return;
if (c is Canvas canvas) canvas.gameObject.AddComponent<CVRCanvasWrapper>();
if (c is InputField input)
{
input.AddComponentIfMissing<InputFocusIntentDetector>();
}
if (c is TMPro.TMP_InputField tmpInput)
{
tmpInput.AddComponentIfMissing<InputFocusIntentDetector>();
}
}
private static void OnProcessCanvas(string collectionId, Canvas canvas)
public class InputFocusIntentDetector : MonoBehaviour, IPointerClickHandler
{
canvas.gameObject.AddComponent<CVRCanvasWrapper>();
public void OnPointerClick(PointerEventData eventData)
{
if (TryGetComponent(out TMPro.TMP_InputField input) && input.isActiveAndEnabled)
ViewManager.Instance.openMenuKeyboard(input);
else if (TryGetComponent(out InputField inputField) && inputField.isActiveAndEnabled)
ViewManager.Instance.openMenuKeyboard(inputField);
}
}
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>ASTExtension</RootNamespace>
<RootNamespace>SuperAwesomeMod</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Reference Include="BTKUILib">