Beispiel #1
0
    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;
        }
    }
Beispiel #2
0
 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));
        }
    }
Beispiel #4
0
    private IEnumerator DoDisplay(BeatData data)
    {
        _output.Clear();

        while (_output.IsBusy)
        {
            yield return(null);
        }

        _output.Display(data.DisplayText);

        while (_output.IsBusy)
        {
            yield return(null);
        }
    }
Beispiel #5
0
    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);
        }
    }
Beispiel #6
0
    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();
        }
    }
Beispiel #7
0
    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());
        }
    }
Beispiel #8
0
    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);
    }
Beispiel #9
0
    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);
    }
Beispiel #10
0
    // 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();
        // }
    }
Beispiel #11
0
    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();
        }
    }
Beispiel #12
0
 private void BeatActions(BeatData beatData)
 {
     StartCoroutine(BeatActionDelay(beatData));
 }
Beispiel #13
0
    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;
        }
    }
Beispiel #14
0
    /// <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());
    }
Beispiel #15
0
    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));
    }
Beispiel #16
0
 public void OnBeat(BeatData beatData)
 {
     DOTween.Kill("PunchPlayer", true);
     myEntityTransform.DOPunchScale(Vector3.one * 0.2f, 0.2f).SetId("PunchPlayer");
 }
Beispiel #17
0
 public void AddBeatToConversation(BeatData beatData)
 {
     currentConversation.Add(beatData);
 }
Beispiel #18
0
 private void Awake()
 {
     _output      = GetComponentInChildren <TextDisplay>();
     _currentBeat = null;
     _wait        = new WaitForSeconds(0.5f);
 }