完整錯誤:
KeyNotFoundException: The given key was not present in the dictionary.
System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <695d1cc93cca45069c528c15c9fdd749>:0)
TonePlayer <lightUp>d__6.MoveNext () (at Assets/TonePlayer.cs:43)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <0ee480759f3d481d82ada245dc74f9fd>:0)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
TonePlayer:Awake() (at Assets/TonePlayer.cs:14)
當我檢查計時陣列 (TonePlayer) 的值并將其與計時陣列 (SongManager) 的值進行比較時,它們的值似乎相同,但未被識別為相同的值我曾嘗試列印陣列的內容和內容相同。
兩個陣列都是相同的型別(字串),每個元素都是一個浮點數,轉換為具有 3 個小數位的字串
.unf 檔案只是一個轉換為 json 的 MIDI,這是它的內容:
{
"header": {
"PPQ": 480,
"timeSignature": [
4,
4
],
"bpm": 120,
"name": "Piano"
},
"tempo": [
{
"absoluteTime": 0,
"seconds": 0,
"bpm": 120
}
],
"timeSignature": [
{
"absoluteTime": 0,
"seconds": 0,
"numerator": 4,
"denominator": 2,
"click": 24,
"notesQ": 8
}
],
"startTime": 0,
"duration": 9.223958333333334,
"tracks": [
{
"startTime": 0,
"duration": 9.223958333333334,
"length": 26,
"notes": [
{
"name": "E5",
"midi": 76,
"time": 0,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333333
},
{
"name": "E5",
"midi": 76,
"time": 0.25,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333333
},
{
"name": "E5",
"midi": 76,
"time": 0.5,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333333
},
{
"name": "C5",
"midi": 72,
"time": 0.75,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333333
},
{
"name": "C5",
"midi": 72,
"time": 1,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "C5",
"midi": 72,
"time": 1.2499999999999998,
"velocity": 0.6299212598425197,
"duration": 0.47395833333333326
},
{
"name": "C5",
"midi": 72,
"time": 1.9999999999999998,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333344
},
{
"name": "D5",
"midi": 74,
"time": 2.25,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "F5",
"midi": 77,
"time": 2.5,
"velocity": 0.6299212598425197,
"duration": 0.4739583333333335
},
{
"name": "E5",
"midi": 76,
"time": 3,
"velocity": 0.6299212598425197,
"duration": 0.4739583333333335
},
{
"name": "D5",
"midi": 74,
"time": 3.5,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "C5",
"midi": 72,
"time": 3.75,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "E5",
"midi": 76,
"time": 4,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "E5",
"midi": 76,
"time": 4.25,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "E5",
"midi": 76,
"time": 4.5,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "C5",
"midi": 72,
"time": 4.75,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "C5",
"midi": 72,
"time": 5,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "C5",
"midi": 72,
"time": 5.25,
"velocity": 0.6299212598425197,
"duration": 0.47395833333333304
},
{
"name": "D5",
"midi": 74,
"time": 6.75,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "D5",
"midi": 74,
"time": 7,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "D5",
"midi": 74,
"time": 7.25,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "D5",
"midi": 74,
"time": 7.5,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "D5",
"midi": 74,
"time": 7.75,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "C5",
"midi": 72,
"time": 8,
"velocity": 0.6299212598425197,
"duration": 0.23645833333333321
},
{
"name": "D5",
"midi": 74,
"time": 8.25,
"velocity": 0.6299212598425197,
"duration": 0.4739583333333339
},
{
"name": "E5",
"midi": 76,
"time": 8.75,
"velocity": 0.6299212598425197,
"duration": 0.4739583333333339
}
],
"controlChanges": {
"7": [
{
"number": 7,
"time": 0,
"value": 0.7874015748031497
}
],
"10": [
{
"number": 10,
"time": 0,
"value": 0.5039370078740157
}
],
"91": [
{
"number": 91,
"time": 0,
"value": 0
}
],
"93": [
{
"number": 93,
"time": 0,
"value": 0
}
],
"121": [
{
"number": 121,
"time": 0,
"value": 0
}
]
},
"id": 0,
"name": "Piano",
"instrumentNumber": 0,
"instrument": "acoustic grand piano",
"instrumentFamily": "piano",
"channelNumber": 0,
"isPercussion": false
},
{
"startTime": 0,
"duration": 0,
"length": 0,
"notes": [],
"controlChanges": {},
"id": 1,
"name": "Piano"
}
]
}
輸出(第一次回圈): 計時(SongManager):0,000、0,236 計時(TonePlayer):0,000、0,236
TonePlayer.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TonePlayer : MonoBehaviour
{
private KeyCode[] keys;
public float minAlpha = 80f;
public float reduceAlphaStep = 1f;
public ToneManager mgr;
public SongManager smgr;
private void Awake()
{
StartCoroutine(lightUp());
keys = new KeyCode[4] { KeyCode.A, KeyCode.S, KeyCode.D, KeyCode.F };
}
IEnumerator lightUp()
{
Dictionary<string[], int> notes = smgr.LoadSong("Assets/test.unf");
Dictionary<int, string> notes_enc = new Dictionary<int, string>();
notes_enc[0] = "C";
notes_enc[1] = "D";
notes_enc[2] = "E";
notes_enc[3] = "F";
for (int i = 0; i < notes.Count; i )
{
string[][] keys=new string[notes.Count][];
keys[0]= new string[notes.Count];
keys[1] = new string[2];
notes.Keys.CopyTo(keys, 0);
string time = keys[i][0];
string duration = keys[i][1];
string[] timing = { time, duration };
mgr.source.PlayOneShot(mgr.tones[notes[timing]]);
print(notes_enc[notes[timing]]);
print(duration);
yield return new WaitForSeconds(float.Parse(duration));
}
yield return null;
}
void Update()
{
for (int i = 0; i < 4; i )
{
if (Input.GetKeyDown(keys[i]))
{
mgr.source.PlayOneShot(mgr.tones[i]);
var temp = mgr.lights[i].color;
temp.a = 1;
//print("set");
mgr.lights[i].color = temp;
}
float alpha = mgr.lights[i].color.a;
if (alpha > (minAlpha / 255f))
{
alpha -= (reduceAlphaStep / 255f);
var temp = mgr.lights[i].color;
temp.a = alpha;
mgr.lights[i].color = temp;
//print(alpha);
}
}
}
}
SongManager.cs:
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using System.IO;
using System;
using UnityEngine;
public class SongManager : MonoBehaviour
{
public string[] first;
private void Awake()
{
LoadSong("Assets/test.unf");
}
public Dictionary<string[], int> LoadSong(string unf_json)
{
Dictionary<string[], int> ret = new Dictionary<string[], int>();
string json = File.ReadAllText(unf_json);
var root = JObject.Parse(json);
var tracks = root.GetValue("tracks")[0]["notes"];
Dictionary<string, int> notes_enc = new Dictionary<string, int>();
notes_enc["C"] = 0;
notes_enc["D"] = 1;
notes_enc["E"] = 2;
notes_enc["F"] = 3;
int z = 0;
foreach (var track in tracks)
{
z ;
float time = ((float)track["time"]);
float duration = ((float)track["duration"]);
string[] timings = { time.ToString("0.000"), duration.ToString("0.000") };
string name = ((string)track["name"])[0].ToString();
//Debug.Log(string.Format("duration: {0}, note: {1}({2})", duration, name, notes_enc[name]));
ret[timings] = notes_enc[name];
}
return ret;
}
}
ToneManager.cs:
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
public class ToneManager : MonoBehaviour
{
public AudioSource source;
public AudioClip[] tones;
[HideInInspector]
public SpriteRenderer[] lights;
public Transform parent;
public TonePlayer player;
private void Start()
{
lights = GetSpriteRenderers(GetChildren(parent));
/*for (int i = 0; i < 4; i )
{
lights[i].color = SetAlpha(lights[i].color, player.minAlpha);
}
*/
}
public Transform[] GetChildren(Transform parent)
{
List<Transform> children = new List<Transform>();
for (int i = 0; i < parent.childCount; i )
{
children.Add(parent.GetChild(i));
}
return children.ToArray();
}
public SpriteRenderer[] GetSpriteRenderers(Transform[] children)
{
SpriteRenderer[] spriteRenderers = new SpriteRenderer[children.Length];
for (int i = 0; i < children.Length; i )
{
spriteRenderers[i] = children[i].GetComponent<SpriteRenderer>();
}
return spriteRenderers;
}
}
uj5u.com熱心網友回復:
你做
string[] timing = { time, duration };
然后在你的字典中使用這個鍵。
這是一個以前從未存在過的新陣列實體,也從未添加到您的字典中!
陣列使用參考相等,而不是值相等!
通常,由于這個原因,使用陣列作為鍵通常并不好,除非您確實知道您仍在處理完全相同的陣列參考。
而不是string[]你寧愿使用Tuple
Tuple<string, string>
或者實際上為什么不直接直接
Tuple<float, float>
它通過而不是默認參考相等來提供適當的值相等比較,因此可以作為關鍵!另請參閱C# 中帶有多維鍵的哈希表
所以你的型別應該是一個
Dictionary<Tuple<string, string>, int>
或相應地
Dictionary<Tuple<float, float>, int>
你會做
var timings = new Tuple<string,string>(time.ToString("0.000"), duration.ToString("0.000"));
或相應地
var timings = new Tuple<float,float>(time, duration);
并將其添加到字典中,稍后將其用作訪問鍵。
uj5u.com熱心網友回復:
問題是您沒有使用Dictionary<string[], int>自定義比較器。默認鍵比較器string[]將通過比較參考而不是內部字串來查找相似的鍵,因此即使它們的內容相同,如果它們是不同的陣列實體,也不會匹配。
因為在這種情況下似乎只需要兩個字串,所以Dictionary<Tuple<string, string>, int>可以代替。您還可以使用Dictionary<string, int>和使用string1 "," string2或類似的東西作為鍵,因為在這種情況下,您的字串不是任意字串,因此很容易將它們格式化為唯一字串。
uj5u.com熱心網友回復:
我建議你使用 Dictionary<Tuple<float, float>, int> 而不是 Dictionary< string[] , int> 因為 Dictionary<TKey,TValue> 需要一個相等的實作來確定鍵是否相等。對于字串陣列,默認是參考相等。
所以以下兩個陣列不相等:
string[] arr1 = {"1", "2"};
string[] arr2 = { "1", "2" };
Console.WriteLine($"arr1 == arr2: {arr1 == arr2}");
使固定:
var notes = new Dictionary<(float, float), int>();
float time = 1;
float duration = 2;
notes[(time, duration)] = 12;
Console.WriteLine(notes[(time, duration)]);
uj5u.com熱心網友回復:
據我所知,在您的 SongManager 中,您正在創建Dictionary<string[], int> ret,但未向其中添加任何值。相反,您正在嘗試直接分配值:ret[timings] = notes_enc[name];。字典不是陣列,應使用Add()方法,這樣的:ret.Add(timings, notes_enc[name]);
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/393335.html
