简单的下落音游

This commit is contained in:
xinkl
2025-11-09 07:45:54 +08:00
parent d948b725a3
commit cc1b427d36
21 changed files with 1262 additions and 127 deletions

View File

@@ -33,11 +33,16 @@ public class CameraFollow : MonoBehaviour
{
var mousePos = Mouse.current.position.ReadValue();
Ray ray = Camera.main.ScreenPointToRay(mousePos);
Physics.Raycast(ray,out RaycastHit hit);
Physics.Raycast(ray, out RaycastHit hit);
if (hit.collider != null)
{
GameObject obj = hit.collider.gameObject;
// if (obj.GetComponent<Note>() != null)
// {
// if (obj.GetComponent<Note>().hitable)
// MusicGame.Instance.onNoteHit(obj.GetComponent<Note>().Uid);
// }
Debug.Log($"点击到了物体: {obj.name}");
}
else

View File

@@ -9,9 +9,10 @@ public class MusicData : ScriptableObject
public string musicName;
public List<MusicTick> musicTicks;
}
[System.Serializable]
[Serializable]
public class MusicTick
{
public int tick;
public double[] times = new double[4] ;
public GameObject[] array = new GameObject[4];
}

View File

@@ -1,40 +1,93 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class MusicGame : MonoBehaviour
{
public static MusicGame Instance { get; private set; }
public MusicData musicData;
bool isPlaying = false;
private bool isPlaying = false;
public Camera mainCamera;
private int tickId = 0;
private int noteId = 0;
public void Start()
public Vector3 judgeLine;
private List<GameObject> tickNote = new List<GameObject>();
double startDsp;
void Start()
{
mainCamera = Camera.main;
Instance = this;
}
public void Update()
void Update()
{
if (Keyboard.current.qKey.wasPressedThisFrame)
{
Play();
}
if (Keyboard.current.qKey.wasPressedThisFrame) Play();
}
public void Play()
{
ActivateTick(musicData.musicTicks[0]);
isPlaying = true;
judgeLine = mainCamera.transform.position + new Vector3(0, -2f, 8);
startDsp = AudioSettings.dspTime; // 音频原点
foreach (MusicTick tick in musicData.musicTicks)
ActivateTick(tick);
}
private void ActivateTick(MusicTick tick)
{
// 实例化与这个tick关联的预制体Note
// 清除旧音符
// tickNote.ForEach(x => Destroy(x));
// tickNote.Clear();
// double startDsp = AudioSettings.dspTime; // 音频原点
for (int i = 0; i < tick.array.Length; i++)
{
if (tick.array[i] != null)
{
Instantiate(tick.array[i], GetSpawnPosition(i), Quaternion.identity);
GameObject obj = Instantiate(tick.array[i], GetSpawnPosition(i), Quaternion.identity);
Note note = obj.GetComponent<Note>();
note.beatTime = startDsp + tick.times[i]; // 直接给绝对时刻
note.Uid = i;
tickNote.Add(obj);
}
}
// 不排队、不LaunchNext每个音符自己到点动
}
Vector3 GetSpawnPosition(int index)
{
return mainCamera.transform.position + new Vector3(-2 + index * 1.5f, 3, 8);
return mainCamera.transform.position + new Vector3(-2 + index * 1.5f, 6, 8);
}
public void onNoteHit(int uid)
{
if (!isPlaying) return;
noteId++;
// 顺序判定仍保留,只用于得分
if (uid != -1 && musicData.musicTicks[tickId].array[noteId].GetComponent<Note>().Uid == uid)
{
Debug.Log($"击中正确按键: {uid}");
}
if (noteId >= musicData.musicTicks[tickId].array.Length) FinshTick();
}
public void FinshTick()
{
Debug.Log($"完成tick: {tickId}");
tickId++;
noteId = 0;
if (tickId < musicData.musicTicks.Count)
{
}
// ActivateTick(musicData.musicTicks[tickId]);
else
{
isPlaying = false;
Debug.Log("完成所有tick");
}
}
}

View File

@@ -0,0 +1,71 @@
using System;
using UnityEngine;
using UnityEngine.InputSystem;
public class Note : MonoBehaviour
{
public int Uid;
[Header("节拍数据")]
public double beatTime; // 绝对击中时刻
public float approach = 1f;
[Header("运行参数")]
[SerializeField] private float speed = 1f;
private bool judged = false;
/* 1. 静态:最近一次空格的 dspTime */
private double lastSpaceTime = double.NegativeInfinity;
private double spawnTime => beatTime - approach;
private float spawnY = 6f;
private float judgeY => MusicGame.Instance.judgeLine.y;
private bool canMove = false;
void Start() => canMove = false;
void Update()
{
double dsp = AudioSettings.dspTime;
// ① 捕获空格时间戳(只抓第一次)
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
lastSpaceTime = dsp;
judged = false;
Debug.Log("空格时间戳:" + lastSpaceTime);
Debug.Log("当前时间:" + beatTime);
}
// ② 到出生时刻才动
if (!canMove && dsp >= spawnTime)
canMove = true;
if (!canMove) return;
// ③ 音频时间驱动位置(带平滑)
float targetY = spawnY - speed * (float)(dsp - spawnTime);
transform.position = new Vector3(transform.position.x, targetY, transform.position.z);
// ⑥ 兜底:掉出屏幕
if (targetY < judgeY)
{
Debug.Log($"{dsp - lastSpaceTime}");
if (dsp - lastSpaceTime <= 0.25f && !judged)
{
Debug.Log($"音符 {Uid}击中");
judged = true;
lastSpaceTime = double.NegativeInfinity;
MusicGame.Instance.onNoteHit(Uid);
}
else
{
MusicGame.Instance.onNoteHit(-1);
Debug.Log($"Miss 音符 {Uid}(超时)");
}
Destroy(gameObject);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0e39c014264598c4b9072bd040cc96e9