Added Unity project files
This commit is contained in:
@ -0,0 +1,122 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using VRC.SDKBase;
|
||||
|
||||
namespace VRC.SDK3.ClientSim
|
||||
{
|
||||
/// <summary>
|
||||
/// System responsible for filtering out UI elements that cannot be interacted with.
|
||||
/// </summary>
|
||||
[AddComponentMenu("")]
|
||||
public class ClientSimInputModule : StandaloneInputModule
|
||||
{
|
||||
private IClientSimInteractiveLayerProvider _interactiveLayerProvider;
|
||||
private ClientSimBaseInput _baseInput;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
this.PreventComponentFromSaving();
|
||||
}
|
||||
|
||||
private void DisableOtherEventSystems()
|
||||
{
|
||||
// Go through and Disable all other event systems in the scene.
|
||||
EventSystem thisEventSystem = GetComponent<EventSystem>();
|
||||
EventSystem[] systems = FindObjectsByType<EventSystem>(FindObjectsSortMode.None);
|
||||
foreach (EventSystem system in systems)
|
||||
{
|
||||
if (system != thisEventSystem)
|
||||
{
|
||||
system.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize(IClientSimInteractiveLayerProvider interactiveLayerProvider)
|
||||
{
|
||||
_interactiveLayerProvider = interactiveLayerProvider;
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
DisableOtherEventSystems();
|
||||
|
||||
// TODO check settings and disable self if player is not spawned to allow normal ui raycasting.
|
||||
m_InputOverride = _baseInput = GetComponent<ClientSimBaseInput>();
|
||||
|
||||
base.Start();
|
||||
}
|
||||
|
||||
|
||||
// Force processing of mouse events even if the cursors is locked.
|
||||
public override void Process()
|
||||
{
|
||||
CursorLockMode currentLockState = Cursor.lockState;
|
||||
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
|
||||
base.Process();
|
||||
|
||||
Cursor.lockState = currentLockState;
|
||||
}
|
||||
|
||||
// Prevent clicking on menus that are not currently interactable.
|
||||
protected override MouseState GetMousePointerEventData(int id)
|
||||
{
|
||||
var pointerEventData = base.GetMousePointerEventData(id);
|
||||
var leftEventData = pointerEventData.GetButtonState(PointerEventData.InputButton.Left).eventData;
|
||||
var pointerRaycast = leftEventData.buttonData.pointerCurrentRaycast;
|
||||
|
||||
// Check if this raycast result is valid. If not, reset the data.
|
||||
if (!ShouldUseRaycastResult(pointerRaycast))
|
||||
{
|
||||
leftEventData.buttonData.pointerCurrentRaycast = new RaycastResult();
|
||||
}
|
||||
|
||||
return pointerEventData;
|
||||
}
|
||||
|
||||
private bool ShouldUseRaycastResult(RaycastResult result)
|
||||
{
|
||||
GameObject hitObj = result.gameObject;
|
||||
if (hitObj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If raycaster did not hit a UI shape, this means some other collider is in front.
|
||||
if (!_baseInput.HitUIShape())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there is no UI shape on this object or in its parents, ignore it.
|
||||
VRC_UiShape shape = hitObj.GetComponentInParent<VRC_UiShape>();
|
||||
if (shape == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GameObject shapeObj = shape.gameObject;
|
||||
// Ignore UI elements not on a currently Interactive layer
|
||||
if (((1 << shapeObj.layer) & _interactiveLayerProvider.GetInteractiveLayers()) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 position = result.worldPosition;
|
||||
// If ray is within any collider on the UIShape, it is valid.
|
||||
foreach (var shapeCollider in shapeObj.GetComponents<Collider>())
|
||||
{
|
||||
// If the closest point is itself, then it is in the collider.
|
||||
if (Vector3.Distance(shapeCollider.ClosestPoint(position), position) < 0.01f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user