UDataAsset - Data Assets in Unreal C++ - Data Instances and Data Classes - UE C++ Tutorial

แชร์
ฝัง
  • เผยแพร่เมื่อ 24 ต.ค. 2024

ความคิดเห็น • 23

  • @peacesells2847
    @peacesells2847 5 หลายเดือนก่อน

    Another video LOADED with detailed info that you usually don't see anywhere else! Thanks a lot for making these videos!!

    • @enigma_dev
      @enigma_dev  4 หลายเดือนก่อน

      Happy to help :)

  • @maciekgadek6480
    @maciekgadek6480 4 หลายเดือนก่อน +1

    Yet another quality video. Can't believe this channel is not wildly popular at this point. I've been working / using UDataAssets for quite a while and still I learned lots of useful stuff from your video.
    IIRC last time you mentioned that you have already couple of videos in production pipeline, I wonder if there are any plans for video about UPrimaryDataAsset, soft object references or asset manager? There are a couple of videos about these but none really demonstrates when to use them, what practical problems they solve and general good practices ralated.

    • @enigma_dev
      @enigma_dev  4 หลายเดือนก่อน +1

      Hey, thanks for the kind words :)
      Unfortunately the current videos I am working on are not those topics. Though, I do want to make an async-loading soft references video.
      I am hesitant to make a video on UPrimaryDataAsset and asset manager soon, because I don't know that I understand all the ins-and-outs on that system. Also I feel like there's a lot of leading up video, like async loading, softobjectptrs, etc. that I need to make first.
      I should take a look at the lyra project and see how it is using primary data assets.
      Right now, I feel like there is some more pressing videos I should make with some fundamental concepts I sort of skipped (like code generation via UHT).
      But maybe I'll make a UPrimaryDataAsset video with a disclaimer that there might be more to it, to kind of close up the series of videos on data management. I'll have to see. Personally I've been itching to get back to gameplay systems like replication, etc.

  • @youseiy
    @youseiy 5 หลายเดือนก่อน +2

    chad posted a new video, must watch! Keep up with content!

  • @GfxWakeup
    @GfxWakeup หลายเดือนก่อน +1

    Hello, thanks for a beautiful explanation, it's very high quality material!
    I have a question. My code architecture is currently based on those DataAssets .. let's say I have monstersDA, and I am sometimes updating their values like HP, status, etc - which then reflects on the UI widgets which are taking values from these Data Assets. Is this a wrong architecture? What's wrong on modifying these DataAssets - if they represents an entity (actor) within the game? What's your thought on this, or what would you recommend doing instead? Thanks a lot for the help!

    • @enigma_dev
      @enigma_dev  หลายเดือนก่อน

      Hey, great question.
      6:41 is where I speak a little bit to this.
      But I think it depends on exactly how you mean here.
      The main thing I am referring to, is we have a single data asset in memory.
      So if you're using a data asset to represent an entities current health, if you write a new health value to the data asset, then you affecting entity that is using that data asset.
      IE if you have entity X and entity Y, you set a data assets current health to 5 for entity X, then Y get's their current health set to 5 as well (despite that likely being a mistake).
      In this case, I would use a Data asset to represent static values (like the max health, etc.)
      But runtime values, I would push to the actor itself (or a component on the actor to make it easy to share behavior).
      That way there's a clear separation between const data, and runtime data.
      But perhaps you mean, it is static data, but you're changing the "max health" for everyone at once.
      Perhaps with like a level or difficulty system?
      So you change difficulty, every enemies max health changes.
      That could work for UDataAssets I suppose, but I think at that point you need to set up delegate hooks for changes.
      I feel like there's probably some other subtle issues there I'm not thinking of.
      Personally I'd set up a UDataAsset for Easy, Medium, and Hard difficulties, and change which data asset the entity is pointing to.
      Or set up a UDataTable spreadsheet (see my other video on that) and have it point to a new row.
      Oh, one issue with using UDataAsset for shared values, is likely it won't work for replication. (though I personally have never tried this, replicating values on data assets). There might be a potential server/client desync if a server changes a value, but the client doesn't also go through the flow to change the value. I think things simplify a lot if you can push these changing values to the actors/actorcomponents themselves.
      edit: There's also perhaps what designers would expect a data asset file to be. They would want to open up to expecting to populate data. So changing it at runtime might violate some expectations there. Overall just isn't something I have seen used before, modifying the properties at runtime. But I haven't looked through all the sample projects, if there's some precedent for it then that would be interesting. Curious to know more of the specifics in this situation. For changing values, you could use FScaleableFloat which lets you set values per level but then you have to introduce a curve table spreadsheet. The levels are defined by columns in the table. You can get values as ints or bools too, not just floats, just have to call a different function and it will cast the float value to the type you request.

  • @staticjpl
    @staticjpl 4 หลายเดือนก่อน +1

    I have a request that might be related. Could you do a tutorial on how the UObjectHandle class work? I have experience with exceptions the handles throw. I just feel now that Unreal is going towards TObjectPtr which are wrappers to the raw pointers, an understanding on how these handles work for caching or lazy loading purposes might come in handy when debugging issues that arise from them.

    • @enigma_dev
      @enigma_dev  4 หลายเดือนก่อน

      That would be a good topic. To be honest though, I don't currently know much about the underlying FObjectHandle class that TObjectPtr appears to be relying on. I've been sort of just treating TObjectPtr like a raw pointer for properties, treating it like a black box.
      I struggle between going too low level on things, I like to focus my videos on the public APIs (like TObjectPtr, TWeakObjectPtr, TSoftObjectPtr, etc.) and try to avoid the internals of things that are meant to be abstracted away. If I make a video on TObjectPtr, it probably won't be too soon, as I have some other big videos I am working on atm.
      You probably already are aware of this, but you don't mark up your TObjectPtrs with UPROEPRTY(), the garbage collector can still free the underlying pointer, and it won't know about the TObjectPtr that should be keeping the reference alive. That can create a memory issue. Easiest solve is to just put UPROPERTY() or UPROPERTY(Transient) above of your TObjectPtrs. So the GC will know not to delete stuff still used.
      I use UPROPERTY(Transient) for runtime objects that are not really configuration, like "which player controller is currently using this thing, etc" that can often change at runtime.

    • @staticjpl
      @staticjpl 4 หลายเดือนก่อน

      @@enigma_dev I am currently publishing a few Unreal Engine documents fairly soon. I've already completed a Reflection one that covers in detail front to back the entire process in C++. Currently I am also finishing up a second document that covers the entire construction and post initialization process for UObjects (FObjectInitialzier,FObjectInstancingGraph) etc.. The reflection one is behind a private repo till I release it. So DM if you want access to It. With regard to the FObjectHandle it's just a container which wraps a UObject Pointer for lazy loading and caching. TObjectPointer gets stripped down to a raw pointer at the end of the day. Epic realized that with 64 bit architectures they could stuff more information in the remaining bits of a pointer so with TObjectPointer they basically encode with it with additional information (Debug info, names etc). I am just unsure how the handles are managed and used yet.

  • @GlassesAndCoffeeMugs
    @GlassesAndCoffeeMugs 4 หลายเดือนก่อน +1

    Say I create a C++ data asset. I create a BP instance of this asset. Designers modify the blueprint instance and give it some values. What's the best way to access those values from C++? My current approach is to give the data asset class a primary asset ID (or just make it UPrimaryAsset), then setup the primary asset in Project Settings > Asset Manager. Then from the cpp side I can use the asset ID + AssetManager to get the path of the primary asset and load. Is there a better way?

    • @enigma_dev
      @enigma_dev  4 หลายเดือนก่อน +1

      fwiw I think it might depend a bit on the context.
      Also, just for clarity, this video is on UDataAssets, not UPrimaryDataAssets. Primary data assets are a subclass of UDataAssets, but have a bit more involved (basically what you've outlined). One day maybe I'll make a video on PrimaryDataAssets, but need to make sure I cover everything accurately.
      Anyways, back to the question. Your approach of getting a primary asset ID and loading from that seems fine to me. I'm more curious of how your C++ code obtains the primaryassetid. I think it is fine if that is a UPROEPRTY that they set, and you use that to load the primary data asset object. That sounds good to me. But if you have it hardcoded as a string somewhere, I don't think that's ideal. If you are using hardcoded strings, then I would consider ways you maybe could avoid that. Some sort of property in editor where you can set it. Sorry I know that might not be much help. This is an area I need to spend some more time on to learn more thoroughly.

    • @GlassesAndCoffeeMugs
      @GlassesAndCoffeeMugs 4 หลายเดือนก่อน

      @@enigma_dev No problem mate, was literally thinking the exact same thing (having a hardcoded asset type and/or asset name would not be preferable). Right now it's hardcoded. I'll see about exposing it to the editor somehow.
      Anyway, I'm doing "AssetManager.GetPrimaryAssetDataList(AssetType)" to return an array of FAssetData, then I can iterate the array and check the primary IDs for the unique name of the asset I want to load. Seems to be working so far.
      Keep up the great work, your channel is awesome.

    • @enigma_dev
      @enigma_dev  4 หลายเดือนก่อน

      ​ @GlassesAndCoffeeMugs
      Thanks :)
      I believe you use a primary asset id uproperty to specify the asset in the editor.
      UPROPERTY(EditAnywhere)
      FPrimaryAssetId AssetId
      But then that becomes a question of where to put that property for a given system.

    • @enigma_dev
      @enigma_dev  4 หลายเดือนก่อน +1

      @@GlassesAndCoffeeMugs
      Thanks :)
      I believe you use a primary asset id uproperty to specify the asset in the editor.
      UPROPERTY(EditAnywhere)
      FPrimaryAssetId AssetId
      But then that becomes a question of where to put it for a given system. Maybe GameState if it is globally available for a gamemode. Maybe as a column in a UDataTable if working with spreadsheets.

  • @shannenmr
    @shannenmr 5 หลายเดือนก่อน

    Think it would be helpful to some if you expanded on why you would use Data Assets over Data Tables and maybe go into ASync Loading / Asset Manager / Querying Meta Data features.

    • @enigma_dev
      @enigma_dev  5 หลายเดือนก่อน +1

      Data tables is the next video I'm working on :)
      Though I didn't directly contrast them in the upcoming video. My gut reaction to the question is, do I want to edit this data in a spreadsheet view (UDataTables) or as an individual asset view (UDataAssets). There's also more nuance (eg composite table overrides for data tables, or primarydataassets(subclass-of-udataasset) asset bundle asnyc loading softobject ptrs). Also, these two concepts can be used together too, you can also put a tablerow-handle(pointing to a UDataTable) in a UDataAsset to have the best of both worlds, if it makes sense for the use case.
      The async loading, asset manager, primary data assets, are all things I want to cover in the future. :)

  • @l_t_m_f
    @l_t_m_f 5 หลายเดือนก่อน +2

    although your videos are amazing, why are you asking the viewer to watch it at a faster speed? i'm asking because I feel like initial speed of the video is aleady perfectly appropriate.

    • @sgtbooz
      @sgtbooz 5 หลายเดือนก่อน

      lol indeed. Default is too fast already.

    • @enigma_dev
      @enigma_dev  5 หลายเดือนก่อน +2

      I had some previous videos that were a bit faster, but some viewers thought them too fast.
      So I've slowed my newer videos down to hopefully address that feedback. But I still feel this is very slow.
      So rather than forcing everyone to go fast, I thought to just put a reminder before the actual video starts that it can be watched on faster speeds.
      I didn't want to make people feel like they must increase speed, just a suggestion. IMO it is a big productivity boost to watch videos on 1.5-2x speed (depends on the video, sometimes slower). For me only takes about 5-10seconds for my brain to adjust. But I know some people can't stand it. There's also some OS dependent behavior too (increased speed on windows/linux sounds much better than on mac, last time I checked mac audio sounded weird). So I realize not everyone likes increased speed. So I tried to communicate it as optional, but nudge people to at least try a speed a bit higher than the default. But maybe that's a mistake. I'd say if you like the speed as is, than it is fine to leave it at the default :)
      This video in particular has a lot of auxiliary information to dataassets (eg setting up a spawner actor, etc.) So I felt I might lose some people during those sections, unless viewing on higher speeds.
      Curious if you have any more thoughts on it. Did it come off as "you really should increase the view speed"? I really only intended it to be a slight nudge.

    • @enigma_dev
      @enigma_dev  5 หลายเดือนก่อน

      Think so? this video in particular too fast, or the videos are in general?

    • @sgtbooz
      @sgtbooz 5 หลายเดือนก่อน +1

      @@enigma_dev Yea, personally I just pause and rewatch, either skipping the auxiliary info for later, or note down everything in one go. So no real problem specifically for me.
      If I had to make a suggestion, it would be the voice volume. Not the recording, but the voice itself. Sometimes it appears you whispered while recording and then ramped up the volume for the video.
      But no really breaking issue there either tbh.

    • @quadriproduction
      @quadriproduction 5 หลายเดือนก่อน +1

      @@enigma_dev gist would be the best..fast speed ..copy and paste ..fast learning...just idea..anyway tkank you