feat: SongCreator 씬 완성 — Beat Sage URL 지원, info.dat 메타데이터 자동 추출
- 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>
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user