Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Koreographer - Audio Driven Events, Animation, and Gameplay

Discussion in 'Assets and Asset Store' started by SonicBloomEric, Sep 15, 2015.

  1. cosic196

    cosic196

    Joined:
    Mar 15, 2018
    Posts:
    6
    Hi Eric, can you please help me?

    I'm trying to procedurally add Koreography Tracks during runtime.
    Here's the test code I'm using and it seems to work only if the Koreography Editor window is open when I press the play button. Otherwise I'm getting a NullReferenceException.

    Code (CSharp):
    1. [RequireComponent(typeof(Koreographer))]
    2. [RequireComponent(typeof(SimpleMusicPlayer))]
    3. public class LevelManager : MonoBehaviour
    4. {
    5.     private Koreographer _koreographer;
    6.     private SimpleMusicPlayer _simpleMusicPlayer;
    7.  
    8.     private void Awake()
    9.     {
    10.         _koreographer = GetComponent<Koreographer>();
    11.         _simpleMusicPlayer = GetComponent<SimpleMusicPlayer>();
    12.         var koreoTrack = ScriptableObject.CreateInstance<KoreographyTrack>();
    13.         KoreographyEvent koreographyEvent = new KoreographyEvent();
    14.         koreographyEvent.StartSample = 0;
    15.         koreographyEvent.EndSample = 0;
    16.         koreoTrack.EventID = "test";
    17.         koreoTrack.AddEvent(koreographyEvent);
    18.         _koreographer.GetKoreographyAtIndex(0).AddTrack(koreoTrack);
    19.         _koreographer.RegisterForEvents("test", OnTestEvent);
    20.         _simpleMusicPlayer.Play();
    21.     }
    22.  
    23.     private void OnTestEvent(KoreographyEvent koreoEvent)
    24.     {
    25.         Debug.Log("WOW");
    26.     }
    27. }
     
  2. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    874
    When reporting exceptions like this, it is always helpful to provide the full report from the console. That will help anyone who sees it better understand what reference was unexpectedly null. As it stands right now, I have to guess.

    And my guess is that you do not have any Koreography loaded when the Koreography Editor window isn't open. Do you have any Koreography loaded in the "Loaded Koreography" field of the Koreographer component? Do you have a Koreography asset specified in your Simple Music Player component?

    Can you provide a screenshot of the NullReferenceException report in your console or otherwise copy the report contents into a message here?

    Also, what happens if you change "Awake()" to "Start()"?
     
  3. cosic196

    cosic196

    Joined:
    Mar 15, 2018
    Posts:
    6
    upload_2020-12-7_17-53-11.png

    Here's a screenshot. I have loaded a Koreography into the Koreographer and into the Simple Music Player.

    Here's the full report from the console if it's hard to read from the screenshot:

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. SonicBloom.Koreo.Koreography.GetTrackByID (System.String eventID) (at <960e9d4d172b4dcf851c77f9dee55996>:0)
    3. SonicBloom.Koreo.Koreography.DoesTrackWithEventIDExist (System.String eventID) (at <960e9d4d172b4dcf851c77f9dee55996>:0)
    4. SonicBloom.Koreo.Koreography.CanAddTrack (SonicBloom.Koreo.KoreographyTrackBase track) (at <960e9d4d172b4dcf851c77f9dee55996>:0)
    5. SonicBloom.Koreo.Koreography.AddTrack (SonicBloom.Koreo.KoreographyTrackBase track) (at <960e9d4d172b4dcf851c77f9dee55996>:0)
    6. LevelManager.Start () (at Assets/Scripts/Level/LevelManager.cs:24)
    I've tried changing Awake to Start, but still get the same error message.

    Btw. I'm using Unity version 2019.4.15f1 and the Koreographer 1.6.1.
    Another thing to note is that I can't open any Koreographer Editor window to get rid of the error, but the editor window which pops up when I click on the edit button in the Simple Music Player/Koreographer component which has the Koreography I'm trying to use. That's the only way to avoid the exception.
     
    Last edited: Dec 7, 2020
  4. cosic196

    cosic196

    Joined:
    Mar 15, 2018
    Posts:
    6
    Also I've modified the code when sending you the question to remove some unnecessary unused parts, but here's the original file if you're trying to find out what's happening at line 24:

    Code (CSharp):
    1. using GameEventBus;
    2. using SonicBloom.Koreo;
    3. using SonicBloom.Koreo.Players;
    4. using UnityEngine;
    5.  
    6. [RequireComponent(typeof(Koreographer))]
    7. [RequireComponent(typeof(SimpleMusicPlayer))]
    8. public class LevelManager : MonoBehaviour
    9. {
    10.     public static EventBus eventBus;
    11.     private Koreographer _koreographer;
    12.     private SimpleMusicPlayer _simpleMusicPlayer;
    13.  
    14.     private void Start()
    15.     {
    16.         _koreographer = GetComponent<Koreographer>();
    17.         _simpleMusicPlayer = GetComponent<SimpleMusicPlayer>();
    18.         var koreoTrack = ScriptableObject.CreateInstance<KoreographyTrack>();
    19.         KoreographyEvent koreographyEvent = new KoreographyEvent();
    20.         koreographyEvent.StartSample = 0;
    21.         koreographyEvent.EndSample = 0;
    22.         koreoTrack.EventID = "test";
    23.         koreoTrack.AddEvent(koreographyEvent);
    24.         _koreographer.GetKoreographyAtIndex(0).AddTrack(koreoTrack);
    25.         _koreographer.RegisterForEvents("test", OnTestEvent);
    26.         _simpleMusicPlayer.Play();
    27.     }
    28.  
    29.     private void OnTestEvent(KoreographyEvent koreoEvent)
    30.     {
    31.         Debug.Log("WOW");
    32.     }
    33.  
    34.     public void StartTheLevel()
    35.     {
    36.        
    37.     }
    38. }
     
  5. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    874
    Did you see my previous post?

    I see that you changed "Awake()" to "Start()". Did that help things at all?

    What is the exact error that you are receiving in the Console?
     
  6. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    874
    If anyone is reading through this conversation, it seems that @cosic196's post got held up in moderation and didn't arrive. The conversation shifted outside of this forum thread briefly as the post was stuck in limbo for a bit...

    The current theory is that @cosic196 is using a Koreography asset but applying an ephemeral (read: not backed by an asset) instance of a KoreographyTrack. When the Editor leaves PlayMode, the underlying C++ instance is destroyed and the C# instance is set to null. This leaves an empty entry inside the Koreography asset's internal tracks list, which, upon re-entry into PlayMode, breaks during an internal validation step. Loading the Koreography asset in the Koreography Editor and keeping it open ensures that the ephemeral KoreographyTrack doesn't get cleaned up because the Koreography (and all of its references) is "serialized" (though not into an asset stored on disk) between PlayMode phases. Once in this state, calls to "AddTrack" in the provided code will return false. However, the track registration will work as it did before because the track already exists (simply from a previous run).

    There are several workarounds to this, but the main two would be:
    1. Create a new (ephemeral) runtime Koreography asset and copy necessary settings (Tempo Sections, AudioClip, Sample Rate) from a "model" Koreography asset.
    2. Be sure to Remove the ephemeral KoreographyTrack asset from the Koreography asset when leaving PlayMode.
    Either of those should be sufficient.
     
  7. cosic196

    cosic196

    Joined:
    Mar 15, 2018
    Posts:
    6
    Thanks for the help!

    Just wanted to let you know that I've tried your suggestion and it works flawlessly. I went with copying settings from an existing Koreography into a new ephemeral Koreography asset and adding KoreographyTracks to it.
    Here's the code for anyone interested:

    Code (CSharp):
    1. using SonicBloom.Koreo;
    2. using SonicBloom.Koreo.Players;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. [RequireComponent(typeof(SimpleMusicPlayer))]
    7. [RequireComponent(typeof(Koreographer))]
    8. public class KoreographyGeneration : MonoBehaviour
    9. {
    10.     [SerializeField]
    11.     private Koreography _koreographyToCopy;
    12.     private Koreography _koreography;
    13.     private Koreographer _koreographer;
    14.     private SimpleMusicPlayer _simpleMusicPlayer;
    15.  
    16.     void Start()
    17.     {
    18.         _koreographer = GetComponent<Koreographer>();
    19.         _simpleMusicPlayer = GetComponent<SimpleMusicPlayer>();
    20.  
    21.         //Copying from given koreography
    22.         _koreography = ScriptableObject.CreateInstance<Koreography>();
    23.         _koreography.SampleRate = _koreographyToCopy.SampleRate;
    24.         _koreography.SourceClip = _koreographyToCopy.SourceClip;
    25.         List<TempoSectionDef> tempoSectionsToCopy = new List<TempoSectionDef>();
    26.         for (int i = 0; i < _koreographyToCopy.GetNumTempoSections(); i++)
    27.         {
    28.             tempoSectionsToCopy.Add(_koreographyToCopy.GetTempoSectionAtIndex(i));
    29.         }
    30.         _koreography.OverwriteTempoSections(tempoSectionsToCopy);
    31.  
    32.         //Creating and inserting a new koreography track
    33.         var koreoTrack = ScriptableObject.CreateInstance<KoreographyTrack>();
    34.         KoreographyEvent koreographyEvent = new KoreographyEvent();
    35.         koreographyEvent.StartSample = 0;
    36.         koreographyEvent.EndSample = koreographyEvent.StartSample;
    37.         koreoTrack.EventID = "test";
    38.         koreoTrack.AddEvent(koreographyEvent);
    39.         _koreography.AddTrack(koreoTrack);
    40.  
    41.         _koreographer.LoadKoreography(_koreography);
    42.         _koreographer.RegisterForEvents("test", OnTestEvent);
    43.         _simpleMusicPlayer.LoadSong(_koreography, 0, false);
    44.         _simpleMusicPlayer.Play();
    45.     }
    46.  
    47.     private void OnTestEvent(KoreographyEvent koreoEvent)
    48.     {
    49.         Debug.Log("WOW");
    50.     }
    51. }
     
    Last edited: Dec 13, 2020
    SonicBloomEric likes this.
  8. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    874
    We have created a Discord server to host discussions pertaining to Koreographer! To participate, please follow the server invite link here.
     
    Last edited: Jan 19, 2021
unityunity