Announcement

Collapse
No announcement yet.

Delay while package loads (was "DynamicLoadObject not loading package")

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Delay while package loads (was "DynamicLoadObject not loading package")

    @Chosker
    After some testing, it looks like you were right about the package taking some time to load. I appear to have been mistaken as to the nature of DynamicLoadObject, in that it performs a non-blocking load (i.e initiates loading but returns immediately rather than waiting). This makes sense, now that I think about it, given the fact that you wouldn't want pauses for content loading in the middle of a deathmatch, say.
    Ordinarily I'd not have a problem with simply waiting and trying to use the content after a slight delay, but given this is dialogue any pause long enough to absolutely guarantee content is fully loaded would be noticeable and not really desirable.



    Bearing my discovery in mind, my new question is this: Does anybody know of a decent way to ensure that the appropriate package is loaded far enough in advance for my call to DynamicLoadObject/PlaySound to succeed, but without introducing unacceptable delays between the player initiating conversation and the audio playing?


    I could have each NPC load the package containing their dialogue data in PostBeginPlay() or defaultproperties but the number of NPCs would make this consume too much memory I think.

    Alternatively I could load the package containing NPC dialogue based on NPC proximity to the player, but the problem of memory consumption remains insofar as if the player simply walks past a number of NPCs they would inadvertently trigger the loading of a number of packages, whether they be used (through conversation being initiated) or not. Is this a concern? Will the engine intelligently unload those packages again if they aren't actually being referenced, or will they stay in memory until the level transitions?


    Feel free to move this post back into the general forum if it would be more appropriate there.



    Original post is as follows:


    My understanding of DynamicLoadObject is that it will load packages required before attempting to instantiate the requested class.

    Unfortunately, when I attempt to use it to instantiate a SoundCue like so:

    Code:
    SoundToPlay = SoundCue(DynamicLoadObject(params.SoundBite, class'SoundCue'));
    		GetPC().Pawn.PlaySound(SoundToPlay);
    It fails to load - nothing happens.

    params.SoundBite is a string.

    On the other hand,

    Code:
    GetPC().Pawn.PlaySound(SoundCue'EFPL_Cafe_Dialogue.barista_01_Cue');
    works without any issues.

    I've resolved this temporarily by putting a hardcoded reference to an object in the package in defaultproperties (which evidently forces the package to be loaded automatically, and therefore DynamicLoadObject succeeds), but my understanding was that the entire point of DynamicLoadObject vs FindObject is that DynamicLoadObject would load the package if it had to. This behaviour seems to not reflect that.

    I'm using the 32-bit build of the May 2012 UDK.

    #2
    Depends on what Params.SoundBite is .

    Comment


      #3
      My bad - its a String.

      Edited my post to indicate that.

      Comment


        #4
        Depends what the contents of that is.

        Comment


          #5
          Apologies for not being more forthcoming. Param.Soundbite contains a string that is fetched from an external data source. The key thing is that the code functions correctly *if* I force the package to load by hard coding a reference to a dummy file in the defaultproperties of the object. That is to say, I have DynamicLoadObject functioning correctly with respect to fetching the sound (I.e the string is the correct value), but it is not loading the package concerned unless it is already referenced.
          In other words, I don't see how the string could be the problem because it works if hardcoded (presumably because that means a package reference is hard coded, forcing the package to load). In any event the contents of param.Soundbite in my first test was the string "EFPL_Cafe_Dialogue.barista_01_Cue".

          Just to be clear, I appreciate your assistance, SS. Just not sure if there's some nuance I'm not aware of that would make the string relevant, if I can show it works when hardcoded into the uc file.

          Comment


            #6
            that's odd.
            this works for me:
            Code:
            	SkelMeshName = SkeletalMesh(DynamicLoadObject(DefaultInvObj.Model, class'SkeletalMesh', true)); // True at the end for silent errors
            DefaultInvObj.Model is just a string that is pulled externally (I use Sapitu).

            perhaps you're not correctly fetching the value from the external data source, how are you doing so?

            Comment


              #7
              I fetch the value using DLLBind and a custom SQLite library i use all throughout my project.
              As I said before though - I can verify the string is correct because the code works *if* my file contains a hardcoded reference to the package, for eg:
              Code:
              dummy=Material'EFPL_Cafe_Dialogue.Dummy'
              Doesn't matter what item from the package is referenced, or where (in a function or the defaultproperties block), my uc file must force a load of the package in advance of my use of dynamicloadobject, by containing said reference, or dynamicloadobject fails, which seems at odds with the documentation concerning the function (which states it will load the package itself if necessary), and is the reason I've posted here rather in just the generic Uscript forum.

              Thanks for the feedback so far. I've attached a condensed copy of the file in question in case that makes things a bit clearer for people.

              Code:
              class EFPLConversationMenu extends GFxMoviePlayer_NotifyClosed classgroup(EFPL);
              
              Var material dummy;
              
              
              function InitConversation(int entityID, int conversationID, int nodeID)
              {
              	local SoundCue soundToPlay;
              	
              	//<snip>
              	
              		SoundToPlay = SoundCue(DynamicLoadObject(params.SoundBite, class'SoundCue'));
              		GetPC().Pawn.PlaySound(SoundToPlay);
              
              	
              }
              
              
              defaultproperties
              {
              	//<snip>
              	
              	//this line is needed in order for the above call to dynamicloadobject to succeed
              	dummy=Material'EFPL_Cafe_Dialogue.Dummy'
              	
              }

              Comment


                #8
                What are you deploying to? iOS or PC? Because DynamicLoadObject can only give you references to things that have been loaded already on consoles and iOS, so you need to force the package to be loaded already with some INI magic or by embedding the resources directly in the map.

                Comment


                  #9
                  so it's not that much of a problem with DynamicLoadObject, but one regarding loading an asset if the package is loaded or not.

                  have you tried dynamicloadobject on the asset itself?
                  Code:
                  SoundToPlay = SoundCue(DynamicLoadObject("Package.TheActualSound", class'SoundCue'));
                  just to make sure the package is being loaded that way, and see if the problem with it not loading the package is caused by using an external string instead of a direct reference to the package.

                  now you say the documentation claims it will load the package if it needs to. and you say it doesn't play because the package isn't really being loaded. is there a possibility that the package is being loaded, but not in time for the sound to play? (ie. the sound tries to play without waiting for the package to finish loading first, and so it fails). worth a shot to try setting a timer to play the sound after a few seconds just to rule that out.

                  in any case, I've only ever done a DynamicLoadObject from already loaded packages. in general I use it for body parts and equipment, which I've included as packages to always load.

                  Comment


                    #10
                    Originally posted by Crusha K. Rool View Post
                    What are you deploying to? iOS or PC? Because DynamicLoadObject can only give you references to things that have been loaded already on consoles and iOS, so you need to force the package to be loaded already with some INI magic or by embedding the resources directly in the map.
                    This occurs with both the editor and the *unpackaged* PC game (i.e. just loading the map from the command line). I'm aware of the issues with forcing a dynamic-referenced-only package to be cooked when deploying, but I'm not at that stage yet.


                    @Chosker
                    Please note, I have edited my original post to respond to your comment.

                    Comment


                      #11
                      glad to be of help, and good thing you found the source of the problem
                      indeed since this is now a matter of how to handle loading or not of audio resources in a smart way, should probably be moved to the programming forum.

                      I'm going to assume here that you're using some sort of dialogue trees or at least dialog sequences. can you just load on PostBeginPlay the first ever thing that an NPC will say to you, and if you start talking to him he'll load the next dialogue sequence (or options in the tree) as he's speaking that first dialogue to you?
                      or maybe this is already what you were thinking.

                      one think I don't know here: if you use DynamicLoadObject on something, will it fully load the package? or will it only "kinda load it" and fully load the resource you want? think of it like when you open the editor: if there's stuff in a package that is being referenced by code, those items will be visible if you select the package in the content browser, but the rest of the stuff will only be visible if you right click it and select 'fully load'.
                      if it doesn't fully load the package, it might be a good idea to just put all of your dialogue sounds inside one package. but if it does fully load it then you'd have *all* of your dialogue sounds in memory so it'd be a bad idea.
                      so it's worth knowing I think.

                      Comment

                      Working...
                      X