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,69 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace VRBeats.ScriptableEvents
|
||||
{
|
||||
public abstract class BaseEventListener<T1 , T2 ,T3 , T4> : MonoBehaviour ,
|
||||
IExposeInvoke<T2>
|
||||
where T1 :
|
||||
IExposeAddListener<T3> ,
|
||||
IExposeRemoveListener<T3>
|
||||
where T4: UnityEvent<T2>
|
||||
|
||||
{
|
||||
|
||||
[SerializeField] private T1 gameEvent;
|
||||
[SerializeField] private T4 response;
|
||||
|
||||
public T4 Response { get { return response; } }
|
||||
public T1 GameEvent { get { return gameEvent; } }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (gameEvent != null)
|
||||
{
|
||||
gameEvent.AddListener( (T3) ((System.Object)this) );
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (gameEvent != null)
|
||||
{
|
||||
gameEvent.RemoveListener((T3)((System.Object)this));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (gameEvent != null)
|
||||
{
|
||||
gameEvent.RemoveListener( (T3)((System.Object)this) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Invoke(T2 value)
|
||||
{
|
||||
if(response != null)
|
||||
response.Invoke(value);
|
||||
}
|
||||
|
||||
public void AddEventListener(UnityAction<T2> unityAction)
|
||||
{
|
||||
response.AddListener( unityAction );
|
||||
}
|
||||
|
||||
public void SetEventListener(T1 gameEvent)
|
||||
{
|
||||
this.gameEvent = gameEvent;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df5ed0832a6aa6743ad1f64bb4b80d2f
|
||||
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/Scripts/ScritableEvents/Core/Base/BaseEventListener.cs
|
||||
uploadId: 546658
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRBeats.ScriptableEvents
|
||||
{
|
||||
public class BaseGameEvent<T1 , T2> : ScriptableObject , IExposeAddListener<T1>, IExposeRemoveListener<T1> , IExposeInvoke<T2> where T1 : IExposeInvoke<T2>
|
||||
{
|
||||
[SerializeField] private List<T1> eventListenerList = null;
|
||||
[HideInInspector] public T2 invokeValue;
|
||||
|
||||
public List<T1> EventListenerList { get { return eventListenerList; } }
|
||||
|
||||
|
||||
public void AddListener(T1 listener)
|
||||
{
|
||||
eventListenerList.Add(listener);
|
||||
}
|
||||
|
||||
public void RemoveListener(T1 listener)
|
||||
{
|
||||
eventListenerList.Remove(listener);
|
||||
}
|
||||
|
||||
public void Invoke(T2 value)
|
||||
{
|
||||
for (int n = eventListenerList.Count - 1; n >= 0; n--)
|
||||
{
|
||||
eventListenerList[n].Invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77195594139989a4fb2f82dae5f1c77e
|
||||
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/Scripts/ScritableEvents/Core/Base/BaseGameEvent.cs
|
||||
uploadId: 546658
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5e389c231710d54bbef17cd54347f38
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEditor;
|
||||
|
||||
namespace VRBeats.ScriptableEvents
|
||||
{
|
||||
//T1 IntGameEvent
|
||||
//T2 int
|
||||
//T3 IntEventListener
|
||||
//T4 OnIntValueChange
|
||||
|
||||
public class BaseGameEventInspector<T1 , T2 , T3, T4> : Editor
|
||||
where T1 : BaseGameEvent<T3 , T2>
|
||||
where T3 : BaseEventListener<T1 , T2 , T3 , T4>
|
||||
where T4 : UnityEvent<T2>
|
||||
{
|
||||
|
||||
private T1 targetEvent = null;
|
||||
private SerializedProperty invokeValue;
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
targetEvent = (T1) target;
|
||||
invokeValue = serializedObject.FindProperty("invokeValue");
|
||||
}
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Sritable events can only be use in running time", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("Listeners");
|
||||
for (int n = 0; n < targetEvent.EventListenerList.Count; n++)
|
||||
{
|
||||
if (GUILayout.Button(targetEvent.EventListenerList[n].gameObject.name))
|
||||
{
|
||||
EditorGUIUtility.PingObject(targetEvent.EventListenerList[n].gameObject);
|
||||
}
|
||||
|
||||
DrawEventNames(targetEvent.EventListenerList[n].Response);
|
||||
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(invokeValue);
|
||||
|
||||
if (GUILayout.Button("Invoke"))
|
||||
{
|
||||
targetEvent.Invoke( targetEvent.invokeValue);
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
}
|
||||
|
||||
private void DrawEventNames(UnityEvent<T2> unityEvent)
|
||||
{
|
||||
for (int n = 0; n < unityEvent.GetPersistentEventCount(); n++)
|
||||
{
|
||||
EditorGUILayout.LabelField(unityEvent.GetPersistentTarget(n).GetType().Name + "." + unityEvent.GetPersistentMethodName(n));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e91efe1ddac6ff4e9414e95247c6dd8
|
||||
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/Scripts/ScritableEvents/Core/Base/Editor/BaseGameEventInspector.cs
|
||||
uploadId: 546658
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea5f4da0f37512a44a68b18784194cba
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace VRBeats.ScriptableEvents
|
||||
{
|
||||
public interface IExposeAddListener<T>
|
||||
{
|
||||
void AddListener(T value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9411d134adbe0b24abba7d7a9e751c29
|
||||
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/Scripts/ScritableEvents/Core/Base/Interfaces/IExposeAddListener.cs
|
||||
uploadId: 546658
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace VRBeats.ScriptableEvents
|
||||
{
|
||||
public interface IExposeInvoke<T>
|
||||
{
|
||||
void Invoke(T value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d43bca55bcdfe342b3dba605f8c4fcd
|
||||
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/Scripts/ScritableEvents/Core/Base/Interfaces/IExposeInvoke.cs
|
||||
uploadId: 546658
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
namespace VRBeats.ScriptableEvents
|
||||
{
|
||||
public interface IExposeRemoveListener<T>
|
||||
{
|
||||
void RemoveListener(T value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d5af0a99701e1649b8f6834c1974cc7
|
||||
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/Scripts/ScritableEvents/Core/Base/Interfaces/IExposeRemoveListener.cs
|
||||
uploadId: 546658
|
||||
Reference in New Issue
Block a user