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,141 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.Animations;
|
||||
#endif
|
||||
|
||||
namespace VRSDK
|
||||
{
|
||||
/// <summary>
|
||||
/// This scripts helps handling the Animator
|
||||
/// </summary>
|
||||
public class AnimatorHelper : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private List<LayerInfo> animatorControllerInfo = null;
|
||||
[SerializeField] private float layerTransitionTime = 0.15f;
|
||||
|
||||
private Animator animator = null;
|
||||
private Coroutine changeLayerValueCoroutine = null;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
animator = GetComponent<Animator>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do smooth layer transition
|
||||
/// </summary>
|
||||
public void EnableLayer(int layer)
|
||||
{
|
||||
if (changeLayerValueCoroutine != null)
|
||||
StopCoroutine( changeLayerValueCoroutine );
|
||||
|
||||
changeLayerValueCoroutine = StartCoroutine( ChangeLayerValueRoutine( layer, 1.0f, layerTransitionTime ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do smooth layer transition
|
||||
/// </summary>
|
||||
public void DisableLayer(int layer)
|
||||
{
|
||||
if (changeLayerValueCoroutine != null)
|
||||
StopCoroutine( changeLayerValueCoroutine );
|
||||
|
||||
changeLayerValueCoroutine = StartCoroutine( ChangeLayerValueRoutine( layer, 0.0f, layerTransitionTime ) );
|
||||
}
|
||||
|
||||
private IEnumerator ChangeLayerValueRoutine(int layer, float v, float t)
|
||||
{
|
||||
float timer = 0.0f;
|
||||
|
||||
while (timer < t)
|
||||
{
|
||||
float layerWeight = animator.GetLayerWeight( layer );
|
||||
animator.SetLayerWeight( layer, Mathf.Lerp( layerWeight, v, timer / t ) );
|
||||
|
||||
timer += Time.deltaTime;
|
||||
|
||||
yield return new WaitForSeconds( Time.deltaTime );
|
||||
}
|
||||
|
||||
animator.SetLayerWeight( layer, v );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is really helpfull, you can know whethever the animator is playing certain state or trasition to it
|
||||
/// </summary>
|
||||
public bool IsPlayingOrTransitionToState(int layer , string stateName)
|
||||
{
|
||||
return IsPlayingState( layer, stateName ) || IsTransitionToState(layer , stateName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// is the state name in layer being played?
|
||||
/// </summary>
|
||||
public bool IsPlayingState(int layer , string stateName)
|
||||
{
|
||||
return animator.GetCurrentAnimatorStateInfo( layer ).IsName( stateName );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is animator trasition to current state in layer
|
||||
/// </summary>
|
||||
public bool IsTransitionToState(int layer , string stateName)
|
||||
{
|
||||
List<string> states = animatorControllerInfo[layer].animatorStates;
|
||||
|
||||
for (int n = 0; n < states.Count; n++)
|
||||
{
|
||||
if (animator.GetAnimatorTransitionInfo( layer ).IsName( states[n] + " -> " + stateName ))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// in order to know if the animator is trasition to another state we need to know all state names before hand
|
||||
/// but we can only know them using using UnityEditor.Animations namespace, so we ned to build this information in Editor
|
||||
/// and serialized it so we can access it later in running time, this method is called in I_AnimatorHelperInspector.cs in the Awake
|
||||
public void ConstructAnimatorControllerInfo()
|
||||
{
|
||||
animatorControllerInfo = new List<LayerInfo>();
|
||||
|
||||
AnimatorController ac = GetComponent<Animator>().runtimeAnimatorController as AnimatorController;
|
||||
|
||||
AnimatorControllerLayer[] layerArray = ac.layers;
|
||||
|
||||
for (int n = 0; n < layerArray.Length; n++)
|
||||
{
|
||||
LayerInfo info = new LayerInfo();
|
||||
info.animatorStates = GetStatesFromLayer( layerArray[n] ); ;
|
||||
|
||||
animatorControllerInfo.Add(info);
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> GetStatesFromLayer(AnimatorControllerLayer layer)
|
||||
{
|
||||
List<string> states = new List<string>();
|
||||
|
||||
for (int n = 0; n < layer.stateMachine.states.Length; n++)
|
||||
{
|
||||
states.Add( layer.stateMachine.states[n].state.name );
|
||||
}
|
||||
|
||||
return states;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// serialize class for storing animator state names
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class LayerInfo
|
||||
{
|
||||
public List<string> animatorStates = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed793d0597bff0a4f8289e720b57ad82
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 168243
|
||||
packageName: VR Beats Kit
|
||||
packageVersion: 2.0
|
||||
assetPath: Assets/VRBeatsKit/Modules/VRSDK/Animator/AnimatorHelper.cs
|
||||
uploadId: 546658
|
||||
Reference in New Issue
Block a user