4dad9e5d5b
- BeatSageUploader: audio_url 지원(UploadFromUrl), PollAndDownload 공통화, ZIP 500 오류 3회 재시도 - BeatSageConverter: info.dat 파싱(SongMetadata), BPM 자동 감지 → 노트 타이밍 변환에 적용 - SongCreatorManager: title/BPM 필수 입력 제거, 난이도 4개 자동 선택, GenerateFlowFromUrl 버그 수정 - NasPublisher: audioPath null 허용(URL 흐름에서 로컬 파일 없는 경우 스킵) - .gitignore/.gitattributes 초기 설정 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
213 lines
6.7 KiB
C#
213 lines
6.7 KiB
C#
using UnityEngine;
|
|
using VRSDK.Events;
|
|
|
|
namespace VRSDK
|
|
{
|
|
public class VR_Slider : VR_Grabbable
|
|
{
|
|
[SerializeField] private Axis slideAxis = Axis.Forward;
|
|
[SerializeField] private Transform slideStartMarker = null;
|
|
[SerializeField] private Transform slideEndMarker = null;
|
|
[SerializeField] private OnValueChangeEvent onValueChange = null;
|
|
|
|
private Vector3 initialLocalPosition = Vector3.zero;
|
|
private Vector3 slideStartMarkeLocalPosition = Vector3.zero;
|
|
private Vector3 slideEndMarkerLocalPosition = Vector3.zero;
|
|
private Vector3 calculateControllerLocalPosition = Vector3.zero;
|
|
private float movementRange = 0.0f;
|
|
private float currentValue = 0.0f;
|
|
|
|
public OnValueChangeEvent OnValueChange { get { return onValueChange; } }
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
|
|
initialLocalPosition = transform.localPosition;
|
|
slideStartMarkeLocalPosition = slideStartMarker.localPosition;
|
|
slideEndMarkerLocalPosition = slideEndMarker.localPosition;
|
|
|
|
movementRange = CalculateMovementRange();
|
|
}
|
|
|
|
|
|
|
|
private void LateUpdate()
|
|
{
|
|
if (activeController == null)
|
|
return;
|
|
|
|
Vector3 controllerPosition = activeController.OriginalParent.position;
|
|
calculateControllerLocalPosition = transform.parent.InverseTransformPoint( activeController.OriginalParent.position );
|
|
}
|
|
|
|
protected override void GrabUpdate ()
|
|
{
|
|
if (activeController == null)
|
|
return;
|
|
|
|
|
|
if (CanSlide(calculateControllerLocalPosition))
|
|
{
|
|
if (slideAxis == Axis.Horizontal)
|
|
{
|
|
|
|
transform.localPosition = new Vector3( calculateControllerLocalPosition.x, initialLocalPosition.y, initialLocalPosition.z );
|
|
}
|
|
else if (slideAxis == Axis.Vertical)
|
|
{
|
|
transform.localPosition = new Vector3( initialLocalPosition.x, calculateControllerLocalPosition.y, initialLocalPosition.z );
|
|
}
|
|
else if (slideAxis == Axis.Forward)
|
|
{
|
|
transform.localPosition = new Vector3( initialLocalPosition.x, initialLocalPosition.y, calculateControllerLocalPosition.z );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
UpdateSlideValue(calculateControllerLocalPosition);
|
|
|
|
base.GrabUpdate();
|
|
}
|
|
|
|
|
|
private bool CanSlide(Vector3 controllerLocalPosition)
|
|
{
|
|
if (slideAxis == Axis.Horizontal)
|
|
{
|
|
return slideStartMarkeLocalPosition.x < controllerLocalPosition.x && slideEndMarkerLocalPosition.x > controllerLocalPosition.x;
|
|
}
|
|
|
|
if (slideAxis == Axis.Vertical)
|
|
{
|
|
return slideStartMarkeLocalPosition.y < controllerLocalPosition.y && slideEndMarkerLocalPosition.y > controllerLocalPosition.y;
|
|
}
|
|
|
|
if (slideAxis == Axis.Forward)
|
|
{
|
|
|
|
return slideStartMarkeLocalPosition.z < controllerLocalPosition.z && slideEndMarkerLocalPosition.z > controllerLocalPosition.z;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void UpdateSlideValue(Vector3 controllerLocalPosition)
|
|
{
|
|
float distance = CalculateDistance( controllerLocalPosition );
|
|
float value = Mathf.Clamp01( distance / movementRange );
|
|
|
|
if (Mathf.Abs( value - currentValue ) > 0.01)
|
|
{
|
|
onValueChange.Invoke( value );
|
|
currentValue = value;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private float CalculateDistance(Vector3 controllerLocalPosition)
|
|
{
|
|
|
|
if (ControllerIsBeyondRange( controllerLocalPosition ))
|
|
return 1.0f;
|
|
else if (ControllerIsBelowRange( controllerLocalPosition ))
|
|
return 0.0f;
|
|
|
|
if (slideAxis == Axis.Horizontal)
|
|
{
|
|
|
|
return Mathf.Abs( slideStartMarkeLocalPosition.x - controllerLocalPosition.x );
|
|
}
|
|
|
|
if (slideAxis == Axis.Vertical)
|
|
{
|
|
return Mathf.Abs( slideStartMarkeLocalPosition.y - controllerLocalPosition.y );
|
|
}
|
|
|
|
if (slideAxis == Axis.Forward)
|
|
{
|
|
return Mathf.Abs( slideStartMarkeLocalPosition.z - controllerLocalPosition.z );
|
|
}
|
|
|
|
return 0.0f;
|
|
}
|
|
|
|
private float CalculateMovementRange()
|
|
{
|
|
if (slideAxis == Axis.Horizontal)
|
|
{
|
|
return Mathf.Abs( slideStartMarkeLocalPosition.x - slideEndMarkerLocalPosition.x );
|
|
}
|
|
|
|
if (slideAxis == Axis.Vertical)
|
|
{
|
|
return Mathf.Abs( slideStartMarkeLocalPosition.y - slideEndMarkerLocalPosition.y );
|
|
}
|
|
|
|
if (slideAxis == Axis.Forward)
|
|
{
|
|
return Mathf.Abs( slideStartMarkeLocalPosition.z - slideEndMarkerLocalPosition.z );
|
|
}
|
|
|
|
return 0.0f;
|
|
}
|
|
|
|
|
|
private bool ControllerIsBeyondRange(Vector3 controllerLocalPosition)
|
|
{
|
|
if (slideAxis == Axis.Horizontal)
|
|
{
|
|
return slideEndMarkerLocalPosition.x < controllerLocalPosition.x;
|
|
}
|
|
|
|
if (slideAxis == Axis.Vertical)
|
|
{
|
|
return slideEndMarkerLocalPosition.y < controllerLocalPosition.y;
|
|
}
|
|
|
|
if (slideAxis == Axis.Forward)
|
|
{
|
|
return slideEndMarkerLocalPosition.z < controllerLocalPosition.z;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool ControllerIsBelowRange(Vector3 controllerLocalPosition)
|
|
{
|
|
if (slideAxis == Axis.Horizontal)
|
|
{
|
|
return slideStartMarkeLocalPosition.x > controllerLocalPosition.x;
|
|
}
|
|
|
|
if (slideAxis == Axis.Vertical)
|
|
{
|
|
return slideStartMarkeLocalPosition.y > controllerLocalPosition.y;
|
|
}
|
|
|
|
if (slideAxis == Axis.Forward)
|
|
{
|
|
return slideStartMarkeLocalPosition.z > controllerLocalPosition.z;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override void OnGrabSuccess(VR_Controller controller)
|
|
{
|
|
activeController = controller;
|
|
currentGrabState = GrabState.Grab;
|
|
RaiseOnGrabStateChangeEvent( GrabState.Grab );
|
|
|
|
GrabController.SetVisibility( !GetCurrentHandAnimationSettings().hideHandOnGrab );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|