Compare commits
4 Commits
58838f0acb
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| abd3c9bb36 | |||
| 182d2c90b9 | |||
| 5e5e918c10 | |||
| 10e9ebae45 |
@@ -7,5 +7,6 @@
|
|||||||
*.wav binary
|
*.wav binary
|
||||||
*.mp3 binary
|
*.mp3 binary
|
||||||
*.ogg binary
|
*.ogg binary
|
||||||
|
*.mp4 binary
|
||||||
*.fbx binary
|
*.fbx binary
|
||||||
*.asset binary
|
*.asset binary
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
# IDE / Generated
|
# IDE / Generated
|
||||||
*.csproj
|
*.csproj
|
||||||
|
*.csproj.user
|
||||||
*.slnx
|
*.slnx
|
||||||
*.sln
|
*.sln
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public static class VRBeatSaberSceneBuilder
|
|||||||
var scene = EditorSceneManager.OpenScene(gamePath, OpenSceneMode.Single);
|
var scene = EditorSceneManager.OpenScene(gamePath, OpenSceneMode.Single);
|
||||||
|
|
||||||
// PlayableManager 제거 (PlayableDirector는 유지)
|
// PlayableManager 제거 (PlayableDirector는 유지)
|
||||||
var pm = Object.FindObjectOfType<PlayableManager>();
|
var pm = Object.FindFirstObjectByType<PlayableManager>();
|
||||||
if (pm != null)
|
if (pm != null)
|
||||||
Object.DestroyImmediate(pm);
|
Object.DestroyImmediate(pm);
|
||||||
|
|
||||||
|
|||||||
+25
-28
@@ -150,10 +150,6 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 441482e8936e35048a1dffac814e3ef8, type: 3}
|
m_Script: {fileID: 11500000, guid: 441482e8936e35048a1dffac814e3ef8, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
m_Profile: {fileID: 11400000, guid: 8882f7434ef4fcd458f02738f32c7b11, type: 2}
|
|
||||||
m_StaticLightingSkyUniqueID: 0
|
|
||||||
m_SkySettings: {fileID: 0}
|
|
||||||
m_SkySettingsFromProfile: {fileID: 0}
|
|
||||||
--- !u!4 &72731932
|
--- !u!4 &72731932
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 1
|
m_ObjectHideFlags: 1
|
||||||
@@ -616,42 +612,42 @@ PrefabInstance:
|
|||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 0.3567679
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: -0.4698689
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
value: -0.22523999
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalRotation.w
|
propertyPath: m_LocalRotation.w
|
||||||
value: 0.99958926
|
value: 0.9239
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalRotation.x
|
propertyPath: m_LocalRotation.x
|
||||||
value: -0
|
value: 0.3827
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalRotation.y
|
propertyPath: m_LocalRotation.y
|
||||||
value: -0.028659718
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalRotation.z
|
propertyPath: m_LocalRotation.z
|
||||||
value: -0
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalEulerAnglesHint.x
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
value: 0
|
value: 45
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
@@ -4555,9 +4551,10 @@ MonoBehaviour:
|
|||||||
m_GameObject: {fileID: 2094521061}
|
m_GameObject: {fileID: 2094521061}
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
m_EditorHideFlags: 0
|
m_EditorHideFlags: 0
|
||||||
m_Script: {fileID: 11500000, guid: 3f8ab482667b2f44691ffe7131ffbdb7, type: 3}
|
m_Script: {fileID: 11500000, guid: 504eaffe3c185bf469313a589c4026d0, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
button: {fileID: 2094521063}
|
||||||
sceneName: Menu
|
sceneName: Menu
|
||||||
--- !u!1 &2138780048
|
--- !u!1 &2138780048
|
||||||
GameObject:
|
GameObject:
|
||||||
@@ -4883,27 +4880,27 @@ PrefabInstance:
|
|||||||
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 0.36676788
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: -0.18886888
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
value: -0.23423982
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalRotation.w
|
propertyPath: m_LocalRotation.w
|
||||||
value: 1
|
value: 0.9238795
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalRotation.x
|
propertyPath: m_LocalRotation.x
|
||||||
value: -0
|
value: 0.38268343
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
||||||
type: 3}
|
type: 3}
|
||||||
@@ -4918,7 +4915,7 @@ PrefabInstance:
|
|||||||
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalEulerAnglesHint.x
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
value: 0
|
value: 45
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
- target: {fileID: 3968956848465607219, guid: f555cbb0b089fb64ca7c7a5b07f11520,
|
||||||
type: 3}
|
type: 3}
|
||||||
@@ -5093,27 +5090,27 @@ PrefabInstance:
|
|||||||
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 0.36676788
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: -0.18886888
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
value: -0.23423982
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalRotation.w
|
propertyPath: m_LocalRotation.w
|
||||||
value: 1
|
value: 0.9238795
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalRotation.x
|
propertyPath: m_LocalRotation.x
|
||||||
value: -0
|
value: 0.38268343
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
||||||
type: 3}
|
type: 3}
|
||||||
@@ -5128,7 +5125,7 @@ PrefabInstance:
|
|||||||
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalEulerAnglesHint.x
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
value: 0
|
value: 45
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
- target: {fileID: 1002067974212273307, guid: e7173b1ee3369204eb181b376ede2a3e,
|
||||||
type: 3}
|
type: 3}
|
||||||
@@ -5305,17 +5302,17 @@ PrefabInstance:
|
|||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 0.3567679
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: -0.4698689
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
value: -0.22523999
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
- target: {fileID: 7481659171502770090, guid: d614df01a29ad3e45bb831298dfbad2c,
|
||||||
type: 3}
|
type: 3}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class DesktopUIMode : MonoBehaviour
|
|||||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
||||||
private static void AutoCreate()
|
private static void AutoCreate()
|
||||||
{
|
{
|
||||||
if (FindObjectOfType<DesktopUIMode>() != null) return;
|
if (FindFirstObjectByType<DesktopUIMode>() != null) return;
|
||||||
new GameObject("[DesktopUIMode]").AddComponent<DesktopUIMode>();
|
new GameObject("[DesktopUIMode]").AddComponent<DesktopUIMode>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ public class DesktopUIMode : MonoBehaviour
|
|||||||
if (cam == null)
|
if (cam == null)
|
||||||
foreach (var c in FindObjectsByType<Camera>(FindObjectsSortMode.None))
|
foreach (var c in FindObjectsByType<Camera>(FindObjectsSortMode.None))
|
||||||
if (c.enabled && c.gameObject.scene.name != "DontDestroyOnLoad") { cam = c; break; }
|
if (c.enabled && c.gameObject.scene.name != "DontDestroyOnLoad") { cam = c; break; }
|
||||||
cam ??= FindObjectOfType<Camera>();
|
cam ??= FindFirstObjectByType<Camera>();
|
||||||
if (cam == null) return;
|
if (cam == null) return;
|
||||||
|
|
||||||
foreach (var canvas in FindObjectsByType<Canvas>(FindObjectsSortMode.None))
|
foreach (var canvas in FindObjectsByType<Canvas>(FindObjectsSortMode.None))
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ public class NasPublisher : MonoBehaviour
|
|||||||
|
|
||||||
[Serializable] private class NasConfig
|
[Serializable] private class NasConfig
|
||||||
{
|
{
|
||||||
public string host;
|
public string host = "";
|
||||||
public string account;
|
public string account = "";
|
||||||
public string rootPath;
|
public string rootPath = "";
|
||||||
public string staticUrl;
|
public string staticUrl = "";
|
||||||
public string password;
|
public string password = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator Publish(
|
public IEnumerator Publish(
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ public class SongController : MonoBehaviour
|
|||||||
[SerializeField] private GameEvent onLevelComplete;
|
[SerializeField] private GameEvent onLevelComplete;
|
||||||
[SerializeField] private TMP_Text countdownText;
|
[SerializeField] private TMP_Text countdownText;
|
||||||
|
|
||||||
|
private const float LaneSpacing = 0.42f;
|
||||||
|
private const float LayerSpacing = 0.38f;
|
||||||
|
private const float HorizontalCenter = 1.5f;
|
||||||
|
private const float VerticalCenter = 1f;
|
||||||
|
|
||||||
private AudioManager _audio;
|
private AudioManager _audio;
|
||||||
|
|
||||||
private static string CacheRoot =>
|
private static string CacheRoot =>
|
||||||
@@ -20,7 +25,7 @@ public class SongController : MonoBehaviour
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
_audio = FindObjectOfType<AudioManager>();
|
_audio = FindFirstObjectByType<AudioManager>();
|
||||||
StartCoroutine(LoadAndPlay());
|
StartCoroutine(LoadAndPlay());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +73,7 @@ public class SongController : MonoBehaviour
|
|||||||
Debug.LogError("[SongController] Map parse failed");
|
Debug.LogError("[SongController] Map parse failed");
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
map.target.Sort((a, b) => a.time.CompareTo(b.time));
|
map.target.Sort(CompareNotes);
|
||||||
|
|
||||||
yield return StartCoroutine(Countdown());
|
yield return StartCoroutine(Countdown());
|
||||||
|
|
||||||
@@ -109,8 +114,8 @@ public class SongController : MonoBehaviour
|
|||||||
|
|
||||||
private void SpawnNote(NoteData note)
|
private void SpawnNote(NoteData note)
|
||||||
{
|
{
|
||||||
float x = -0.375f + note.position * 0.25f;
|
float x = MapLaneX(note.position);
|
||||||
float y = -0.333f + note.lineLayer * 0.333f;
|
float y = MapLayerY(note.lineLayer);
|
||||||
|
|
||||||
// 스폰 시점의 실제 남은 시간으로 역산 → 동시 노트가 프레임 차이 나도 같은 타이밍에 도착
|
// 스폰 시점의 실제 남은 시간으로 역산 → 동시 노트가 프레임 차이 나도 같은 타이밍에 도착
|
||||||
float remaining = note.time - _audio.CurrentTime;
|
float remaining = note.time - _audio.CurrentTime;
|
||||||
@@ -129,6 +134,31 @@ public class SongController : MonoBehaviour
|
|||||||
VR_BeatManager.instance.Spawn(cubePrefab, info);
|
VR_BeatManager.instance.Spawn(cubePrefab, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int CompareNotes(NoteData a, NoteData b)
|
||||||
|
{
|
||||||
|
int timeCompare = a.time.CompareTo(b.time);
|
||||||
|
if (timeCompare != 0)
|
||||||
|
return timeCompare;
|
||||||
|
|
||||||
|
int positionCompare = a.position.CompareTo(b.position);
|
||||||
|
if (positionCompare != 0)
|
||||||
|
return positionCompare;
|
||||||
|
|
||||||
|
return a.lineLayer.CompareTo(b.lineLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float MapLaneX(int position)
|
||||||
|
{
|
||||||
|
int lane = Mathf.Clamp(position, 0, 3);
|
||||||
|
return (lane - HorizontalCenter) * LaneSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float MapLayerY(int lineLayer)
|
||||||
|
{
|
||||||
|
int layer = Mathf.Clamp(lineLayer, 0, 2);
|
||||||
|
return (layer - VerticalCenter) * LayerSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
// Beat Saber cutDirection → VRBeats Direction
|
// Beat Saber cutDirection → VRBeats Direction
|
||||||
// BS: 0=Up 1=Down 2=Left 3=Right 4=UpperLeft 5=UpperRight 6=LowerLeft 7=LowerRight 8=Any
|
// BS: 0=Up 1=Down 2=Left 3=Right 4=UpperLeft 5=UpperRight 6=LowerLeft 7=LowerRight 8=Any
|
||||||
private static readonly Direction[] CutDirMap =
|
private static readonly Direction[] CutDirMap =
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ public class SongSelectManager : MonoBehaviour
|
|||||||
tTmp.color = Color.white;
|
tTmp.color = Color.white;
|
||||||
tTmp.alignment = TextAlignmentOptions.MidlineLeft;
|
tTmp.alignment = TextAlignmentOptions.MidlineLeft;
|
||||||
tTmp.overflowMode = TextOverflowModes.Overflow;
|
tTmp.overflowMode = TextOverflowModes.Overflow;
|
||||||
tTmp.enableWordWrapping = false;
|
tTmp.textWrappingMode = TextWrappingModes.NoWrap;
|
||||||
titleGO.AddComponent<MarqueeText>();
|
titleGO.AddComponent<MarqueeText>();
|
||||||
|
|
||||||
// Artist
|
// Artist
|
||||||
|
|||||||
@@ -0,0 +1,278 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.XR;
|
||||||
|
|
||||||
|
namespace VRBeats
|
||||||
|
{
|
||||||
|
[RequireComponent(typeof(LineRenderer))]
|
||||||
|
public class VRPointerController : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private bool isRightHand = true;
|
||||||
|
[SerializeField] private float maxDistance = 50f;
|
||||||
|
|
||||||
|
private LineRenderer _line;
|
||||||
|
private bool _prevTrigger;
|
||||||
|
private Selectable _currentHover;
|
||||||
|
|
||||||
|
private static readonly Color NormalColor = new Color(1f, 1f, 1f, 0.8f);
|
||||||
|
private static readonly Color HoverColor = new Color(0.3f, 0.8f, 1f, 1f);
|
||||||
|
|
||||||
|
private float _deviceLogTimer;
|
||||||
|
|
||||||
|
// 버튼별 이전 상태
|
||||||
|
private bool _prevGrip;
|
||||||
|
private bool _prevPrimary;
|
||||||
|
private bool _prevSecondary;
|
||||||
|
private bool _prevThumbstick;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
_line = GetComponent<LineRenderer>();
|
||||||
|
_line.positionCount = 2;
|
||||||
|
_line.startWidth = 0.005f;
|
||||||
|
_line.endWidth = 0.001f;
|
||||||
|
_line.useWorldSpace = true;
|
||||||
|
// enabled 상태는 OnEnable/OnDisable이 관리 — Awake에서 건드리지 않음
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
// Awake 이후 reflection으로 isRightHand가 설정되므로 Start에서 로그
|
||||||
|
Debug.Log($"[VRPointer] Start — {gameObject.name} / isRightHand={isRightHand}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
if (_line != null) _line.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
if (_line != null) _line.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
// 3초마다 연결된 디바이스 목록 출력
|
||||||
|
_deviceLogTimer += Time.deltaTime;
|
||||||
|
if (_deviceLogTimer >= 3f)
|
||||||
|
{
|
||||||
|
_deviceLogTimer = 0f;
|
||||||
|
LogConnectedDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool trigger = GetButton(CommonUsages.triggerButton);
|
||||||
|
bool grip = GetButton(CommonUsages.gripButton);
|
||||||
|
bool primary = GetButton(CommonUsages.primaryButton);
|
||||||
|
bool secondary = GetButton(CommonUsages.secondaryButton);
|
||||||
|
bool thumbstick = GetButton(CommonUsages.primary2DAxisClick);
|
||||||
|
|
||||||
|
bool triggerDown = trigger && !_prevTrigger;
|
||||||
|
bool gripDown = grip && !_prevGrip;
|
||||||
|
bool primaryDown = primary && !_prevPrimary;
|
||||||
|
bool secondaryDown = secondary && !_prevSecondary;
|
||||||
|
bool thumbstickDown = thumbstick && !_prevThumbstick;
|
||||||
|
|
||||||
|
_prevTrigger = trigger;
|
||||||
|
_prevGrip = grip;
|
||||||
|
_prevPrimary = primary;
|
||||||
|
_prevSecondary = secondary;
|
||||||
|
_prevThumbstick = thumbstick;
|
||||||
|
|
||||||
|
string hand = isRightHand ? "R" : "L";
|
||||||
|
if (triggerDown) Debug.Log($"[VRPointer:{hand}] 검지 트리거 눌림");
|
||||||
|
if (gripDown) Debug.Log($"[VRPointer:{hand}] 그립(중지) 눌림");
|
||||||
|
if (primaryDown) Debug.Log($"[VRPointer:{hand}] {(isRightHand ? "A" : "X")} 버튼 눌림");
|
||||||
|
if (secondaryDown) Debug.Log($"[VRPointer:{hand}] {(isRightHand ? "B" : "Y")} 버튼 눌림");
|
||||||
|
if (thumbstickDown)Debug.Log($"[VRPointer:{hand}] 조이스틱 클릭 눌림");
|
||||||
|
|
||||||
|
Ray ray = new Ray(transform.position, transform.forward);
|
||||||
|
float hitDist = maxDistance;
|
||||||
|
|
||||||
|
Selectable hit = FindSelectableUnderRay(ray, ref hitDist);
|
||||||
|
|
||||||
|
// 호버 변화 로그
|
||||||
|
if (hit != _currentHover)
|
||||||
|
{
|
||||||
|
Debug.Log(hit != null
|
||||||
|
? $"[VRPointer] HOVER → {hit.gameObject.name}"
|
||||||
|
: $"[VRPointer] HOVER → (없음)");
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateHoverState(hit);
|
||||||
|
|
||||||
|
// 검지 트리거 또는 A/X 버튼으로 클릭
|
||||||
|
if (triggerDown || primaryDown)
|
||||||
|
{
|
||||||
|
if (_currentHover != null)
|
||||||
|
{
|
||||||
|
string btn = triggerDown ? "검지 트리거" : (isRightHand ? "A" : "X");
|
||||||
|
Debug.Log($"[VRPointer:{hand}] CLICK [{btn}] → {_currentHover.gameObject.name}");
|
||||||
|
Click(_currentHover);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log($"[VRPointer:{hand}] CLICK — 레이 아래 버튼 없음 " +
|
||||||
|
$"pos={transform.position:F2} fwd={transform.forward:F2}");
|
||||||
|
DebugRaycastAttempt(new Ray(transform.position, transform.forward));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawLine(hitDist);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogConnectedDevices()
|
||||||
|
{
|
||||||
|
var all = new List<InputDevice>();
|
||||||
|
InputDevices.GetDevices(all);
|
||||||
|
|
||||||
|
if (all.Count == 0)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[VRPointer] 연결된 XR 디바이스 없음 ({gameObject.name})");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var chars = InputDeviceCharacteristics.Controller |
|
||||||
|
(isRightHand ? InputDeviceCharacteristics.Right : InputDeviceCharacteristics.Left);
|
||||||
|
var matched = new List<InputDevice>();
|
||||||
|
InputDevices.GetDevicesWithCharacteristics(chars, matched);
|
||||||
|
|
||||||
|
Debug.Log($"[VRPointer] 전체 디바이스 {all.Count}개 | " +
|
||||||
|
$"{(isRightHand ? "오른손" : "왼손")} 컨트롤러 {matched.Count}개 ({gameObject.name})");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateHoverState(Selectable hit)
|
||||||
|
{
|
||||||
|
if (hit == _currentHover) return;
|
||||||
|
|
||||||
|
var es = EventSystem.current;
|
||||||
|
if (_currentHover != null)
|
||||||
|
ExecuteEvents.Execute(_currentHover.gameObject,
|
||||||
|
new PointerEventData(es), ExecuteEvents.pointerExitHandler);
|
||||||
|
|
||||||
|
_currentHover = hit;
|
||||||
|
|
||||||
|
if (_currentHover != null)
|
||||||
|
ExecuteEvents.Execute(_currentHover.gameObject,
|
||||||
|
new PointerEventData(es), ExecuteEvents.pointerEnterHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Click(Selectable sel)
|
||||||
|
{
|
||||||
|
var es = EventSystem.current;
|
||||||
|
if (es == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[VRPointer] EventSystem.current is null — click 실패");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var eventData = new PointerEventData(es);
|
||||||
|
ExecuteEvents.Execute(sel.gameObject, eventData, ExecuteEvents.pointerDownHandler);
|
||||||
|
ExecuteEvents.Execute(sel.gameObject, eventData, ExecuteEvents.pointerUpHandler);
|
||||||
|
ExecuteEvents.Execute(sel.gameObject, eventData, ExecuteEvents.pointerClickHandler);
|
||||||
|
|
||||||
|
var btn = sel.GetComponent<Button>();
|
||||||
|
if (btn != null) btn.onClick.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawLine(float hitDist)
|
||||||
|
{
|
||||||
|
Color c = _currentHover != null ? HoverColor : NormalColor;
|
||||||
|
_line.startColor = c;
|
||||||
|
_line.endColor = new Color(c.r, c.g, c.b, 0f);
|
||||||
|
_line.SetPosition(0, transform.position);
|
||||||
|
_line.SetPosition(1, transform.position + transform.forward * hitDist);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DebugRaycastAttempt(Ray ray)
|
||||||
|
{
|
||||||
|
var all = Selectable.allSelectablesArray;
|
||||||
|
Debug.Log($"[VRPointer:DEBUG] Selectable 총 {all.Length}개 | ray.origin={ray.origin:F2} ray.dir={ray.direction:F2}");
|
||||||
|
|
||||||
|
foreach (Selectable sel in all)
|
||||||
|
{
|
||||||
|
if (!sel.gameObject.activeInHierarchy) { Debug.Log($" SKIP(비활성) {sel.gameObject.name}"); continue; }
|
||||||
|
if (!sel.interactable) { Debug.Log($" SKIP(interactable=false) {sel.gameObject.name}"); continue; }
|
||||||
|
|
||||||
|
var rt = sel.GetComponent<RectTransform>();
|
||||||
|
if (rt == null) { Debug.Log($" SKIP(RectTransform없음) {sel.gameObject.name}"); continue; }
|
||||||
|
|
||||||
|
Vector3[] c = new Vector3[4];
|
||||||
|
rt.GetWorldCorners(c);
|
||||||
|
|
||||||
|
Vector3 normal = rt.forward;
|
||||||
|
if (Vector3.Dot(normal, ray.direction) >= 0f) normal = -normal;
|
||||||
|
|
||||||
|
Plane plane = new Plane(normal, c[0]);
|
||||||
|
bool hit = plane.Raycast(ray, out float dist);
|
||||||
|
if (!hit) { Debug.Log($" MISS(Plane.Raycast=false) {sel.gameObject.name} | rtPos={rt.position:F2} normal={normal:F2}"); continue; }
|
||||||
|
|
||||||
|
bool inRect = IsPointInRect(ray.GetPoint(dist), c);
|
||||||
|
Debug.Log($" {(inRect ? "HIT" : "MISS(InRect=false)")} {sel.gameObject.name} | dist={dist:F2} inRect={inRect}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Selectable FindSelectableUnderRay(Ray ray, ref float maxDist)
|
||||||
|
{
|
||||||
|
Selectable closest = null;
|
||||||
|
float closestDist = maxDist;
|
||||||
|
|
||||||
|
foreach (Selectable sel in Selectable.allSelectablesArray)
|
||||||
|
{
|
||||||
|
if (!sel.gameObject.activeInHierarchy || !sel.interactable) continue;
|
||||||
|
|
||||||
|
var rt = sel.GetComponent<RectTransform>();
|
||||||
|
if (rt == null) continue;
|
||||||
|
|
||||||
|
Vector3[] corners = new Vector3[4];
|
||||||
|
rt.GetWorldCorners(corners);
|
||||||
|
|
||||||
|
// Plane.Raycast은 normal 쪽(앞면)에서 레이가 출발해야 true 반환.
|
||||||
|
// rt.forward가 카메라 반대를 향할 수 있으므로 레이 원점 방향으로 노말 보정.
|
||||||
|
Vector3 normal = rt.forward;
|
||||||
|
if (Vector3.Dot(normal, ray.direction) >= 0f)
|
||||||
|
normal = -normal;
|
||||||
|
|
||||||
|
Plane plane = new Plane(normal, corners[0]);
|
||||||
|
if (!plane.Raycast(ray, out float dist)) continue;
|
||||||
|
if (dist >= closestDist || dist <= 0f) continue;
|
||||||
|
|
||||||
|
if (!IsPointInRect(ray.GetPoint(dist), corners)) continue;
|
||||||
|
|
||||||
|
closestDist = dist;
|
||||||
|
closest = sel;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxDist = closestDist;
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsPointInRect(Vector3 p, Vector3[] c)
|
||||||
|
{
|
||||||
|
Vector3 toP = p - c[0];
|
||||||
|
Vector3 right = c[3] - c[0];
|
||||||
|
Vector3 up = c[1] - c[0];
|
||||||
|
|
||||||
|
float r = Vector3.Dot(toP, right) / right.sqrMagnitude;
|
||||||
|
float u = Vector3.Dot(toP, up) / up.sqrMagnitude;
|
||||||
|
return r >= 0f && r <= 1f && u >= 0f && u <= 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GetButton(InputFeatureUsage<bool> usage)
|
||||||
|
{
|
||||||
|
var chars = InputDeviceCharacteristics.Controller |
|
||||||
|
(isRightHand
|
||||||
|
? InputDeviceCharacteristics.Right
|
||||||
|
: InputDeviceCharacteristics.Left);
|
||||||
|
|
||||||
|
var devices = new List<InputDevice>();
|
||||||
|
InputDevices.GetDevicesWithCharacteristics(chars, devices);
|
||||||
|
if (devices.Count == 0) return false;
|
||||||
|
|
||||||
|
devices[0].TryGetFeatureValue(usage, out bool pressed);
|
||||||
|
return pressed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: eec74ab726176d74491e9be716a7a609
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
namespace VRBeats
|
||||||
|
{
|
||||||
|
// 모든 씬에서 자동 실행.
|
||||||
|
// Game 씬: VRPointerController를 비활성 상태로 추가 → VR_InteractorController가 게임오버 시 활성화.
|
||||||
|
// 나머지 씬: 바로 활성 상태로 추가.
|
||||||
|
public class VRPointerSetup : MonoBehaviour
|
||||||
|
{
|
||||||
|
private static VRPointerSetup instance;
|
||||||
|
|
||||||
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||||
|
private static void ResetStatics()
|
||||||
|
{
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||||
|
private static void AutoInject()
|
||||||
|
{
|
||||||
|
if (instance != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var go = new GameObject("[VRPointerSetup]");
|
||||||
|
go.AddComponent<VRPointerSetup>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (instance != null && instance != this)
|
||||||
|
{
|
||||||
|
Destroy(gameObject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = this;
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
SetupActiveScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||||
|
{
|
||||||
|
SetupScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetupActiveScene()
|
||||||
|
{
|
||||||
|
SetupScene(SceneManager.GetActiveScene());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetupScene(Scene scene)
|
||||||
|
{
|
||||||
|
bool isGameScene = scene.name == "Game";
|
||||||
|
SetupControllers(disabledByDefault: isGameScene);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetupControllers(bool disabledByDefault)
|
||||||
|
{
|
||||||
|
foreach (var go in FindObjectsByType<GameObject>(FindObjectsSortMode.None))
|
||||||
|
{
|
||||||
|
string name = go.name;
|
||||||
|
bool isRight = name.Contains("Right");
|
||||||
|
bool isLeft = name.Contains("Left");
|
||||||
|
|
||||||
|
if (!isRight && !isLeft) continue;
|
||||||
|
if (!name.Contains("Controller") && !name.Contains("Hand")) continue;
|
||||||
|
if (go.GetComponent<LineRenderer>() == null) continue;
|
||||||
|
if (go.GetComponent<VRPointerController>() != null) continue;
|
||||||
|
|
||||||
|
var pointer = go.AddComponent<VRPointerController>();
|
||||||
|
|
||||||
|
var field = typeof(VRPointerController)
|
||||||
|
.GetField("isRightHand",
|
||||||
|
System.Reflection.BindingFlags.NonPublic |
|
||||||
|
System.Reflection.BindingFlags.Instance);
|
||||||
|
field?.SetValue(pointer, isRight);
|
||||||
|
|
||||||
|
// Game 씬에서는 게임오버 전까지 비활성
|
||||||
|
if (disabledByDefault)
|
||||||
|
pointer.enabled = false;
|
||||||
|
|
||||||
|
Debug.Log($"[VRPointerSetup] {(isRight ? "Right" : "Left")} pointer 추가: {go.name} (enabled={!disabledByDefault})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 38f89babd4e99734aac47edbc4f87aa3
|
||||||
+36
-9
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@ namespace DamageSystem
|
|||||||
OnDamage.AddListener( ApplyImpactForce );
|
OnDamage.AddListener( ApplyImpactForce );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyImpactForce(DamageInfo info, DamageablePart damageable)
|
protected override void ApplyImpactForce(DamageInfo info, DamageablePart damageable)
|
||||||
{
|
{
|
||||||
//if this AI if no dead it is being controlled by the Animator so dont apply any impact force
|
//if this AI if no dead it is being controlled by the Animator so dont apply any impact force
|
||||||
if (!IsDead)
|
if (!IsDead)
|
||||||
@@ -28,4 +28,3 @@ namespace DamageSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace VRSDK.Climbing
|
|||||||
{
|
{
|
||||||
base.Start();
|
base.Start();
|
||||||
|
|
||||||
target = FindObjectOfType<ClimbingTarget>();
|
target = FindFirstObjectByType<ClimbingTarget>();
|
||||||
onGrabStateChange.AddListener( OnGrabStateChangeClimb );
|
onGrabStateChange.AddListener( OnGrabStateChangeClimb );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,4 +89,3 @@ namespace VRSDK.Climbing
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEditor.Build;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -193,8 +194,8 @@ namespace VRSDK.EditorCode
|
|||||||
public static void ForceRebuild()
|
public static void ForceRebuild()
|
||||||
{
|
{
|
||||||
string[] rebuildSymbols = { "RebuildToggle1", "RebuildToggle2" };
|
string[] rebuildSymbols = { "RebuildToggle1", "RebuildToggle2" };
|
||||||
string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(
|
NamedBuildTarget buildTarget = NamedBuildTarget.FromBuildTargetGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||||
EditorUserBuildSettings.selectedBuildTargetGroup );
|
string definesString = PlayerSettings.GetScriptingDefineSymbols(buildTarget);
|
||||||
var definesStringTemp = definesString;
|
var definesStringTemp = definesString;
|
||||||
if (definesStringTemp.Contains( rebuildSymbols[0] ))
|
if (definesStringTemp.Contains( rebuildSymbols[0] ))
|
||||||
{
|
{
|
||||||
@@ -208,14 +209,9 @@ namespace VRSDK.EditorCode
|
|||||||
{
|
{
|
||||||
definesStringTemp += ";" + rebuildSymbols[0];
|
definesStringTemp += ";" + rebuildSymbols[0];
|
||||||
}
|
}
|
||||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(
|
PlayerSettings.SetScriptingDefineSymbols(buildTarget, definesStringTemp);
|
||||||
EditorUserBuildSettings.selectedBuildTargetGroup,
|
PlayerSettings.SetScriptingDefineSymbols(buildTarget, definesString);
|
||||||
definesStringTemp );
|
|
||||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(
|
|
||||||
EditorUserBuildSettings.selectedBuildTargetGroup,
|
|
||||||
definesString );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-5
@@ -15,10 +15,6 @@ namespace VRSDK.EditorCode
|
|||||||
|
|
||||||
private HandVisualizerTool targetScript = null;
|
private HandVisualizerTool targetScript = null;
|
||||||
|
|
||||||
private static string returnScenePath = null;
|
|
||||||
private static Scene returnScene;
|
|
||||||
private static bool inPreviewMode = false;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -95,4 +91,3 @@ namespace VRSDK.EditorCode
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-5
@@ -26,15 +26,15 @@ namespace VRSDK.EditorCode
|
|||||||
{
|
{
|
||||||
|
|
||||||
Scene originalScene = EditorSceneManager.GetActiveScene();
|
Scene originalScene = EditorSceneManager.GetActiveScene();
|
||||||
originalScenePath = EditorApplication.currentScene;
|
originalScenePath = originalScene.path;
|
||||||
|
|
||||||
Scene previewScene = EditorSceneManager.NewScene( NewSceneSetup.DefaultGameObjects, NewSceneMode.Additive );
|
Scene previewScene = EditorSceneManager.NewScene( NewSceneSetup.DefaultGameObjects, NewSceneMode.Additive );
|
||||||
EditorSceneManager.MoveGameObjectToScene( clone, previewScene );
|
EditorSceneManager.MoveGameObjectToScene( clone, previewScene );
|
||||||
|
|
||||||
EditorSceneManager.UnloadSceneAsync( originalScene );
|
EditorSceneManager.UnloadSceneAsync( originalScene );
|
||||||
previewModeEnable = true;
|
previewModeEnable = true;
|
||||||
inspectedGrabbable = GameObject.FindObjectOfType<VR_Grabbable>();
|
inspectedGrabbable = GameObject.FindFirstObjectByType<VR_Grabbable>();
|
||||||
activeController = GameObject.FindObjectOfType<VR_Controller>();
|
activeController = GameObject.FindFirstObjectByType<VR_Controller>();
|
||||||
|
|
||||||
OverrideGrabAnimation();
|
OverrideGrabAnimation();
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ namespace VRSDK.EditorCode
|
|||||||
{
|
{
|
||||||
handPreviewSave = new HandPreviewSave( inspectedGrabbable );
|
handPreviewSave = new HandPreviewSave( inspectedGrabbable );
|
||||||
ExitPreviewMode();
|
ExitPreviewMode();
|
||||||
GameObjectMarker marker = GameObject.FindObjectOfType<GameObjectMarker>();
|
GameObjectMarker marker = GameObject.FindFirstObjectByType<GameObjectMarker>();
|
||||||
handPreviewSave.LoadInto(marker.GetComponent<VR_Grabbable>());
|
handPreviewSave.LoadInto(marker.GetComponent<VR_Grabbable>());
|
||||||
GameObject.DestroyImmediate(marker);
|
GameObject.DestroyImmediate(marker);
|
||||||
}
|
}
|
||||||
@@ -131,4 +131,3 @@ namespace VRSDK.EditorCode
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace VRSDK
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
Player player = FindObjectOfType<Player>();
|
Player player = FindFirstObjectByType<Player>();
|
||||||
gameOverScreenFader = player.GameOverScreenFader;
|
gameOverScreenFader = player.GameOverScreenFader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,4 +123,3 @@ namespace VRSDK
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace VRSDK
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
characterController = FindObjectOfType<VR_CharacterController>();
|
characterController = FindFirstObjectByType<VR_CharacterController>();
|
||||||
|
|
||||||
if (characterController != null)
|
if (characterController != null)
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,7 @@ namespace VRSDK
|
|||||||
|
|
||||||
if (anchorPoint == null)
|
if (anchorPoint == null)
|
||||||
{
|
{
|
||||||
Player player = FindObjectOfType<Player>();
|
Player player = FindFirstObjectByType<Player>();
|
||||||
anchorPoint = player.PocketsAnchorPoint;
|
anchorPoint = player.PocketsAnchorPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ namespace VRSDK
|
|||||||
|
|
||||||
private void SetTeleportCallback()
|
private void SetTeleportCallback()
|
||||||
{
|
{
|
||||||
VR_TeleportHandler teleportHandler = FindObjectOfType<VR_TeleportHandler>();
|
VR_TeleportHandler teleportHandler = FindFirstObjectByType<VR_TeleportHandler>();
|
||||||
|
|
||||||
if (teleportHandler != null)
|
if (teleportHandler != null)
|
||||||
{
|
{
|
||||||
@@ -102,4 +102,3 @@ namespace VRSDK
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Platinio
|
|||||||
{
|
{
|
||||||
|
|
||||||
//get all the singletones
|
//get all the singletones
|
||||||
T[] singletons = GameObject.FindObjectsOfType( typeof(T) ) as T[];
|
T[] singletons = FindObjectsByType<T>(FindObjectsSortMode.None);
|
||||||
|
|
||||||
if(singletons != null)
|
if(singletons != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,10 +18,9 @@ namespace VRSDK
|
|||||||
{
|
{
|
||||||
for (int n = 0; n < wallCubePartArray.Length; n++)
|
for (int n = 0; n < wallCubePartArray.Length; n++)
|
||||||
{
|
{
|
||||||
wallCubePartArray[n].Reset( resetTime );
|
wallCubePartArray[n].ResetPart( resetTime );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace VRSDK
|
|||||||
rb = GetComponent<Rigidbody>();
|
rb = GetComponent<Rigidbody>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset(float t)
|
public void ResetPart(float t)
|
||||||
{
|
{
|
||||||
rb.isKinematic = true;
|
rb.isKinematic = true;
|
||||||
|
|
||||||
@@ -64,4 +64,3 @@ namespace VRSDK
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace VRSDK
|
|||||||
public HandPhysics(HistoryBuffer buffer)
|
public HandPhysics(HistoryBuffer buffer)
|
||||||
{
|
{
|
||||||
historyBuffer = buffer;
|
historyBuffer = buffer;
|
||||||
characterController = MonoBehaviour.FindObjectOfType<VR_CharacterController>();
|
characterController = MonoBehaviour.FindFirstObjectByType<VR_CharacterController>();
|
||||||
|
|
||||||
trackingSpace = VR_Manager.instance.Player.TrackingSpace;
|
trackingSpace = VR_Manager.instance.Player.TrackingSpace;
|
||||||
|
|
||||||
@@ -148,4 +148,3 @@ namespace VRSDK
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,17 +95,17 @@ namespace VRSDK
|
|||||||
return GetAxis1D(button) > 0.25f;
|
return GetAxis1D(button) > 0.25f;
|
||||||
case VR_InputButton.Primary:
|
case VR_InputButton.Primary:
|
||||||
#if UNITY_XR
|
#if UNITY_XR
|
||||||
thisInputDevice.IsPressed(InputHelpers.Button.PrimaryButton, out value);
|
thisInputDevice.TryGetFeatureValue(CommonUsages.primaryButton, out value);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case VR_InputButton.Secondary:
|
case VR_InputButton.Secondary:
|
||||||
#if UNITY_XR
|
#if UNITY_XR
|
||||||
thisInputDevice.IsPressed(InputHelpers.Button.SecondaryButton, out value);
|
thisInputDevice.TryGetFeatureValue(CommonUsages.secondaryButton, out value);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case VR_InputButton.TumbstickPress:
|
case VR_InputButton.TumbstickPress:
|
||||||
#if UNITY_XR
|
#if UNITY_XR
|
||||||
thisInputDevice.IsPressed(InputHelpers.Button.Primary2DAxisClick, out value);
|
thisInputDevice.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out value);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -158,4 +158,3 @@ namespace VRSDK
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
namespace VRSDK.Locomotion
|
namespace VRSDK.Locomotion
|
||||||
{
|
{
|
||||||
//this scripts handles aim marker position and rotation
|
//this scripts handles aim marker position and rotation
|
||||||
public class VR_AimMarker : MonoBehaviour
|
public class VR_AimMarker : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private GameObject marker = null;
|
[SerializeField] private GameObject marker = null;
|
||||||
[SerializeField] private BoxCollider collider = null;
|
[FormerlySerializedAs("collider")]
|
||||||
|
[SerializeField] private BoxCollider markerCollider = null;
|
||||||
[SerializeField] private float slopeLimit;
|
[SerializeField] private float slopeLimit;
|
||||||
|
|
||||||
public GameObject Marker { get { return marker; } }
|
public GameObject Marker { get { return marker; } }
|
||||||
public BoxCollider Collider { get { return collider; } }
|
public BoxCollider Collider { get { return markerCollider; } }
|
||||||
public float SlopeLimit { get { return slopeLimit; } }
|
public float SlopeLimit { get { return slopeLimit; } }
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
@@ -52,4 +55,3 @@ namespace VRSDK.Locomotion
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,11 +88,13 @@ namespace VRSDK
|
|||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
public float CameraHeight;
|
public float CameraHeight;
|
||||||
|
|
||||||
|
#if SDK_OCULUS
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This event is raised after the character controller is moved. This is used by the OVRAvatarLocomotion script to keep the avatar transform synchronized
|
/// This event is raised after the character controller is moved. This is used by the OVRAvatarLocomotion script to keep the avatar transform synchronized
|
||||||
/// with the OVRPlayerController.
|
/// with the OVRPlayerController.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<Transform> TransformUpdated;
|
public event Action<Transform> TransformUpdated;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This bool is set to true whenever the player controller has been teleported. It is reset after every frame. Some systems, such as
|
/// This bool is set to true whenever the player controller has been teleported. It is reset after every frame. Some systems, such as
|
||||||
@@ -177,7 +179,9 @@ namespace VRSDK
|
|||||||
private float SimulationRate = 60f;
|
private float SimulationRate = 60f;
|
||||||
private float buttonRotation = 0f;
|
private float buttonRotation = 0f;
|
||||||
private bool ReadyToSnapTurn; // Set to true when a snap turn has occurred, code requires one frame of centered thumbstick to enable another snap turn.
|
private bool ReadyToSnapTurn; // Set to true when a snap turn has occurred, code requires one frame of centered thumbstick to enable another snap turn.
|
||||||
|
#if SDK_OCULUS
|
||||||
private bool playerControllerEnabled = false;
|
private bool playerControllerEnabled = false;
|
||||||
|
#endif
|
||||||
private float moveInfluence = 0.0f;
|
private float moveInfluence = 0.0f;
|
||||||
public Vector3 lastPosition = Vector3.zero;
|
public Vector3 lastPosition = Vector3.zero;
|
||||||
private Vector3 velocity = Vector3.zero;
|
private Vector3 velocity = Vector3.zero;
|
||||||
@@ -409,8 +413,6 @@ namespace VRSDK
|
|||||||
moveRight = Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow);
|
moveRight = Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow);
|
||||||
moveBack = Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow);
|
moveBack = Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow);
|
||||||
#endif
|
#endif
|
||||||
bool dpad_move = false;
|
|
||||||
|
|
||||||
MoveScale = 1.0f;
|
MoveScale = 1.0f;
|
||||||
|
|
||||||
if ((moveForward && moveLeft) || (moveForward && moveRight) || (moveBack && moveLeft) || (moveBack && moveRight))
|
if ((moveForward && moveLeft) || (moveForward && moveRight) || (moveBack && moveLeft) || (moveBack && moveRight))
|
||||||
@@ -427,6 +429,7 @@ namespace VRSDK
|
|||||||
|
|
||||||
// Run!
|
// Run!
|
||||||
#if !UNITY_XR
|
#if !UNITY_XR
|
||||||
|
bool dpad_move = false;
|
||||||
if (dpad_move || Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
|
if (dpad_move || Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
|
||||||
moveInfluence *= 2.0f;
|
moveInfluence *= 2.0f;
|
||||||
#endif
|
#endif
|
||||||
@@ -713,4 +716,3 @@ namespace VRSDK
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ namespace VRSDK
|
|||||||
|
|
||||||
private void FindOrCreate_VR_Manager()
|
private void FindOrCreate_VR_Manager()
|
||||||
{
|
{
|
||||||
if (FindObjectOfType<VR_Manager>() == null)
|
if (FindFirstObjectByType<VR_Manager>() == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("you need a VR_Manager active in the scene in order to use VR Shooter Kit");
|
Debug.LogError("you need a VR_Manager active in the scene in order to use VR Shooter Kit");
|
||||||
}
|
}
|
||||||
@@ -630,4 +630,3 @@ namespace VRSDK
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ namespace VRSDK
|
|||||||
{
|
{
|
||||||
private float minAcelerationThreshold = 0.0f;
|
private float minAcelerationThreshold = 0.0f;
|
||||||
private float maxAcelerationThreshold = 0.0f;
|
private float maxAcelerationThreshold = 0.0f;
|
||||||
private int sampleCount = 0;
|
|
||||||
|
|
||||||
private VR_Controller controller = null;
|
private VR_Controller controller = null;
|
||||||
private GesturePhase rotationGesturePhase = GesturePhase.Tracking;
|
private GesturePhase rotationGesturePhase = GesturePhase.Tracking;
|
||||||
private Quaternion rotationGesturefromQuaternion = Quaternion.identity;
|
private Quaternion rotationGesturefromQuaternion = Quaternion.identity;
|
||||||
@@ -128,4 +126,3 @@ namespace VRSDK
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ namespace VRSDK
|
|||||||
protected bool preventDefault = false;
|
protected bool preventDefault = false;
|
||||||
protected float velocityChangeThreshold = 10f;
|
protected float velocityChangeThreshold = 10f;
|
||||||
protected float angularVelocityChangeThreshold = 20f;
|
protected float angularVelocityChangeThreshold = 20f;
|
||||||
private bool previousUseGravityState = false;
|
|
||||||
private bool previousGravityState = false;
|
|
||||||
private VR_Controller lastInteractController = null;
|
private VR_Controller lastInteractController = null;
|
||||||
private bool objectWasThrow = false;
|
private bool objectWasThrow = false;
|
||||||
protected bool canUseDropZone = true;
|
protected bool canUseDropZone = true;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace VRSDK
|
|||||||
|
|
||||||
#region PUBLIC
|
#region PUBLIC
|
||||||
public VR_SDK CurrentSDK { get { return currentSDK; } }
|
public VR_SDK CurrentSDK { get { return currentSDK; } }
|
||||||
|
public ControllerGestureConfig GestureConfig { get { return gestureConfig; } }
|
||||||
public List<VR_Interactable> InteractList { get { return interactList; } }
|
public List<VR_Interactable> InteractList { get { return interactList; } }
|
||||||
public List<VR_Highlight> HighlightList { get { return highlightList; } }
|
public List<VR_Highlight> HighlightList { get { return highlightList; } }
|
||||||
public List<VR_Grabbable> GrabbableList { get { return grabbableList; } }
|
public List<VR_Grabbable> GrabbableList { get { return grabbableList; } }
|
||||||
@@ -43,7 +44,7 @@ namespace VRSDK
|
|||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
player = FindObjectOfType<VR_Player>();
|
player = FindFirstObjectByType<VR_Player>();
|
||||||
player.Construct();
|
player.Construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,4 +141,3 @@ namespace VRSDK
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace VRSDK
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return FindObjectOfType<CharacterController>();
|
return FindFirstObjectByType<CharacterController>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,4 +109,3 @@ namespace VRSDK
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace VRSDK
|
|||||||
|
|
||||||
public float SpeedModifier { get { return speedModifier; } }
|
public float SpeedModifier { get { return speedModifier; } }
|
||||||
public float AngularSpeedModifier { get { return aungularSpeedModifier; } }
|
public float AngularSpeedModifier { get { return aungularSpeedModifier; } }
|
||||||
bool throwed = false;
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -39,4 +38,3 @@ namespace VRSDK
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ MonoBehaviour:
|
|||||||
m_OccludeARHitsWith2DObjects: 0
|
m_OccludeARHitsWith2DObjects: 0
|
||||||
m_ScaleMode: 0
|
m_ScaleMode: 0
|
||||||
m_UIPressInput:
|
m_UIPressInput:
|
||||||
m_InputSourceMode: 2
|
m_InputSourceMode: 1
|
||||||
m_InputActionPerformed:
|
m_InputActionPerformed:
|
||||||
m_Name: UI Press
|
m_Name: UI Press
|
||||||
m_Type: 1
|
m_Type: 1
|
||||||
@@ -259,7 +259,15 @@ MonoBehaviour:
|
|||||||
m_Id: 0630124c-531b-4795-acfe-690be0b93310
|
m_Id: 0630124c-531b-4795-acfe-690be0b93310
|
||||||
m_Processors:
|
m_Processors:
|
||||||
m_Interactions:
|
m_Interactions:
|
||||||
m_SingletonActionBindings: []
|
m_SingletonActionBindings:
|
||||||
|
- m_Name:
|
||||||
|
m_Id: a1b2c3d4-1111-2222-3333-444455556666
|
||||||
|
m_Path: <XRController>{RightHand}/triggerPressed
|
||||||
|
m_Interactions:
|
||||||
|
m_Processors:
|
||||||
|
m_Groups:
|
||||||
|
m_Action: UI Press
|
||||||
|
m_Flags: 0
|
||||||
m_Flags: 0
|
m_Flags: 0
|
||||||
m_InputActionValue:
|
m_InputActionValue:
|
||||||
m_Name: UI Press Value
|
m_Name: UI Press Value
|
||||||
@@ -927,7 +935,7 @@ MonoBehaviour:
|
|||||||
m_OccludeARHitsWith2DObjects: 0
|
m_OccludeARHitsWith2DObjects: 0
|
||||||
m_ScaleMode: 0
|
m_ScaleMode: 0
|
||||||
m_UIPressInput:
|
m_UIPressInput:
|
||||||
m_InputSourceMode: 2
|
m_InputSourceMode: 1
|
||||||
m_InputActionPerformed:
|
m_InputActionPerformed:
|
||||||
m_Name: UI Press
|
m_Name: UI Press
|
||||||
m_Type: 1
|
m_Type: 1
|
||||||
@@ -935,7 +943,15 @@ MonoBehaviour:
|
|||||||
m_Id: bc4a4f29-0c8c-48eb-b453-4183b34bc238
|
m_Id: bc4a4f29-0c8c-48eb-b453-4183b34bc238
|
||||||
m_Processors:
|
m_Processors:
|
||||||
m_Interactions:
|
m_Interactions:
|
||||||
m_SingletonActionBindings: []
|
m_SingletonActionBindings:
|
||||||
|
- m_Name:
|
||||||
|
m_Id: b2c3d4e5-aaaa-bbbb-cccc-ddddeeeeffff
|
||||||
|
m_Path: <XRController>{LeftHand}/triggerPressed
|
||||||
|
m_Interactions:
|
||||||
|
m_Processors:
|
||||||
|
m_Groups:
|
||||||
|
m_Action: UI Press
|
||||||
|
m_Flags: 0
|
||||||
m_Flags: 0
|
m_Flags: 0
|
||||||
m_InputActionValue:
|
m_InputActionValue:
|
||||||
m_Name: UI Press Value
|
m_Name: UI Press Value
|
||||||
|
|||||||
@@ -1625,7 +1625,7 @@ RectTransform:
|
|||||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
m_AnchoredPosition: {x: 0, y: 0}
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
m_SizeDelta: {x: 890, y: 666}
|
m_SizeDelta: {x: 850, y: 800}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!114 &359789290
|
--- !u!114 &359789290
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@@ -1647,7 +1647,7 @@ MonoBehaviour:
|
|||||||
m_OnCullStateChanged:
|
m_OnCullStateChanged:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_Sprite: {fileID: 21300000, guid: eb6ca18f47347e94aa2011847ccd1fa9, type: 3}
|
m_Sprite: {fileID: 21300000, guid: 6765d030cfc5fc84e9523fcd9439be89, type: 3}
|
||||||
m_Type: 0
|
m_Type: 0
|
||||||
m_PreserveAspect: 0
|
m_PreserveAspect: 0
|
||||||
m_FillCenter: 1
|
m_FillCenter: 1
|
||||||
@@ -4145,6 +4145,7 @@ GameObject:
|
|||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 1051307065}
|
- component: {fileID: 1051307065}
|
||||||
- component: {fileID: 1051307064}
|
- component: {fileID: 1051307064}
|
||||||
|
- component: {fileID: 1051307066}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: VR_Manager
|
m_Name: VR_Manager
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -4184,6 +4185,18 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 622937451}
|
m_Father: {fileID: 622937451}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &1051307066
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1051307063}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 38f89babd4e99734aac47edbc4f87aa3, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: Assembly-CSharp::VRBeats.VRPointerSetup
|
||||||
--- !u!4 &1143639918 stripped
|
--- !u!4 &1143639918 stripped
|
||||||
Transform:
|
Transform:
|
||||||
m_CorrespondingSourceObject: {fileID: 748387694978730046, guid: f5d43ad86a21ab1479a999e16359b99b,
|
m_CorrespondingSourceObject: {fileID: 748387694978730046, guid: f5d43ad86a21ab1479a999e16359b99b,
|
||||||
@@ -5145,7 +5158,7 @@ MonoBehaviour:
|
|||||||
m_CheckFor3DOcclusion: 0
|
m_CheckFor3DOcclusion: 0
|
||||||
m_BlockingMask:
|
m_BlockingMask:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Bits: 2147483647
|
m_Bits: 4294967295
|
||||||
m_RaycastTriggerInteraction: 1
|
m_RaycastTriggerInteraction: 1
|
||||||
--- !u!114 &1445586367
|
--- !u!114 &1445586367
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@@ -5186,7 +5199,7 @@ MonoBehaviour:
|
|||||||
m_FallbackScreenDPI: 96
|
m_FallbackScreenDPI: 96
|
||||||
m_DefaultSpriteDPI: 96
|
m_DefaultSpriteDPI: 96
|
||||||
m_DynamicPixelsPerUnit: 1
|
m_DynamicPixelsPerUnit: 1
|
||||||
m_PresetInfoIsWorld: 0
|
m_PresetInfoIsWorld: 1
|
||||||
--- !u!223 &1445586369
|
--- !u!223 &1445586369
|
||||||
Canvas:
|
Canvas:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -7446,7 +7459,7 @@ MonoBehaviour:
|
|||||||
m_CheckFor3DOcclusion: 0
|
m_CheckFor3DOcclusion: 0
|
||||||
m_BlockingMask:
|
m_BlockingMask:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Bits: 2147483647
|
m_Bits: 4294967295
|
||||||
m_RaycastTriggerInteraction: 1
|
m_RaycastTriggerInteraction: 1
|
||||||
--- !u!114 &1965927025
|
--- !u!114 &1965927025
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@@ -7487,7 +7500,7 @@ MonoBehaviour:
|
|||||||
m_FallbackScreenDPI: 96
|
m_FallbackScreenDPI: 96
|
||||||
m_DefaultSpriteDPI: 96
|
m_DefaultSpriteDPI: 96
|
||||||
m_DynamicPixelsPerUnit: 1
|
m_DynamicPixelsPerUnit: 1
|
||||||
m_PresetInfoIsWorld: 0
|
m_PresetInfoIsWorld: 1
|
||||||
--- !u!223 &1965927027
|
--- !u!223 &1965927027
|
||||||
Canvas:
|
Canvas:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ namespace VRBeats
|
|||||||
[SerializeField] private float fadeOutTime = 4.0f;
|
[SerializeField] private float fadeOutTime = 4.0f;
|
||||||
|
|
||||||
private AudioSource audioSource = null;
|
private AudioSource audioSource = null;
|
||||||
|
private double scheduledDspStartTime = -1.0;
|
||||||
|
private bool hasScheduledClip = false;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
@@ -43,13 +45,37 @@ namespace VRBeats
|
|||||||
|
|
||||||
public void PlayClip(AudioClip clip)
|
public void PlayClip(AudioClip clip)
|
||||||
{
|
{
|
||||||
audioSource.clip = clip;
|
PlayClipScheduled(clip);
|
||||||
audioSource.Play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CurrentTime => audioSource != null ? audioSource.time : 0f;
|
public double PlayClipScheduled(AudioClip clip, double delaySeconds = 0.1)
|
||||||
|
{
|
||||||
|
ResetThisComponent();
|
||||||
|
audioSource.Stop();
|
||||||
|
audioSource.clip = clip;
|
||||||
|
audioSource.time = 0.0f;
|
||||||
|
|
||||||
|
scheduledDspStartTime = AudioSettings.dspTime + delaySeconds;
|
||||||
|
hasScheduledClip = true;
|
||||||
|
audioSource.PlayScheduled(scheduledDspStartTime);
|
||||||
|
|
||||||
|
return scheduledDspStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float CurrentTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (audioSource == null)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
if (hasScheduledClip)
|
||||||
|
return (float)(AudioSettings.dspTime - scheduledDspStartTime);
|
||||||
|
|
||||||
|
return audioSource.time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ namespace VRBeats
|
|||||||
|
|
||||||
public override void DoDamage(DamageInfo info)
|
public override void DoDamage(DamageInfo info)
|
||||||
{
|
{
|
||||||
|
// 방향·속도·색상이 맞지 않으면 자르지 않음
|
||||||
|
var beatCube = GetComponent<VR_BeatCube>();
|
||||||
|
if (beatCube != null && !beatCube.IsCutIntentValid(info as BeatDamageInfo))
|
||||||
|
return;
|
||||||
|
|
||||||
onCut.Invoke(info);
|
onCut.Invoke(info);
|
||||||
|
|
||||||
var beatDamageInfo = info as BeatDamageInfo;
|
var beatDamageInfo = info as BeatDamageInfo;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace VRBeats
|
|||||||
public class VR_BeatCube : MonoBehaviour
|
public class VR_BeatCube : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private float minCutSpeed = 0.5f;
|
[SerializeField] private float minCutSpeed = 0.5f;
|
||||||
[SerializeField] private OnSliceAction sliceAction = null;
|
[SerializeField] private float maxCutAngle = 40f;
|
||||||
[SerializeField] private GameEvent onCorrectSlice = null;
|
[SerializeField] private GameEvent onCorrectSlice = null;
|
||||||
[SerializeField] private GameEvent onIncorrectSlice = null;
|
[SerializeField] private GameEvent onIncorrectSlice = null;
|
||||||
[SerializeField] private GameEvent onPlayerMiss = null;
|
[SerializeField] private GameEvent onPlayerMiss = null;
|
||||||
@@ -65,7 +65,7 @@ namespace VRBeats
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsCutIntentValid(BeatDamageInfo info)
|
public bool IsCutIntentValid(BeatDamageInfo info)
|
||||||
{
|
{
|
||||||
if (info == null) return false;
|
if (info == null) return false;
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ namespace VRBeats
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
float cutAngle = Vector2.Angle(transform.up, info.hitDir);
|
float cutAngle = Vector2.Angle(transform.up, info.hitDir);
|
||||||
return info.colorSide == ThisColorSide && cutAngle < 80.0f;
|
return info.colorSide == ThisColorSide && cutAngle < maxCutAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,4 +111,3 @@ namespace VRBeats
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ namespace VRBeats
|
|||||||
[SerializeField] private BoxCollider playZone = null;
|
[SerializeField] private BoxCollider playZone = null;
|
||||||
[SerializeField] private Transform player = null;
|
[SerializeField] private Transform player = null;
|
||||||
[SerializeField] private VR_BeatSettings settings = null;
|
[SerializeField] private VR_BeatSettings settings = null;
|
||||||
[SerializeField] private GameEvent onGameOver = null;
|
|
||||||
|
|
||||||
private AudioManager audioManager = null;
|
private AudioManager audioManager = null;
|
||||||
private EnviromentController enviromentController = null;
|
private EnviromentController enviromentController = null;
|
||||||
private PlayableDirector playableDirector = null;
|
private PlayableDirector playableDirector = null;
|
||||||
@@ -24,20 +22,17 @@ namespace VRBeats
|
|||||||
|
|
||||||
public Transform Player { get { return player; } }
|
public Transform Player { get { return player; } }
|
||||||
|
|
||||||
private int playerConsecutiveMiss = 0;
|
|
||||||
|
|
||||||
protected override void Awake()
|
protected override void Awake()
|
||||||
{
|
{
|
||||||
base.Awake();
|
base.Awake();
|
||||||
audioManager = FindObjectOfType<AudioManager>();
|
audioManager = FindFirstObjectByType<AudioManager>();
|
||||||
enviromentController = FindObjectOfType<EnviromentController>();
|
enviromentController = FindFirstObjectByType<EnviromentController>();
|
||||||
playableDirector = FindObjectOfType<PlayableDirector>();
|
playableDirector = FindFirstObjectByType<PlayableDirector>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Start()
|
protected override void Start()
|
||||||
{
|
{
|
||||||
base.Start();
|
base.Start();
|
||||||
playerConsecutiveMiss = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ namespace VRBeats
|
|||||||
{
|
{
|
||||||
public class VR_InteractorController : MonoBehaviour
|
public class VR_InteractorController : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
[SerializeField] private bool disableOnAwake = true;
|
||||||
|
|
||||||
private UnityEngine.XR.Interaction.Toolkit.Interactors.XRRayInteractor rayInteractor = null;
|
private UnityEngine.XR.Interaction.Toolkit.Interactors.XRRayInteractor rayInteractor = null;
|
||||||
private UnityEngine.XR.Interaction.Toolkit.Interactors.Visuals.XRInteractorLineVisual interactorLineVisual = null;
|
private UnityEngine.XR.Interaction.Toolkit.Interactors.Visuals.XRInteractorLineVisual interactorLineVisual = null;
|
||||||
private LineRenderer lineRender = null;
|
private LineRenderer lineRender = null;
|
||||||
@@ -15,22 +17,54 @@ namespace VRBeats
|
|||||||
interactorLineVisual = GetComponent<UnityEngine.XR.Interaction.Toolkit.Interactors.Visuals.XRInteractorLineVisual>();
|
interactorLineVisual = GetComponent<UnityEngine.XR.Interaction.Toolkit.Interactors.Visuals.XRInteractorLineVisual>();
|
||||||
lineRender = GetComponent<LineRenderer>();
|
lineRender = GetComponent<LineRenderer>();
|
||||||
|
|
||||||
|
if (disableOnAwake)
|
||||||
DisableXRRayInteractorComponents();
|
DisableXRRayInteractorComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisableXRRayInteractorComponents()
|
public void DisableXRRayInteractorComponents()
|
||||||
{
|
{
|
||||||
rayInteractor.enabled = false;
|
if (rayInteractor != null)
|
||||||
interactorLineVisual.enabled = false;
|
rayInteractor.enabled = false;
|
||||||
lineRender.enabled = false;
|
if (interactorLineVisual != null)
|
||||||
|
interactorLineVisual.enabled = false;
|
||||||
|
if (lineRender != null)
|
||||||
|
lineRender.enabled = false;
|
||||||
|
|
||||||
|
// VRPointerController 위치가 컨트롤러/레이 구조에 따라 달라질 수 있어서 계층 전체에서 찾는다.
|
||||||
|
var pointer = FindPointerController();
|
||||||
|
if (pointer != null)
|
||||||
|
pointer.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnableXRRayInteractorComponents()
|
public void EnableXRRayInteractorComponents()
|
||||||
{
|
{
|
||||||
rayInteractor.enabled = true;
|
if (rayInteractor != null)
|
||||||
interactorLineVisual.enabled = true;
|
rayInteractor.enabled = true;
|
||||||
lineRender.enabled = true;
|
if (interactorLineVisual != null)
|
||||||
|
interactorLineVisual.enabled = true;
|
||||||
|
if (lineRender != null)
|
||||||
|
lineRender.enabled = true;
|
||||||
|
|
||||||
|
var pointer = FindPointerController();
|
||||||
|
if (pointer != null)
|
||||||
|
pointer.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VRPointerController FindPointerController()
|
||||||
|
{
|
||||||
|
var pointer = GetComponent<VRPointerController>();
|
||||||
|
if (pointer != null)
|
||||||
|
return pointer;
|
||||||
|
|
||||||
|
pointer = GetComponentInParent<VRPointerController>();
|
||||||
|
if (pointer != null)
|
||||||
|
return pointer;
|
||||||
|
|
||||||
|
pointer = GetComponentInChildren<VRPointerController>(true);
|
||||||
|
if (pointer != null)
|
||||||
|
return pointer;
|
||||||
|
|
||||||
|
return transform.root.GetComponentInChildren<VRPointerController>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ namespace VRBeats
|
|||||||
|
|
||||||
private void Rotate()
|
private void Rotate()
|
||||||
{
|
{
|
||||||
float rotation = Random.Range(-maxRotation , maxRotation);
|
float direction = Random.value < 0.5f ? -1.0f : 1.0f;
|
||||||
|
float rotation = Random.Range(minRotation, maxRotation) * direction;
|
||||||
transform.RotateTween( Vector3.forward , rotation , animTime).SetEase(ease).SetOnComplete( Rotate );
|
transform.RotateTween( Vector3.forward , rotation , animTime).SetEase(ease).SetOnComplete( Rotate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace VRBeats
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VolumeSingleton[] instancesArray = FindObjectsOfType<VolumeSingleton>();
|
VolumeSingleton[] instancesArray = FindObjectsByType<VolumeSingleton>(FindObjectsSortMode.None);
|
||||||
|
|
||||||
foreach (var volumeSingleton in instancesArray)
|
foreach (var volumeSingleton in instancesArray)
|
||||||
{
|
{
|
||||||
@@ -30,4 +30,3 @@ namespace VRBeats
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Platinio.UI
|
|||||||
Canvas canvas = null;
|
Canvas canvas = null;
|
||||||
|
|
||||||
//just return the first encounter canvas
|
//just return the first encounter canvas
|
||||||
canvas = GameObject.FindObjectOfType<Canvas>();
|
canvas = GameObject.FindFirstObjectByType<Canvas>();
|
||||||
|
|
||||||
if (canvas != null)
|
if (canvas != null)
|
||||||
{
|
{
|
||||||
@@ -144,4 +144,3 @@ namespace Platinio.UI
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace VRBeats
|
|||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
enviromentController = FindObjectOfType<EnviromentController>();
|
enviromentController = FindFirstObjectByType<EnviromentController>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace VRBeats
|
|||||||
initialValue += "0";
|
initialValue += "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
scoreManager = FindObjectOfType<ScoreManager>();
|
scoreManager = FindFirstObjectByType<ScoreManager>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,4 +58,3 @@ namespace VRBeats
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6fb30ae126e70f441a51ad0652c5e708
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,18 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b1b477339527b404585e10e42a15d653
|
||||||
|
VideoClipImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 3
|
||||||
|
frameRange: 0
|
||||||
|
startFrame: -1
|
||||||
|
endFrame: -1
|
||||||
|
colorSpace: 0
|
||||||
|
deinterlace: 0
|
||||||
|
encodeAlpha: 0
|
||||||
|
flipVertical: 0
|
||||||
|
flipHorizontal: 0
|
||||||
|
importAudio: 1
|
||||||
|
targetSettings: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
@@ -0,0 +1,143 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6765d030cfc5fc84e9523fcd9439be89
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 0
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: iOS
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 5e97eb03825dee720800000000000000
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
+135
-68
@@ -7,6 +7,103 @@ Meta Quest용 VR Beat Saber 클론. Beat Sage API로 노래를 자동 채보하
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 현재 상태 (2026-05-26)
|
||||||
|
|
||||||
|
현재 저장소는 VRBeatsKit 기반 프로젝트 위에 커스텀 곡 선택/생성/NAS 연동 흐름을 붙인 상태다.
|
||||||
|
|
||||||
|
- Unity 버전: `6000.3.12f1`
|
||||||
|
- 현재 브랜치: `main`
|
||||||
|
- 원격 저장소: `origin` = `https://whdwo798.synology.me/whdwo798/BeatSaber.git`
|
||||||
|
- 최근 푸시 커밋: `182d2c9 fix: stabilize VR UI and song playback`
|
||||||
|
- `dotnet build VRBeatSaber.slnx --no-incremental` 결과: 오류 0개, 경고 0개
|
||||||
|
- 현재 워킹트리에는 큐브 간격 보정과 경고 제거 작업이 커밋 전 변경으로 남아 있다.
|
||||||
|
|
||||||
|
### 실제 씬 구성
|
||||||
|
|
||||||
|
현재 Build Settings는 아래 순서다.
|
||||||
|
|
||||||
|
1. `Assets/VRBeatsKit/Scenes/Menu.unity`
|
||||||
|
2. `Assets/VRBeatsKit/Scenes/BoxingStyle.unity`
|
||||||
|
3. `Assets/Scenes/SongCreator.unity`
|
||||||
|
4. `Assets/VRBeatsKit/Scenes/SaberStyle.unity`
|
||||||
|
5. `Assets/Scenes/Game.unity`
|
||||||
|
|
||||||
|
문서 아래쪽에 남아 있는 `Intro -> SongSelect -> Game -> SongCreator` 흐름은 목표 설계에 가깝다. 현재 실제 진입점은 VRBeatsKit `Menu.unity`이며, 그 안의 `SongSelect` 패널이 커스텀 곡 선택 UI 역할을 한다.
|
||||||
|
|
||||||
|
### 현재 구현된 주요 흐름
|
||||||
|
|
||||||
|
```text
|
||||||
|
Menu.unity / SongSelect
|
||||||
|
-> DownloadManager가 NAS 정적 서버의 songs.json 로드
|
||||||
|
-> SongDetailPanel에서 곡/난이도 다운로드
|
||||||
|
-> GameSession.SelectedSong / SelectedDifficulty 설정
|
||||||
|
-> Game.unity 로드
|
||||||
|
|
||||||
|
Game.unity
|
||||||
|
-> SongController가 temporaryCachePath의 mp3 + map json 로드
|
||||||
|
-> VRBeats.AudioManager로 음악 재생
|
||||||
|
-> 오디오 시간 기준으로 VR_BeatManager.Spawn() 호출
|
||||||
|
-> VR_BeatCube / Cuttable / DamageSaber가 색상, 방향, 속도 판정
|
||||||
|
|
||||||
|
SongCreator.unity
|
||||||
|
-> SongCreatorManager가 로컬 mp3 또는 직접 mp3 URL 입력
|
||||||
|
-> BeatSageUploader가 Beat Sage 요청/폴링/ZIP 다운로드
|
||||||
|
-> BeatSageConverter가 .dat를 NoteData로 변환
|
||||||
|
-> NasPublisher가 mp3, map json, songs.json을 Synology NAS에 업로드
|
||||||
|
```
|
||||||
|
|
||||||
|
### 최근 반영된 변경
|
||||||
|
|
||||||
|
- `Assets/Script/SongController.cs`
|
||||||
|
- Beat Saber 4라인 좌표 매핑을 넓혀 인접 큐브가 가로로 겹치는 문제를 줄였다.
|
||||||
|
- 기존 라인 x 좌표는 대략 `-0.375, -0.125, 0.125, 0.375`였고, 현재는 `-0.63, -0.21, 0.21, 0.63`이다.
|
||||||
|
- 맵 노트 정렬을 `time -> position -> lineLayer` 순서로 바꿔 같은 시간대 노트 처리 순서를 안정화했다.
|
||||||
|
- 전체 C# 경고 제거
|
||||||
|
- `FindObjectOfType`, `FindObjectsOfType`, `InputHelpers`, `TMP_Text.enableWordWrapping`, `EditorApplication.currentScene`, 구버전 `PlayerSettings` API를 최신 API로 교체했다.
|
||||||
|
- 미사용 필드/변수, 상속 멤버 숨김, Unity 메시지 시그니처 경고를 정리했다.
|
||||||
|
- 최종 확인 빌드: `dotnet build VRBeatSaber.slnx --no-incremental` = 경고 0개, 오류 0개.
|
||||||
|
- `Assets/Script/VRPointerController.cs`, `VRPointerSetup.cs` 추가
|
||||||
|
- VR 컨트롤러 레이로 Unity UI 버튼을 직접 hover/click 처리한다.
|
||||||
|
- `Game` 씬에서는 게임오버 전까지 비활성화하고, 메뉴 계열 씬에서는 활성화한다.
|
||||||
|
- `Assets/Script/VRPointerSetup.cs`
|
||||||
|
- `DontDestroyOnLoad` 싱글턴으로 변경되어 `Menu -> SongCreator -> Game` 같은 씬 전환 후에도 포인터를 다시 주입한다.
|
||||||
|
- `SceneManager.sceneLoaded`마다 현재 씬 컨트롤러를 검사한다.
|
||||||
|
- `Assets/VRBeatsKit/Scripts/Core/VR_InteractorController.cs`
|
||||||
|
- XR Ray Interactor enable/disable 시 `VRPointerController`도 함께 제어한다.
|
||||||
|
- 컨트롤러 구조 차이를 고려해 현재 오브젝트, 부모, 자식, 루트 하위에서 `VRPointerController`를 찾는다.
|
||||||
|
- `Assets/VRBeatsKit/Scripts/Core/AudioManager.cs`
|
||||||
|
- `AudioSource.Play()` 대신 `PlayScheduled()`를 사용하고, `AudioSettings.dspTime` 기준으로 `CurrentTime`을 계산한다.
|
||||||
|
- MP3 재생 시작 시점과 노트 스폰 기준 시간이 프레임 상태에 따라 흔들리는 문제를 줄이기 위한 변경이다.
|
||||||
|
- `Assets/VRBeatsKit/Scripts/Core/VR_BeatCube.cs`
|
||||||
|
- `IsCutIntentValid()`를 public으로 변경하고 `maxCutAngle`을 추가했다.
|
||||||
|
- `Assets/VRBeatsKit/Scripts/Core/Cuttable.cs`
|
||||||
|
- 색상/방향/속도가 틀린 큐브는 절단 시각 효과도 발생하지 않도록 막았다.
|
||||||
|
- `Assets/Scenes/Game.unity`
|
||||||
|
- `SongController`가 큐브 프리팹, `OnLevelComplete`, 카운트다운 텍스트와 연결되어 있다.
|
||||||
|
- `GameOverPopup`의 Back 버튼에 깨진 스크립트 참조가 있어 `LoadSceneButton`으로 복구했다.
|
||||||
|
- 현재 사용 중인 좌/우 세이버 루트 회전을 `X 45도`로 보정해 컨트롤러에서 너무 수직으로 서는 문제를 줄였다.
|
||||||
|
- `Assets/VRBeatsKit/Scenes/Menu.unity`
|
||||||
|
- `SongSelectManager`, `DownloadManager`, `SongDetailPanel`, `SongLibrary`가 연결되어 있다.
|
||||||
|
- `VRPointerSetup`이 `VR_Manager`에 추가되어 있다.
|
||||||
|
- `Assets/img/360.mp4`, `Assets/img/beatSaber.png`
|
||||||
|
- 메뉴/비주얼용 에셋으로 추가됨.
|
||||||
|
- `.gitignore`
|
||||||
|
- `*.csproj.user` 제외 추가.
|
||||||
|
- `.gitattributes`
|
||||||
|
- `*.mp4 binary` 추가.
|
||||||
|
|
||||||
|
### 현재 주의사항
|
||||||
|
|
||||||
|
1. `Assets/StreamingAssets/nas_config.json`은 현재 저장소에 없다. NAS 업로드를 테스트하려면 로컬에 직접 만들어야 하며, 절대 커밋하지 않는다.
|
||||||
|
2. `SongCreator.unity`의 직렬화된 `nasBaseUrl` 값에 끝 공백이 들어가 있다: `http://whdwo798.synology.me:5000 `. 런타임에서 `nas_config.json`으로 덮어쓰지 않으면 로그인 URL 문제가 날 수 있다.
|
||||||
|
3. `SongCreatorManager`는 난이도 토글 필드를 갖고 있지만 현재 로직은 4개 난이도(`normal`, `hard`, `expert`, `expertplus`)를 항상 전부 생성한다.
|
||||||
|
4. `manualEditorButton`은 씬에서 미연결이고 코드에서도 사용하지 않는다.
|
||||||
|
5. `Assets/img/360.mp4`는 약 192MB다. 현재 일반 Git으로 푸시되어 있으므로, 원격 정책이 바뀌면 Git LFS 전환을 검토해야 한다.
|
||||||
|
6. 큐브 간격은 수치상 겹침을 피하도록 넓혔지만, 실제 Quest 착용 테스트에서 손 위치/판정 거리/시야 피로도를 확인해야 한다.
|
||||||
|
7. SongCreator에서 생성 직후 첫 재생이 곡에 따라 늦거나 싱크가 흔들리는 체감이 있었다. 게임 씬 오디오 기준은 `AudioSettings.dspTime`으로 개선했지만, 생성/다운로드/첫 로드 전체 파이프라인은 추가 로그 검증이 필요하다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 기존 프로젝트 소스 코드
|
## 기존 프로젝트 소스 코드
|
||||||
|
|
||||||
**기존 프로젝트 전체 파일은 아래 git 저장소에서 가져온다.**
|
**기존 프로젝트 전체 파일은 아래 git 저장소에서 가져온다.**
|
||||||
@@ -168,101 +265,69 @@ SongSelect → SongCreator → (NAS 업로드) → SongSelect
|
|||||||
| `SongLibrary.cs` | 다운로드 상태 추적 (persistentDataPath) |
|
| `SongLibrary.cs` | 다운로드 상태 추적 (persistentDataPath) |
|
||||||
| `SongSelectManager.cs` | 곡 목록 UI |
|
| `SongSelectManager.cs` | 곡 목록 UI |
|
||||||
| `SongDetailPanel.cs` | 곡 상세 / 다운로드 / 플레이 버튼 |
|
| `SongDetailPanel.cs` | 곡 상세 / 다운로드 / 플레이 버튼 |
|
||||||
| `SongCreatorManager.cs` | 크리에이터 UI, 파일 선택, URL 다운로드. title/BPM 수동 입력 불필요 — info.dat에서 자동 추출. 난이도는 항상 4개 전부 생성. |
|
| `SongCreatorManager.cs` | 크리에이터 UI, 파일 선택, URL 다운로드. title/BPM 수동 입력 불필요 — info.dat에서 자동 추출. 난이도는 현재 항상 4개 전부 생성. |
|
||||||
| `IntroManager.cs` | 인트로 → SongSelect 자동 전환 |
|
| `SongController.cs` | Game 씬 실행부. 캐시된 mp3/map json을 로드하고 VRBeatsKit `VR_BeatManager.Spawn()`으로 노트를 스폰. |
|
||||||
| `DesktopUIMode.cs` | 에디터에서 XR 없이 테스트할 때 UI Raycaster 교체 |
|
| `DesktopUIMode.cs` | 에디터에서 XR 없이 테스트할 때 UI Raycaster 교체 |
|
||||||
| `ScoreManager.cs` | 싱글턴 — Score/Combo/MaxCombo/Multiplier/HP |
|
| `VRPointerController.cs` | VR 컨트롤러 레이로 UI hover/click 처리. 디버그 로그 포함. |
|
||||||
| `ScoreHUD.cs` | 점수/콤보 TMP + HP 슬라이더 |
|
| `VRPointerSetup.cs` | 씬 로드 후 손/컨트롤러 오브젝트에 `VRPointerController` 자동 주입. |
|
||||||
| `ResultsPanel.cs` | 결과 화면 (CLEAR/FAILED, 랭크 S~D) |
|
| `XRSimulatorLoader.cs` | 에디터/PC 테스트용 XR Interaction Simulator 프리팹 주입. |
|
||||||
| `SaberGlow.cs` | 검 끝 포인트 라이트 제어 |
|
|
||||||
| `SaberSkinSelector.cs` | 검 외형 선택 (PlayerPrefs 저장) |
|
|
||||||
| `CacheManager.cs` | 캐시 정리 유틸 |
|
|
||||||
|
|
||||||
### 새로 작성이 필요한 스크립트
|
### 현재 미이식/미확인 스크립트
|
||||||
|
|
||||||
| 파일 | 내용 |
|
| 파일 | 내용 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `Spawner.cs` | **VRBeatsKit 통합 버전** — 아래 상세 참고 |
|
| `IntroManager.cs` | 현재 저장소에 없음. 인트로 씬 흐름을 살릴 경우 작성/이식 필요. |
|
||||||
|
| `ScoreManager.cs`, `ScoreHUD.cs`, `ResultsPanel.cs` | 전역 네임스페이스 커스텀 점수 UI는 현재 저장소에 없음. 현재는 VRBeatsKit `VRBeats.ScoreManager`와 이벤트 자산을 사용. |
|
||||||
|
| `SaberGlow.cs`, `SaberSkinSelector.cs`, `CacheManager.cs` | 현재 저장소에 없음. 필요 시 기존 프로젝트에서 이식. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Spawner.cs 새 버전 작성 방법 (핵심)
|
## Game 실행부 현재 구현
|
||||||
|
|
||||||
기존 Spawner는 `cubePrefabs[]`(GameObject)를 Instantiate했다.
|
기존 인수인계 문서에는 `Spawner.cs`를 새로 작성하라고 되어 있었지만, 현재 저장소에서는 별도 `Spawner.cs` 대신 `Assets/Script/SongController.cs`가 그 역할을 수행한다.
|
||||||
새 버전은 `VR_BeatManager.instance.Spawn(Spawneable, SpawnEventInfo)`를 호출한다.
|
|
||||||
|
|
||||||
### 변경 포인트
|
### `SongController.cs` 핵심
|
||||||
|
|
||||||
**1. AudioSource 획득 방식 변경**
|
|
||||||
```csharp
|
```csharp
|
||||||
// 기존: [SerializeField] AudioSource audioSource;
|
private IEnumerator LoadAndPlay()
|
||||||
// 신규: VRBeatsKit AudioManager에서 가져옴
|
|
||||||
void Awake()
|
|
||||||
{
|
{
|
||||||
var am = FindObjectOfType<VRBeats.AudioManager>();
|
SongInfo song = GameSession.SelectedSong;
|
||||||
if (am != null) audioSource = am.GetComponent<AudioSource>();
|
string diff = GameSession.SelectedDifficulty;
|
||||||
|
// mp3와 map json을 Application.temporaryCachePath/beatsaber/{songId}/ 에서 로드
|
||||||
|
// 카운트다운 후 VRBeats.AudioManager.PlayClip(clip)
|
||||||
|
// SpawnRoutine(map.target) 실행
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
**2. 큐브 프리팹 타입 변경**
|
private void SpawnNote(NoteData note)
|
||||||
```csharp
|
|
||||||
// 기존: public GameObject[] cubePrefabs; (RED=0, BLUE=1)
|
|
||||||
// 신규:
|
|
||||||
public VRBeats.Spawneable redCubePrefab; // colorType == 0
|
|
||||||
public VRBeats.Spawneable blueCubePrefab; // colorType == 1
|
|
||||||
```
|
|
||||||
|
|
||||||
**3. SpawnNote() 전면 교체**
|
|
||||||
```csharp
|
|
||||||
// Beat Saber cutDirection(0~8) → VRBeats Direction 매핑
|
|
||||||
private static readonly VRBeats.Direction[] DirMap =
|
|
||||||
{
|
{
|
||||||
VRBeats.Direction.Up, // 0
|
float x = MapLaneX(note.position);
|
||||||
VRBeats.Direction.Down, // 1
|
float y = MapLayerY(note.lineLayer);
|
||||||
VRBeats.Direction.Left, // 2
|
|
||||||
VRBeats.Direction.Right, // 3
|
|
||||||
VRBeats.Direction.UpperLeft, // 4
|
|
||||||
VRBeats.Direction.UpperRight, // 5
|
|
||||||
VRBeats.Direction.LowerLeft, // 6
|
|
||||||
VRBeats.Direction.LowerRight, // 7
|
|
||||||
VRBeats.Direction.Center // 8 (dot)
|
|
||||||
};
|
|
||||||
|
|
||||||
private void SpawnNote(NoteData data)
|
var info = new SpawnEventInfo
|
||||||
{
|
|
||||||
if (VRBeats.VR_BeatManager.instance == null) return;
|
|
||||||
|
|
||||||
VRBeats.Spawneable prefab = data.colorType == 0 ? redCubePrefab : blueCubePrefab;
|
|
||||||
if (prefab == null) return;
|
|
||||||
|
|
||||||
var info = new VRBeats.SpawnEventInfo
|
|
||||||
{
|
{
|
||||||
colorSide = data.colorType == 0 ? VRBeats.ColorSide.Right : VRBeats.ColorSide.Left,
|
position = new Vector3(x, y, 0f),
|
||||||
hitDirection = DirMap[Mathf.Clamp(data.cutDirection, 0, 8)],
|
colorSide = note.colorType == 0 ? ColorSide.Left : ColorSide.Right,
|
||||||
// position: 0~3열 → -0.5~0.5, 0~2행 → -0.5~0.5
|
hitDirection = MapCutDirection(note.cutDirection),
|
||||||
position = new Vector3(
|
useSpark = true,
|
||||||
(data.position / 3.0f) - 0.5f,
|
speed = 2f,
|
||||||
(data.lineLayer / 2.0f) - 0.5f,
|
travelTimeOverride = note.time - _audio.CurrentTime,
|
||||||
0f),
|
|
||||||
speed = noteSpeed,
|
|
||||||
useSpark = true
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VRBeats.VR_BeatManager.instance.Spawn(prefab, info);
|
VR_BeatManager.instance.Spawn(cubePrefab, info);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**4. spawnPoints[] 제거** — VR_BeatManager가 PlayZone 기반으로 위치 계산하므로 불필요.
|
`travelTimeOverride`는 동시 노트가 프레임 차이로 스폰되어도 같은 타이밍에 도착하도록 `VR_BeatManager`에 추가된 값이다.
|
||||||
|
|
||||||
**5. 나머지 로직은 기존과 동일** — InitGame(), CountDown(), LoadAudioClip(), ShowResults() 등
|
현재 라인 매핑은 `LaneSpacing = 0.42f`, `LayerSpacing = 0.38f`를 사용한다. 이는 VRBeatsKit 큐브 콜라이더의 실제 폭이 기존 라인 간격보다 커서 인접 라인이 겹치던 문제를 피하기 위한 값이다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ScoreManager 충돌 없음
|
## ScoreManager 충돌 없음
|
||||||
|
|
||||||
- 우리 `ScoreManager.cs` → 전역 네임스페이스
|
- 예전 설계: 전역 네임스페이스 커스텀 `ScoreManager.cs`
|
||||||
- VRBeatsKit `Scripts/UI/ScoreManager.cs` → `namespace VRBeats`
|
- 현재 저장소: `Assets/VRBeatsKit/Scripts/UI/ScoreManager.cs`의 `VRBeats.ScoreManager` 사용
|
||||||
- 두 파일이 공존 가능. 우리 ScoreManager를 그대로 사용한다.
|
- 전역 커스텀 `ScoreManager.cs`를 다시 이식하면 네임스페이스가 달라 공존은 가능하지만, 이벤트 연결과 UI 패널을 별도로 구성해야 한다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -427,8 +492,10 @@ Application.temporaryCachePath/beatsaber/{songId}/
|
|||||||
|
|
||||||
## 알려진 주의사항
|
## 알려진 주의사항
|
||||||
|
|
||||||
1. **Game 씬 직접 Play 금지**: `GameSession.SelectedSong == null` → SongSelect로 튕김. 반드시 SongSelect 씬부터 시작.
|
1. **Game 씬 직접 Play 주의**: `GameSession.SelectedSong == null`이면 `SongController`가 오류를 로그로 남기고 진행하지 않는다. 곡 플레이는 `Menu.unity`의 SongSelect에서 선택/다운로드 후 진입해야 한다.
|
||||||
2. **NAS 업로드**: 수동 multipart body (UploadHandlerRaw) 사용. Unity 기본 multipart는 DSM에서 401 오류.
|
2. **NAS 업로드**: 수동 multipart body (UploadHandlerRaw) 사용. Unity 기본 multipart는 DSM에서 401 오류.
|
||||||
3. **AudioType.MPEG**: MP3 로딩 시 `UnityWebRequestMultimedia.GetAudioClip(uri, AudioType.MPEG)` 사용.
|
3. **AudioType.MPEG**: MP3 로딩 시 `UnityWebRequestMultimedia.GetAudioClip(uri, AudioType.MPEG)` 사용.
|
||||||
4. **Unity `??` 연산자**: Unity Object에 `??` 쓰면 fake-null을 못 잡음. 반드시 `if (x == null)` 또는 `TryGetComponent` 사용.
|
4. **Unity `??` 연산자**: Unity Object에 `??` 쓰면 fake-null을 못 잡음. 반드시 `if (x == null)` 또는 `TryGetComponent` 사용.
|
||||||
5. **씬 Build Settings 등록 필수**: Intro(0), SongSelect(1), Game(2), SongCreator(3), MapEditorScene(4)
|
5. **Build Settings 현재 상태**: 현재 등록 순서는 `Menu`, `BoxingStyle`, `SongCreator`, `SaberStyle`, `Game`이다. 예전 목표 설계의 `Intro`, `SongSelect`, `MapEditorScene`은 현재 Build Settings에 없다.
|
||||||
|
6. **경고 0 상태 유지**: 패키지 내부까지 경고를 제거해 둔 상태라, 새 SDK/API를 추가할 때 `dotnet build VRBeatSaber.slnx --no-incremental`로 경고 재발 여부를 확인한다.
|
||||||
|
7. **VR 실기 테스트 필수 항목**: 게임오버 Back/Retry 클릭, SongCreator UI 클릭, 큐브 가로 간격, 큐브 도착 싱크, 세이버 각도는 Quest에서 직접 확인해야 한다.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"com.unity.2d.sprite": "1.0.0",
|
||||||
"com.unity.ai.navigation": "2.0.11",
|
"com.unity.ai.navigation": "2.0.11",
|
||||||
"com.unity.collab-proxy": "2.11.4",
|
"com.unity.collab-proxy": "2.11.4",
|
||||||
"com.unity.ide.rider": "3.0.39",
|
"com.unity.ide.rider": "3.0.39",
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"com.unity.2d.sprite": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"depth": 0,
|
||||||
|
"source": "builtin",
|
||||||
|
"dependencies": {}
|
||||||
|
},
|
||||||
"com.unity.ai.navigation": {
|
"com.unity.ai.navigation": {
|
||||||
"version": "2.0.11",
|
"version": "2.0.11",
|
||||||
"depth": 0,
|
"depth": 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user