private void DisplayFirstBeat(BeatData data) { Vector2 pos; SMSBubble newBubble; float bubbleHeight; float bubbleWidth; switch (currentSpeaker) { case Speaker.Client: //Create newbubble newBubble = DialogueManager.instance.CreateSMSBubble(smsArea); newBubble.SetUp(data.DisplayText, clientBubbleColor); //get dimension bubbleHeight = newBubble.GetComponent <RectTransform>().rect.height; bubbleWidth = newBubble.GetComponent <RectTransform>().rect.width; //calculate position at the top of the screen in the client case pos = (Vector2)smsClientStartPosition.position + (clientSmsOffset * EssoUtility.GetAspectRatio()); //update postion and display text newBubble.transform.position = pos + new Vector2(bubbleWidth / 2, -(bubbleHeight / 2) * EssoUtility.GetAspectRatio()); previousBubble = newBubble; vibrationController.BeginViewBob(); AudioManager.instance.PlayAtRandomPitch("PhoneVibrateSFX"); smsBubbles.Add(previousBubble); break; //calculate position at the top of the screen in the mc case case Speaker.MainCharacter: newBubble = DialogueManager.instance.CreateSMSBubble(smsArea); newBubble.SetUp(data.DisplayText, mcBubbleColor); //get dimension bubbleHeight = newBubble.GetComponent <RectTransform>().rect.height; bubbleWidth = newBubble.GetComponent <RectTransform>().rect.width; //calculate position at the top of the screen in the client case pos = (Vector2)smsMCStartPosition.position + (mcSmsOffset * EssoUtility.GetAspectRatio()); //update postion and display text newBubble.transform.position = pos + new Vector2(-bubbleWidth / 2, -(bubbleHeight / 2) * EssoUtility.GetAspectRatio()); previousBubble = newBubble; smsBubbles.Add(previousBubble); break; } }
public void ManageSpawns(BeatData beatData) { beatsAfterWallCreated++; if (beatsAfterWallCreated == gameConfig.beatsBeforeJump + 2) { SpawnWallIfAble(beatData); } //if (beatsAfterWallCreated % 2 == 1) { if (beatsAfterWallCreated != 0 && beatsAfterWallCreated != gameConfig.beatsBeforeJump + 1 && beatsAfterWallCreated != 0) { SpawnCircleIfAble(beatData); } } }
public void AddBeat(int _beatTypeIndex, float _progressRatioTime, bool _showVisual) { BeatData _curBeatData = new BeatData() { typeIndex = _beatTypeIndex, progressRatioTime = _progressRatioTime }; tunes[0].tuneAllBeats.Add(_curBeatData); tunes[0].tuneTypeBeats[_beatTypeIndex].Add(_curBeatData); StartCoroutine(audioManager.PlayClip(_beatTypeIndex)); if (_showVisual) { beatAnims.Add(UIManager.CreateBeatTypeVisual(_beatTypeIndex, _progressRatioTime)); } }
private IEnumerator DoDisplay(BeatData data) { _output.Clear(); while (_output.IsBusy) { yield return(null); } _output.Display(data.DisplayText); while (_output.IsBusy) { yield return(null); } }
private void DisplayBeat(int id) { BeatData data = _data.GetBeatById(id); StartCoroutine(DoDisplay(data)); _currentBeat = data; if (data.bossPick) { Player.instance.sceneLoader.spawnBoss(data.goodChoice); } if (data.getChoiceList().Count == 0) { Invoke("showCloseButton", 1); Player.instance.menus.lockSelection(true); } }
private void handleChoice(int i) { if(i < 0 || i > _currentChoices.Length) return; ChoiceData choice = _currentChoices[i]; BeatData nextBeat = _data.GetBeatById(choice.NextID); NPC npcSpeaking = PlayerController.instance.npcSpeaking; // If the choice is unavailable (button inactive) then don't continue with the choice if(npcSpeaking.HasUsedDialogueType(choice.Type)) return; if(choice.TextType == ChoiceTextType.BribeAmount && !LevelManager.instance.CanAffordBribe(i)) return; if(nextBeat.Type != DialogueType.Goodbye) { switch(nextBeat.DisplayTextType) { case SpeechType.FlatterResponse: npcSpeaking.RespondToFlattery(choice.IsCorrectChoice); break; case SpeechType.ThreatenResponse: npcSpeaking.RespondToThreaten(choice.IsCorrectChoice); break; case SpeechType.BribeResponse: choice.IsCorrectChoice = npcSpeaking.ReceiveBribe(i); LevelManager.instance.SpendBribe(i); break; case SpeechType.RumourStart: choice.IsCorrectChoice = npcSpeaking.CanGiveRumour() && HasRumourAvailable(npcSpeaking); if(choice.IsCorrectChoice && !unlockedRumours.ContainsKey(npcSpeaking)) { UnlockRandomRumour(npcSpeaking); } break; case SpeechType.RumourEnd: npcSpeaking.CompleteRumour(); break; } DisplayBeat(choice.NextID, false, choice.IsCorrectChoice); } else { PlayerController.instance.ExitDialogue(); } }
public IEnumerator BeatActionDelay(BeatData beatData) { yield return(new WaitForSeconds(rhythmizationConfig.GetMusicDelay)); FireInvokeIfAble(); beatAfterJumpId++; onBeat?.Invoke(beatData); if (beatAfterJumpId == gameConfig.beatsBeforeJump + gameConfig.beatsDuringJump) { beatAfterJumpId = 0; List <float> jumps = new List <float>(); for (int i = 0; i < gameConfig.beatsDuringJump + 1; i++) { jumps.Add(beatData.GetTimeToFollowingBeat(beatData, i)); } NW.Game.EventsProvider.onJump?.Invoke(beatData.GetTimeToFollowingBeat(beatData, gameConfig.beatsDuringJump) * 0.49f); NW.Game.EventsProvider.onJumps?.Invoke(jumps.ToArray()); } }
public void DisplayBeat(int id, Speaker newSpeaker) { currentSpeaker = newSpeaker; BeatData data = storyData.GetBeatById(id); //if there is no previous bubble assume this is the start of the conversation //if there is no previous bubble assume this is the start of the conversation if (previousBubble == false) { DisplayFirstBeat(data); } //if not append from previous bubble else { DisplaySmsBubble(data); } OnBeatDisplayed?.Invoke(data); }
void Start() { BeatData.RepeatChorus(); if (debugStartTime > 0) { while (beatIndex < BeatData.beatTimes.Count && BeatData.beatTimes[beatIndex] - Beat.ShrinkTime <= debugStartTime) { beatIndex++; } while (sliderIndex < BeatData.sliderTimes.Count && BeatData.sliderTimes[sliderIndex].startTime - Beat.ShrinkTime <= debugStartTime) { sliderIndex++; } } musicAudio.time = debugStartTime; Invoke("PlaySong", secondsBeforePlaySong); }
// Starts coroutines in order to scroll beat text and choices on the screen // success parameter is used for certain choice responses private IEnumerator DoDisplay(BeatData data, bool showAnimations, bool success = false) { if(showAnimations) { HUD.instance.dialogueMenu.SetActive(); yield return _waitInitial; } else { HUD.instance.dialogueMenu.HideChoicesPanel(); } NPC npcSpeaking = PlayerController.instance.npcSpeaking; TextDisplay npcSpeech = HUD.instance.dialogueMenu.NpcSpeechText; npcSpeech.Clear(); while (npcSpeech.IsBusy) { yield return null; } if(data.DisplayTextType == SpeechType.FlatterResponse || data.DisplayTextType == SpeechType.ThreatenResponse || data.DisplayTextType == SpeechType.BribeResponse) { HUD.instance.dialogueMenu.ShowNpcSpeech(data.GetDisplayText(_textData, success), showAnimations); } else if(data.DisplayTextType == SpeechType.RumourStart) { string text; if(success) { text = unlockedRumours[npcSpeaking].StartText; } else if(HasRumourAvailable(npcSpeaking)) { // If there are rumours available but the NPC disposition is too low then give a rejection line text = _textData.GetRandomRumourFail(); } else { // If there aren't any rumours available give a neutral apology text = _textData.GetRandomRumourUnknown(); } HUD.instance.dialogueMenu.ShowNpcSpeech(text, showAnimations); } else if(data.DisplayTextType == SpeechType.RumourEnd) { Rumour rumour = GetRumourForTargetNpc(npcSpeaking); HUD.instance.dialogueMenu.ShowNpcSpeech(rumour.EndText, showAnimations); CompleteRumour(rumour); } else { HUD.instance.dialogueMenu.ShowNpcSpeech(data.GetDisplayText(_textData, npcSpeaking.DispositionType), showAnimations); } // npcSpeech.Display(data.GetDisplayText(npcSpeaking.disposition)); // On the greeting beat wait until the speech has finished before showing the other panels while(npcSpeech.IsBusy) { yield return null; } if(showAnimations) HUD.instance.dialogueMenu.ShowNpcInfo(npcSpeaking); // yield return _wait; // Copy choices from other beat if needed if(data.CopyChoicesFromBeat) { int id = data.BeatIdToCopyFrom; data.Decision = _data.GetBeatById(id).Decision; } // Set choices List<ChoiceData> choices = new List<ChoiceData>();; int correctChoice = Random.Range(0, data.Decision.Count - 1); // -1 to account for the nevermind choice List<string> usedTextLines = new List<string>(); // Keep track of use choice text to avoid getting the same line twice for(int i = 0; i < data.Decision.Count; i++) { data.Decision[i].IsCorrectChoice = i == correctChoice; switch(data.Decision[i].TextType) { case ChoiceTextType.RandomFlatter: string text; do { text = _textData.GetRandomFlattery(npcSpeaking, i == correctChoice); } while(usedTextLines.Contains(text)); usedTextLines.Add(text); data.Decision[i].DisplayText = text; break; case ChoiceTextType.RandomThreaten: do { text = _textData.GetRandomThreaten(npcSpeaking, i == correctChoice); } while(usedTextLines.Contains(text)); usedTextLines.Add(text); data.Decision[i].DisplayText = text; break; case ChoiceTextType.BribeAmount: data.Decision[i].DisplayText = LevelManager.instance.BribeGoldAmount(i) + " gold"; break; case ChoiceTextType.RumourMid: Rumour rumour = GetRumourForTargetNpc(npcSpeaking); if(rumour != null) { data.Decision[i].DisplayText = rumour.MiddleText; choices.Add(data.Decision[i]); } break; } // Add all choices other than rumour as that is handled in the switch if(data.Decision[i].TextType != ChoiceTextType.RumourMid) { choices.Add(data.Decision[i]); } } _currentChoices = choices.ToArray(); HUD.instance.dialogueMenu.ShowChoicesPanel(npcSpeaking, _currentChoices); // for (int count = 0; count < data.Decision.Count; ++count) // { // ChoiceData choice = data.Decision[count]; // npcSpeech.Display(string.Format("{0}: {1}", (count + 1), choice.DisplayText)); // while (npcSpeech.IsBusy) // { // yield return null; // } // } // if(data.Decision.Count > 0) // { // npcSpeech.ShowWaitingForInput(); // } }
void DrawMain() { soundFile = (AudioClip)EditorGUILayout.ObjectField(new GUIContent("Audio File", "The file that will be used to generate data."), soundFile, typeof(AudioClip), false); if (GUILayout.Button("Analyze Real Quick")) { //Populate an array full of all the samples in the audiofile. This will be big. Like, millions big. Multithread is possible numSamples = soundFile.samples; numChannels = soundFile.channels; lengthOfSong = soundFile.length; allChannelsSamples = new float[numSamples * numChannels]; soundFile.GetData(allChannelsSamples, 0); sampleRate = soundFile.frequency; Thread myThread = new Thread(this.AnalyzeAudio); myThread.Start(); } switch (complexityInt) { case 0: { SimpleMenu(); break; } case 1: { IntermediateMenu(); break; } case 2: { ComplexMenu(); break; } default: break; } if (GUILayout.Button("Create Audio Data Scriptable Object")) { BeatData asset = CreateInstance <BeatData>(); asset.time = new float[importantMoments.length]; asset.song = soundFile; for (int i = 0; i < importantMoments.length; i++) { asset.time[i] = importantMoments[i].time; } AssetDatabase.CreateAsset(asset, string.Format("Assets/BeatData/{0}.asset", soundFile.name)); AssetDatabase.SaveAssets(); EditorUtility.FocusProjectWindow(); } }
private void BeatActions(BeatData beatData) { StartCoroutine(BeatActionDelay(beatData)); }
private void DisplaySmsBubble(BeatData data) { Vector2 pos; SMSBubble newBubble; float bubbleHeight = previousBubble.GetComponent <RectTransform>().rect.height;; float newBubbleHeight; float newBubbleWidth; switch (currentSpeaker) { case Speaker.Client: //set up sms bubbles newBubble = DialogueManager.instance.CreateSMSBubble(smsArea); newBubble.SetUp(data.DisplayText, clientBubbleColor); //get bubble dimensions newBubbleHeight = newBubble.GetComponent <RectTransform>().rect.height; newBubbleWidth = newBubble.GetComponent <RectTransform>().rect.width; //Spawn new bubble with an offset of its previous position + the offset of it's height from its centre pos = new Vector2(smsClientStartPosition.position.x + newBubbleWidth / 2, previousBubble.transform.position.y - bubbleHeight / 2 - newBubbleHeight / 2) + (clientSmsOffset + bubbleOffset) * EssoUtility.GetAspectRatio(); //Update position newBubble.transform.position = pos; previousBubble = newBubble; smsBubbles.Add(previousBubble); if (pos.y < smsScreenEndPoint.position.y) { float vertDistance = smsScreenEndPoint.position.y - pos.y; ScrollUnitsUp(vertDistance + newBubbleHeight / 2); } vibrationController.BeginViewBob(); AudioManager.instance.PlayAtRandomPitch("PhoneVibrateSFX"); break; case Speaker.MainCharacter: //set up sms bubbles newBubble = DialogueManager.instance.CreateSMSBubble(smsArea); newBubble.SetUp(data.DisplayText, mcBubbleColor); //get bubble dimensions newBubbleHeight = newBubble.GetComponent <RectTransform>().rect.height; newBubbleWidth = newBubble.GetComponent <RectTransform>().rect.width; //Spawn new bubble with an offset of its previous position + the offset of it's height from its centre pos = new Vector2(smsMCStartPosition.position.x - newBubbleWidth / 2, previousBubble.transform.position.y - bubbleHeight / 2 - newBubbleHeight / 2) + (mcSmsOffset + bubbleOffset) * EssoUtility.GetAspectRatio(); //Update position newBubble.transform.position = pos; previousBubble = newBubble; smsBubbles.Add(previousBubble); if (pos.y < smsScreenEndPoint.position.y) { float vertDistance = smsScreenEndPoint.position.y - pos.y; ScrollUnitsUp(vertDistance + newBubbleHeight / 2); } break; } }
/// <summary> /// トラックデータ解析 /// </summary> public void TrackDataAnalysis(byte[] data, short division, Action <NoteData[], SoflanData[], BeatData[]> success, Action failure) { // リスト初期化 var noteList = new List <NoteData>(); var soflanList = new List <SoflanData>(); var beatList = new List <BeatData>(); try { uint deltaTime = 0; // デルタタイム格納用 uint currentTime = 0; // デルタタイムを足していく、つまり現在の時間(ノーツやソフランのイベントタイムはこれを使う) byte tmp = 0; // 値保存用 byte statusByte = 0; // ステータスバイト byte dataByte0, dataByte1, dataByte2, dataByte3; // メッセージの後に付いてるデータ // データぶん回す for (int i = 0; i < data.Length;) { // メモ データ部は<デルタタイム><イベント>の繰り返しで構成されている /* デルタタイム(可変長数値表現) */ deltaTime = 0; // 可変長数値表現をint型に戻す while (true) { // 無限ループは怖いので例外を書いておく if (i >= data.Length) { throw new Exception("delta time infinity loop."); } tmp = data[i++]; // 下位7bitを格納 deltaTime |= tmp & (uint)0x7f; // 最上位1bitが0ならデータ終了 if ((tmp & 0x80) == 0) { break; } // 次の下位7bit用に移動 deltaTime = deltaTime << 7; } // 現在の時間にデルタタイムを足す currentTime += deltaTime; System.Diagnostics.Debug.WriteLine("delta_time:" + deltaTime); System.Diagnostics.Debug.WriteLine("current_time:" + currentTime); /* ランニングステータス(前回のステータスバイトを使いまわす) */ if (data[i] < 0x80) { // ランニングステータス適応 //throw new Exception("not status byte. must be statusByte < 0x80 || statusByte > 0xff" + statusByte); System.Diagnostics.Debug.WriteLine("Running Status."); } else { // ステータスバイト保存 statusByte = data[i++]; } /* イベント */ /* MIDIイベント(ステータスバイト0x80-0xEF) */ if (statusByte >= 0x80 && statusByte <= 0xef) { // MIDIチャンネル番号 System.Diagnostics.Debug.WriteLine("channel:" + (statusByte & 0x0f)); switch (statusByte & 0xf0) { /* チャンネルメッセージ */ case 0x80: // ノートオフ // どのキーが離されたか dataByte0 = data[i++]; // ベロシティ値 dataByte1 = data[i++]; // ノート情報生成 { var note = new NoteData(); note.EventTime = (int)currentTime; note.LaneIndex = dataByte0; noteList.Add(note); } System.Diagnostics.Debug.WriteLine("NoteOFF. kk:" + dataByte0 + " vv:" + dataByte1); break; case 0x90: // ノートオン(ノートオフが呼ばれるまでは押しっぱなし扱い) // どのキーが押されたか dataByte0 = data[i++]; // ベロシティ値(鍵盤押す強さ機能がないキーボードは0x40固定) キーボードによってはノートオフメッセージの代わりにここで0を送ってくる dataByte1 = data[i++]; // ノート情報生成 { var note = new NoteData(); note.EventTime = (int)currentTime; note.LaneIndex = dataByte0; note.IsPress = dataByte1 != 0; noteList.Add(note); } System.Diagnostics.Debug.WriteLine("NoteON. kk:" + dataByte0 + " vv:" + dataByte1); break; case 0xa0: // ポリフォニック キープレッシャー(鍵盤楽器で、キーを押した状態でさらに押し込んだ際に、その圧力に応じて送信される) // どのキーが押されたか dataByte0 = data[i++]; // 押されている圧力 dataByte1 = data[i++]; System.Diagnostics.Debug.WriteLine("Polyphonic Key Pressure. kk:" + dataByte0 + " vv:" + dataByte1); break; case 0xb0: // コントロールチェンジ(音量、音質など様々な要素を制御するための命令) // コントロールする番号 dataByte0 = data[i++]; // 設定する値 dataByte1 = data[i++]; // ※0x00-0x77までがコントロールチェンジで、それ以上はチャンネルモードメッセージとして処理する if (dataByte0 < 0x78) { // コントロールチェンジ System.Diagnostics.Debug.WriteLine("Controller Change. cc:" + dataByte0 + " nn:" + dataByte1); } else { // チャンネルモードメッセージは一律データバイトを2つ使用している // チャンネルモードメッセージ switch (dataByte0) { case 0x78: // オールサウンドオフ // 該当するチャンネルの発音中の音を直ちに消音する。後述のオールノートオフより強制力が強い。 System.Diagnostics.Debug.WriteLine("All Sound Off."); break; case 0x79: // リセットオールコントローラ // 該当するチャンネルの全種類のコントロール値を初期化する。 System.Diagnostics.Debug.WriteLine("Reset All Controllers."); break; case 0x7a: // ローカルコントロール(ピアノ音ゲーをやる時に電子ピアノに設定するやつ) // オフ:鍵盤を弾くとMIDIメッセージは送信されるがピアノ自体から音は出ない // オン:鍵盤を弾くと音源から音が出る(基本こっち) System.Diagnostics.Debug.WriteLine("Local Control. xx:" + (dataByte1 == 0 ? "Local Off" : "Local On")); break; case 0x7b: // オールノートオフ // 該当するチャンネルの発音中の音すべてに対してノートオフ命令を出す System.Diagnostics.Debug.WriteLine("All Notes Off."); break; /* MIDIモード設定 */ // オムニのオン・オフとモノ・ポリモードを組み合わせて4種類のモードがある case 0x7c: // オムニモードオフ System.Diagnostics.Debug.WriteLine("Omni Mode Off."); break; case 0x7d: // オムニモードオン System.Diagnostics.Debug.WriteLine("Omni Mode On."); break; case 0x7e: // モノモードオン /* * dataByte2 * 00 = use n...16 * 01 = use 1 channel * 0x10 = use 16 channels (provided n=0) */ System.Diagnostics.Debug.WriteLine("Mono Mode On."); break; case 0x7f: // モノモードオン System.Diagnostics.Debug.WriteLine("Poly Mode On."); break; default: throw new Exception("channel mode message unintended value."); } } break; case 0xc0: // プログラムチェンジ(音色を変える命令) // 音色の番号 dataByte0 = data[i++]; System.Diagnostics.Debug.WriteLine("Program Change. pp:" + dataByte0); break; case 0xd0: // チャンネルプレッシャー(概ねポリフォニック キープレッシャーと同じだが、違いはそのチャンネルの全ノートナンバーに対して有効となる) // 圧力の値 dataByte0 = data[i++]; System.Diagnostics.Debug.WriteLine("Channel Key Pressure. ww:" + dataByte0); break; case 0xe0: // ピッチベンド(ウォェーンウェューンの表現で使う) // Least Signiflcant Byte dataByte0 = data[i++]; // Most Signiflcant Byte dataByte1 = data[i++]; // メモ 日本語wikiではMSB,LSBの順だと記載されているが、別の英語のサイトではLSB,MSBの順と記載されており正解が分からない。試す機会があったら確認 System.Diagnostics.Debug.WriteLine("Pitch Bend. LSB:" + dataByte0 + " MSB:" + dataByte1); break; default: throw new Exception("channel voice message unintended value."); } } /* システムエクスクルーシブ (SysEx) イベント よくわからんから適当にあしらう */ else if (statusByte == 0x70 || statusByte == 0x7f) { // データ長 byte dataLength = data[i++]; // スルーするー i += dataLength; } /* メタイベント*/ else if (statusByte == 0xff) { tmp = data[i++]; byte[] dataByteArray; // データ長 byte dataLength = data[i++]; switch (tmp) { case 0x00: // シーケンスメッセージ if (dataLength != 0x02) { throw new Exception("Sequence Number not value 0x02."); } // dataByte0 = data[i++]; // dataByte1 = data[i++]; System.Diagnostics.Debug.WriteLine("Sequence. Number. ss:" + dataByte0 + " ss:" + dataByte1); break; case 0x01: // テキストイベント System.Diagnostics.Debug.WriteLine("Text Event."); if (dataLength == 0) { continue; } // テキスト dataByteArray = new byte[dataLength]; Array.Copy(data, i, dataByteArray, 0, dataLength); i += dataLength; System.Diagnostics.Debug.WriteLine("Length:" + dataLength + " Text:" + System.Text.Encoding.ASCII.GetString(dataByteArray)); break; case 0x02: // 著作権表示 System.Diagnostics.Debug.WriteLine("Copyright Notice."); if (dataLength == 0) { continue; } // テキスト dataByteArray = new byte[dataLength]; Array.Copy(data, i, dataByteArray, 0, dataLength); i += dataLength; System.Diagnostics.Debug.WriteLine("Length:" + dataLength + " Text:" + System.Text.Encoding.ASCII.GetString(dataByteArray)); break; case 0x03: // シーケンス/トラック名 System.Diagnostics.Debug.WriteLine("Sequence/Track Name."); if (dataLength == 0) { continue; } // テキスト dataByteArray = new byte[dataLength]; Array.Copy(data, i, dataByteArray, 0, dataLength); i += dataLength; System.Diagnostics.Debug.WriteLine("Length:" + dataLength + " Text:" + System.Text.Encoding.ASCII.GetString(dataByteArray)); break; case 0x04: // 楽器名 System.Diagnostics.Debug.WriteLine("Instrument Name."); if (dataLength == 0) { continue; } // テキスト dataByteArray = new byte[dataLength]; Array.Copy(data, i, dataByteArray, 0, dataLength); i += dataLength; System.Diagnostics.Debug.WriteLine("Length:" + dataLength + " Text:" + System.Text.Encoding.ASCII.GetString(dataByteArray)); break; case 0x05: // 歌詞 System.Diagnostics.Debug.WriteLine("Lyric."); if (dataLength == 0) { continue; } // テキスト dataByteArray = new byte[dataLength]; Array.Copy(data, i, dataByteArray, 0, dataLength); i += dataLength; System.Diagnostics.Debug.WriteLine("Length:" + dataLength + " Text:" + System.Text.Encoding.ASCII.GetString(dataByteArray)); break; case 0x06: // マーカー System.Diagnostics.Debug.WriteLine("Marker."); if (dataLength == 0) { continue; } // テキスト dataByteArray = new byte[dataLength]; Array.Copy(data, i, dataByteArray, 0, dataLength); i += dataLength; System.Diagnostics.Debug.WriteLine(" Length:" + dataLength + " Text:" + System.Text.Encoding.ASCII.GetString(dataByteArray)); break; case 0x07: // キューポイント System.Diagnostics.Debug.WriteLine("Cue Point."); if (dataLength == 0) { continue; } // テキスト dataByteArray = new byte[dataLength]; Array.Copy(data, i, dataByteArray, 0, dataLength); i += dataLength; System.Diagnostics.Debug.WriteLine("Length:" + dataLength + " Text:" + System.Text.Encoding.ASCII.GetString(dataByteArray)); break; case 0x20: // MIDIチャンネルプリフィクス if (dataLength != 0x01) { throw new Exception("MIDI Channel Prefix not value 0x01."); } // dataByte0 = data[i++]; System.Diagnostics.Debug.WriteLine("MIDI Channel Prefix. cc:" + dataByte0); break; case 0x21: // MIDIポートプリフィックス if (dataLength != 0x01) { throw new Exception("MIDI Port Prefix not value 0x01."); } // dataByte0 = data[i++]; System.Diagnostics.Debug.WriteLine("MIDI Port Prefix. cc:" + dataByte0); break; case 0x2f: // トラック終了 if (dataLength != 0x00) { throw new Exception("End of Track not value 0x00."); } System.Diagnostics.Debug.WriteLine("End of Track."); break; case 0x51: // テンポ if (dataLength != 0x03) { throw new Exception("Set Tempo not value 0x03."); } // 4分音符の長さをマイクロ秒単位で格納されている //dataByteArray = new byte[4]; //Array.Copy(data, i, dataByteArray, 0, 3); //i += 3; //// byte配列をintに変換 //var tempo = BitConverter.ToInt32(dataByteArray, 0); var tempo = 0; tempo |= data[i++]; tempo <<= 8; tempo |= data[i++]; tempo <<= 8; tempo |= data[i++]; { // ソフラン情報生成 var soflan = new SoflanData(); soflan.EventTime = (int)currentTime; // BPM割り出し soflan.Bpm = 60000000 / (float)tempo; // 小数点第1で切り捨て処理(10にすると第一位、100にすると第2位まで切り捨てられる) soflan.Bpm = Mathf.Floor(soflan.Bpm * 10) / 10; // tick値割り出し soflan.Tick = (60 / soflan.Bpm / division * 1000); // リストにつっこむ soflanList.Add(soflan); } System.Diagnostics.Debug.WriteLine("Set Tempo. tt:" + tempo); break; case 0x54: // SMTPEオフセット if (dataLength != 0x05) { throw new Exception("SMTPE Offset not value 0x05."); } // hour dataByte0 = data[i++]; // minutes dataByte1 = data[i++]; // seconds dataByte2 = data[i++]; // frames dataByte3 = data[i++]; // fractional frame. tmp = data[i++]; System.Diagnostics.Debug.WriteLine("SMTPE Offset. hh:" + dataByte0 + ", mm:" + dataByte1 + ", ss:" + dataByte2 + ", fr:" + dataByte3 + " , ff:" + tmp); break; case 0x58: // 拍子 if (dataLength != 0x04) { throw new Exception("Time Signature not value 0x04."); } // Time signature numerator dataByte0 = data[i++]; // Time signeture denominator expressed as a power of 2 dataByte1 = data[i++]; // MIDI Clocks per metronome tick dataByte2 = data[i++]; // Number of 1/32 notes per 24 MIDI clocks(8 is standard) dataByte3 = data[i++]; { // 拍子情報生成 var beat = new BeatData(); beat.EventTime = (int)currentTime; // 分子 beat.Numerator = dataByte0; // 分母 beat.Denominator = 1; for (int j = 0; j < dataByte1; j++) { beat.Denominator *= 2; // 2の累乗 } // リストにつっこむ beatList.Add(beat); } System.Diagnostics.Debug.WriteLine("Time Signature. nn:" + dataByte0 + ", dd:" + dataByte1 + ", cc:" + dataByte2 + ", bb:" + dataByte3); break; case 0x59: // 調号 if (dataLength != 0x02) { throw new Exception("Key Signature not value 0x02."); } // number of sharps or flats -7, 0(key of C), +7 dataByte0 = data[i++]; // 0: major key. 1: minor key dataByte1 = data[i++]; System.Diagnostics.Debug.WriteLine("Key Signature. sf:" + dataByte0 + ", mi:" + (dataByte1 == 0 ? "major key" : "minor key")); break; case 0x7f: // シーケンサ固有メタイベント // length of <id>+<data> dataLength = data[i++]; // 1 or 3 bytes repressenting the Manufacture's ID if (dataLength - 8 == 1) { dataByte1 = data[i++]; } else if (dataLength - 8 == 3) { dataByteArray = new byte[3]; Array.Copy(data, i, dataByteArray, 0, 3); i += 3; } else { throw new Exception("Seuencer-Specific Meta-event length not 1 or 3"); } // 8-bit binary data dataByteArray = new byte[8]; Array.Copy(data, i, dataByteArray, 0, 8); i += 8; System.Diagnostics.Debug.WriteLine("Seuencer-Specific Meta-event"); break; default: throw new Exception("meta event unintended value:" + tmp); } } } } catch (Exception e) { // エラーメッセージ処理 Debug.LogWarning("MIDIDataAnalysisError: " + e); failure(); } // テンポを元にイベント時刻を補正 ModificationEventTimes(noteList, soflanList, beatList); success(noteList.ToArray(), soflanList.ToArray(), beatList.ToArray()); }
private void ManageOnBeat(BeatData beatData) { float newPos = myEntityTransform.position.x + (beatData.GetTimeToFollowingBeat(beatData, 1) * gameConfig.playerSpeedOnDoTween); MoveMe(newPos, gameConfig.playerSpeedOnDoTween / gameConfig.playerSpeedOnDoTween * beatData.GetTimeToFollowingBeat(beatData, 1)); }
public void OnBeat(BeatData beatData) { DOTween.Kill("PunchPlayer", true); myEntityTransform.DOPunchScale(Vector3.one * 0.2f, 0.2f).SetId("PunchPlayer"); }
public void AddBeatToConversation(BeatData beatData) { currentConversation.Add(beatData); }
private void Awake() { _output = GetComponentInChildren <TextDisplay>(); _currentBeat = null; _wait = new WaitForSeconds(0.5f); }