Jsonファイルを読み込んでノーツを生成することはできたのですが、
タイミングよく判定ラインに降らせる事ができませんでした。
譜面の読み方を学んだり、BPMの値によって1分間に何小節必要なのか、
一小節、一拍にか掛かる時間を計算したりして
道のり=速さ*時間の法則を使ってノーツから次のノーツの距離を測って生成したりしたのですが、
上手くいきませんでした。どなたかわかる方がいましたら回答よろしくお願いします。
追記
ObjectPoolクラスを追加しました。
C#
1/// <summary> 2/// ノートを生成するクラス 3/// </summary> 4public class NotesCreater : ObjectPool 5{ 6 /// <summary> タップノーツ </summary> 7 [SerializeField] GameObject tapNote; 8 /// <summary> ホールドノーツ </summary> 9 [SerializeField] GameObject holdNote; 10 /// <summary> フリックノーツ </summary> 11 [SerializeField] GameObject flickNote; 12 /// <summary> 最初にInstance化するObjectの数 </summary> 13 [SerializeField] int initNotesCount; 14 /// <summary> 追加でInstance化するObjectの数 </summary> 15 [SerializeField] int createNotesCount; 16 /// <summary> Noteの角度 </summary> 17 Quaternion angle = Quaternion.Euler(-30f, 0, 0); 18 [SerializeField] Transform judgmentLine; 19 20 LoadTest load = new LoadTest(); 21 MusicDTO.EditData music; 22 23 void Awake() 24 { 25 try 26 { 27 FileInfo file = new FileInfo(load.FilePath); 28 using (StreamReader sr = new StreamReader(file.OpenRead())) 29 { 30 music = JsonUtility.FromJson<MusicDTO.EditData>(sr.ReadToEnd()); 31 } 32 } 33 catch (FileNotFoundException e) 34 { 35 Debug.LogError("指定されたファイルが見つかりませんでした\n" + e); 36 } 37 38 AudioManager clip = GameObject.Find("MusicSource").GetComponent<AudioManager>(); 39 // 小節の数 40 float numberOfMeasures = music.BPM / 4f; 41 // 一小節に掛かる時間(秒) 42 float oneBarTime = 60f / numberOfMeasures; 43 // 一拍に掛かる時間(秒) => ノーツの間隔 44 float oneBeatTime = oneBarTime / 16f; 45 46 //Vector3 judgLinePos = judgmentLine.position; 47 for (int i = 0; i < music.notes.Count; i++) 48 { 49 float distance = Note.NoteSpeed * beatPerSecond; 50 Vector3 notePos = new Vector3(-3.8f + music.notes[i].block * 1.9f, 51 music.notes[i].num * distance / Mathf.Sqrt(3.0f), 52 music.notes[i].num * distance); 53 54 switch (music.notes[i].type) 55 { 56 case 1: 57 CreatePool(tapNote, notePos, angle); 58 break; 59 case 2: 60 CreatePool(holdNote, notePos, angle); 61 break; 62 case 3: 63 CreatePool(flickNote, notePos, angle); 64 break; 65 default: 66 break; 67 } 68 } 69 clip.Music.Play(); 70 } 71} 72 73//(music.notes[i].num * note.NoteSpeed) 74//(music.notes[i].num * note.NoteSpeed) 75//judgLinePos.y + ((music.notes[i].num - clip.Music.time) * music.notes[i].LPB) / Mathf.Sqrt(3.0f), 76//judgLinePos.z + (music.notes[i].num - clip.Music.time) * music.notes[i].LPB); 77//music.BPM / 60f 78//music.BPM / 60f
C#
1/// <summary> 2/// ノートを降らせるクラス 3/// </summary> 4[RequireComponent(typeof(Rigidbody))] 5public class Note : MonoBehaviour 6{ 7 Rigidbody rigid; 8 [SerializeField] static float noteSpeed = 4.0f; 9 public static float NoteSpeed { get { return noteSpeed; } } 10 11 void OnEnable() 12 { 13 noteSpeed = 4f * 158f / 60f; 14 rigid = GetComponent<Rigidbody>(); 15 rigid.useGravity = false; 16 rigid.velocity = Vector3.zero; 17 } 18 19 void FixedUpdate() 20 { 21 Vector3 angle = new Vector3(-30, 0, 0); 22 Vector3 direction = Quaternion.Euler(angle) * Vector3.back; 23 rigid.velocity = direction * noteSpeed; 24 } 25}
C#
1/// <summary> 2/// オブジェクトを生成して使い回すクラス 3/// </summary> 4public abstract class ObjectPool : MonoBehaviour 5{ 6 /// <summary> PoolするObject </summary> 7 GameObject poolObj; 8 /// <summary> PoolしたObjectを格納するList </summary> 9 List<GameObject> poolObjList; 10 11 /// <summary> 12 /// オブジェクトプールを作成 13 /// </summary> 14 /// <param name="obj"> Instance化するObject </param> 15 /// <param name="pos"> Instance化する位置 </param> 16 /// <param name="angle"> Instance化する角度 </param> 17 protected void CreatePool(GameObject obj, Vector3 pos, Quaternion angle) 18 { 19 poolObj = obj; 20 poolObjList = new List<GameObject>(); 21 22 var newObj = CreateNewObject(pos, angle); 23 //newObj.gameObject.SetActive(false); 24 poolObjList.Add(newObj); 25 } 26 27 /// <summary> 28 /// 未使用のObjectを探す 29 /// </summary> 30 /// <param name="pos"> Instance化する位置 </param> 31 /// <param name="angle"> Instance化する角度 </param> 32 /// <returns></returns> 33 protected GameObject GetUnusedObject(Vector3 pos, Quaternion angle) 34 { 35 // 使用中でないものを探す 36 foreach (var obj in poolObjList) 37 { 38 if (obj.gameObject.activeSelf == false) 39 { 40 obj.gameObject.SetActive(true); 41 return obj; 42 } 43 } 44 45 // 全て使用中だったら新しく作って返す 46 var newObj = CreateNewObject(pos, angle); 47 newObj.gameObject.SetActive(true); 48 poolObjList.Add(newObj); 49 return newObj; 50 } 51 52 /// <summary> 53 /// Objectが足らなかった場合、新しくInstance化する 54 /// </summary> 55 /// <param name="pos"> 位置 </param> 56 /// <param name="angle"> 角度 </param> 57 /// <returns> Instance化したObject </returns> 58 GameObject CreateNewObject(Vector3 pos, Quaternion angle) 59 { 60 var newObj = Instantiate(poolObj, pos, angle); 61 newObj.name = poolObj.name + (poolObjList.Count + 1); 62 return newObj; 63 } 64 65 /// <summary> 66 /// PoolしたObjectを全て削除する 67 /// </summary> 68 protected void DeleteAllPoolObject() 69 { 70 foreach (var poolObj in poolObjList) 71 { 72 Destroy(poolObj); 73 } 74 75 poolObjList.Clear(); 76 } 77}
C#
1/// <summary> 2 /// 譜面データを読み込むクラス 3 /// </summary> 4 public class LoadManager : MonoBehaviour 5 { 6 /// <summary> 譜面が保存されている場所 </summary> 7 string filePath = "/Users/sasuke/Documents/FonePaw/Notes/シャイニングスター.json"; 8 public string FilePath { get { return filePath; } } 9 /// <summary> 楽曲名 </summary> 10 public string Name { get; private set; } 11 /// <summary> レーンの総数 </summary> 12 public int MaxBlock { get; private set; } 13 /// <summary> 1分間に四分音符が何拍なるか </summary> 14 public float BPM { get; private set; } 15 /// <summary> 譜面の開始位置 </summary> 16 public int Offset { get; private set; } 17 /// <summary> Noteクラスのメンバ変数を保持する </summary> 18 public List<MusicDTO.Note> Notes { get; private set; } 19 /// <summary> 1拍の内にプレイカーソルが何ライン進むか </summary> 20 public List<int> LPB { get; private set; } = new List<int>(); 21 /// <summary> 拍子番号 </summary> 22 public List<int> Num { get; private set; } = new List<int>(); 23 /// <summary> レーンの番号 </summary> 24 public List<int> Block { get; private set; } = new List<int>(); 25 /// <summary> Notesの種類 </summary> 26 public List<NoteType> Type { get; private set; } = new List<NoteType>(); 27 /// <summary> ノートが判定ラインに重なるタイミング </summary> 28 public List<float> NoteJudgTiming { get; private set; } = new List<float>(); 29 /// <summary> 小節の数 </summary> 30 public float NumberOfMeasures { get; private set; } 31 /// <summary> 一小節に掛かる時間(秒) </summary> 32 public float OneBarTime { get; private set; } 33 /// <summary> 一拍に掛かる時間(秒) </summary> 34 public float OneBeatTime { get; private set; } 35 MusicDTO.EditData musicalData; 36 37 void Awake() 38 { 39 LoadNotesData(); 40 PropertyInitializer(); 41 SubstituteMusicalScoreData(); 42 } 43 44 /// <summary> 45 /// 譜面の小節数、一小節、一拍に掛かる時間を格納 46 /// </summary> 47 public void PropertyInitializer() 48 { 49 NumberOfMeasures = musicalData.BPM / 4f; 50 OneBarTime = 60f / NumberOfMeasures; 51 OneBeatTime = OneBarTime / 16f; 52 } 53 54 /// <summary> 55 /// 譜面からNotesの情報を取得して格納する 56 /// </summary> 57 public void LoadNotesData() 58 { 59 try 60 { 61 FileInfo file = new FileInfo(filePath); 62 using (StreamReader sr = new StreamReader(file.OpenRead())) 63 { 64 musicalData = JsonUtility.FromJson<MusicDTO.EditData>(sr.ReadToEnd()); 65 } 66 } 67 catch (FileNotFoundException e) 68 { 69 Debug.LogError(e + "指定されたファイルが見つかりませんでした\n"); 70 } 71 } 72 73 /// <summary> 74 /// 譜面データをプロパティに代入する 75 /// </summary> 76 public void SubstituteMusicalScoreData() 77 { 78 Name = musicalData.name; 79 MaxBlock = musicalData.maxBlock; 80 BPM = musicalData.BPM; 81 Offset = musicalData.offset; 82 foreach (var data in musicalData.notes) 83 { 84 LPB.Add(data.LPB); 85 Num.Add(data.num); 86 Block.Add(data.block); 87 NoteJudgTiming.Add(data.num * OneBeatTime); 88 } 89 Notes = musicalData.notes; 90 } 91 }
追記
使用している譜面制作エディタはこちらになります。
NoteEditor
追記2
譜面データを変数に格納して管理するクラスがあり、
ノートの番号ごとに判定ラインに重なる時間を保持していて、その値をNoteクラスで使いたいのですが、
Noteクラスが一つ一つのノートにアタッチされているので、ノートごとにそのノートに紐づいた値を
取得することができませんでした。この場合管理の仕方が間違っているのでしょうか。
使いたい変数はNoteJudgTimingです。
回答1件
あなたの回答
tips
プレビュー