92 lines
3.0 KiB
C#
92 lines
3.0 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.EventSystems;
|
||
|
||
namespace VRTitle.Input
|
||
{
|
||
/// <summary>
|
||
/// VRコントローラーからのポインター入力とUI操作を仲介するコンポーネント
|
||
/// </summary>
|
||
[RequireComponent(typeof(LineRenderer))]
|
||
public class VRLaserPointer : MonoBehaviour
|
||
{
|
||
[Header("Ray Settings")]
|
||
[SerializeField] private float maxDistance = 10f;
|
||
[SerializeField] private LayerMask uiLayerMask = ~0;
|
||
|
||
[Header("Visual")]
|
||
[SerializeField] private LineRenderer lineRenderer;
|
||
|
||
private GameObject currentHoveredObject;
|
||
|
||
private void Reset()
|
||
{
|
||
lineRenderer = GetComponent<LineRenderer>();
|
||
lineRenderer.positionCount = 2;
|
||
lineRenderer.startWidth = 0.005f;
|
||
lineRenderer.endWidth = 0.001f;
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
ProcessPointer();
|
||
}
|
||
|
||
private void ProcessPointer()
|
||
{
|
||
Ray ray = new Ray(transform.position, transform.forward);
|
||
PointerEventData pointerData = new PointerEventData(EventSystem.current)
|
||
{
|
||
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
|
||
};
|
||
|
||
List<RaycastResult> results = new List<RaycastResult>();
|
||
EventSystem.current?.RaycastAll(pointerData, results);
|
||
|
||
Vector3 targetPosition = transform.position + transform.forward * maxDistance;
|
||
|
||
if (results.Count > 0)
|
||
{
|
||
RaycastResult hit = results[0];
|
||
targetPosition = hit.worldPosition;
|
||
UpdateHoverState(hit.gameObject, pointerData);
|
||
}
|
||
else
|
||
{
|
||
UpdateHoverState(null, pointerData);
|
||
}
|
||
|
||
// ポインター描画の更新
|
||
lineRenderer.SetPosition(0, transform.position);
|
||
lineRenderer.SetPosition(1, targetPosition);
|
||
}
|
||
|
||
private void UpdateHoverState(GameObject newHover, PointerEventData pointerData)
|
||
{
|
||
if (currentHoveredObject == newHover) return;
|
||
|
||
if (currentHoveredObject != null)
|
||
{
|
||
ExecuteEvents.Execute(currentHoveredObject, pointerData, ExecuteEvents.pointerExitHandler);
|
||
}
|
||
|
||
currentHoveredObject = newHover;
|
||
|
||
if (currentHoveredObject != null)
|
||
{
|
||
ExecuteEvents.Execute(currentHoveredObject, pointerData, ExecuteEvents.pointerEnterHandler);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// トリガーボタンが押された時に呼び出す(Input System側から呼び出し可能)
|
||
/// </summary>
|
||
public void OnPrimaryTriggerDown()
|
||
{
|
||
if (currentHoveredObject == null) return;
|
||
|
||
PointerEventData pointerData = new PointerEventData(EventSystem.current);
|
||
ExecuteEvents.Execute(currentHoveredObject, pointerData, ExecuteEvents.pointerClickHandler);
|
||
}
|
||
}
|
||
} |