• Try the new UI Toolkit sample – now available on the Asset Store

    In Unity 2021 LTS, UI Toolkit offers a collection of features, resources, and tools to help you build and debug adaptive runtime UIs on a wide range of game applications and Editor extensions. Its intuitive workflow enables Unity creators in different roles – artists, programmers, and designers alike – to get started with UI development as quickly as possible.See our earlier blog post for an explanation of UI Toolkit’s main benefits, such as enhanced scalability and performance, already being leveraged by studios like Mechanistry for their game, Timberborn.While Unity UI remains the go-to solution for positioning and lighting UI in a 3D world or integrating with other Unity systems, UI Toolkit for runtime UI can already benefit game productions seeking performance and scalability as of Unity 2021 LTS. It’s particularly effective for Screen Space – Overlay UI, and scales well on a variety of screen resolutions.That’s why we’re excited to announce two new learning resources to better support UI development with UI Toolkit:UI Toolkit sample – Dragon Crashers: The demo is now available to download for free from the Asset Store.User interface design and implementation in Unity: This free e-book can be download from hereRead on to learn about some key features part of the UI Toolkit sample project.The UI Toolkit sample demonstrates how you can leverage UI Toolkit for your own applications. This demo involves a full-featured interface over a slice of the 2D project Dragon Crashers, a mini RPG, using the Unity 2021 LTS UI Toolkit workflow at runtime.Some of the actions illustrated in the sample project show you how to:Style with selectors in Unity style sheetfiles and use UXML templatesCreate custom controls, such as a circular meter or tabbed viewsCustomize the appearance of elements like sliders and toggle buttonsUse Render Texture for UI overlay effects, USS animations, seasonal themes, and moreTo try out the project after adding it to your assets, enter Play mode. Please note that UI Toolkit interfaces do not appear in the Scene view. Instead, you can view them in the Game view or UI Builder.The menu on the left helps you navigate the modal main menu screens. This vertical column of buttons provides access to the five modal screens that comprise the main menu.While some interactivity is possible, such as healing the characters by dragging available potions in the scene, gameplay has been kept to a minimum to ensure continued focus on the UI examples.Let’s take a closer look at the UIs in the menu bar:The home screen serves as a landing pad when launching the application. You can use this screen to play the game or receive simulated chat messages.The character screen involves a mix of GameObjects and UI elements. This is where you can explore each of the four Dragon Crashers characters. Use the stats, skills, and bio tabs to read the specific character details, and click on the inventory slots to add or remove items. The preview area shows a 2D lit and rigged character over a tiled background.The resources screen links to documentation, the forum, and other resources for making the most of UI Toolkit.The shop screen simulates an in-game store where you can purchase hard and soft currency, such as gold or gems, as well as virtual goods like healing potions. Each item in the shop screen is a separate VisualTreeAsset. UI Toolkit instantiates these assets at runtime; one for each ScriptableObject in the Resources/GameData.The mail screen is a front-end reader of fictitious messages that uses a tabbed menu to separate the inbox and deleted messages.The game screen is a mini version of the Dragon Crashers project that starts playing automatically. In this project, you’ll notice a few revised elements with UI Toolkit, such as a pause button, health bars, and the capacity to drag a healing potion element to your characters when they take damage.UI Toolkit enables you to build stable and consistent UIs for your entire project. At the same time, it provides flexible tools for adding your own design flourishes and details to further flesh out the game’s theme and style.Let’s go over some of the features used to refine the UI designs in the sample:Render Textures:UI Toolkit interfaces are rendered last in the render queue, meaning you can’t overlay other game graphics on top of a UI Toolkit UI. Render Textures provide a workaround to this limitation, making it possible to integrate in-game effects into UI Toolkit UIs. While these effects based on Render Textures should be used sparingly, you’ll still be able to afford sharp effects within the context of a fullscreen UI, without running gameplay. The following images show a number of Render Textures from the demo.Themes with Theme style sheets: TSS files are Asset files that are similar to regular USS files. They serve as a starting point for defining your own custom theme via USS selectors as well as property and variable settings. In the demo, we duplicated the default theme files and modified the copies to offer seasonal variations.Custom UI elements: Since designers are trained to think outside the box, UI Toolkit gives you plenty of room to customize or extend the standard library. The demo project highlights a few custom-built elements in the tabbed menus, slide toggles, and drop-down lists, plus a radial counter to demonstrate what UI artists are capable of alongside developers.USS transitions for animated UI state changes: Adding transitions to the menu screens can polish and smooth out your visuals. UI Toolkit makes this more straightforward with the Transition Animations property, part of the UI Builder’s Inspector. Adjust the Property, Duration, Easing, and Delay properties to set up the animation. Then simply change styles for UI Toolkit to apply the animated transition at runtime.Post-processing volume for a background blur: A popular effect in games is to blur a crowded gameplay scene to draw the player’s attention to a particular pop-up message or dialog window. You can achieve this effect by enabling Depth of Field in the Volume framework.We made sure that efficient workflows were used to fortify the UI. Here are a few recommendations for keeping the project well-organized:Consistent naming conventions: It’s important to adopt naming conventions that align with your visual elements and style sheets. Clear naming conventions not only maintain the hierarchy’s organization in UI Builder, they make it more accessible to your teammates, and keep the code clean and readable. More specifically, we suggest the Block Element Modifiernaming convention for visual elements and style sheets. Just at a glance, an element’s BEM naming can tell you what it does, how it appears, and how it relates to the other elements around it. See the following BEM naming examples:Responsive UI layout: Similar to web technologies, UI Toolkit offers the possibility of creating layouts where “child” visual elements adapt to the current available size inside their “parent” visual elements, and others where each element has an absolute position anchored to a reference point, akin to the Unity UI system. The sample uses both options as needed through the visual elements of the UI.PSD Importer: One of the most effective tools for creating the demo, PSD Importer allows artists to work in a master document without having to manually export every sprite separately. When changes are needed, they can be done in the original PSD file and updated automatically in Unity.ScriptableObjects: In order to focus on UI design and implementation, the sample project simulates backend data, such as in-app purchases and mail messages, using ScriptableObjects. You can conveniently customize this stand-in data from the Resources/GameData folder and use the example to create similar data assets, like inventory items and character or dialog data in UI Toolkit.Remember that with UI Toolkit, UI layouts and styles are decoupled from code. This means that rewriting the backend data can occur independently from the UI design. If your development team replaces those systems, the interface should continue to work.Additional tools used in the demo include particle systems created with the Built-in Particle System for special effects, and the 2D toolset, among others. Feel free to review the project via the Inspector to see how these different elements come into play.You can find reference art made by the UI artists under UI/Reference, as replicated in UI Builder. The whole process, from mockups to wireframes, is also documented in the e-book. Finally, all of the content in the sample can be added to your own Unity project.You can download the UI Toolkit sample – Dragon Crashers from the Asset Store. Once you’ve explored its different UI designs, please provide your feedback on the forum.Then be sure to check out our e-book, User interface design and implementation in Unity. Download
    #try #new #toolkit #sample #now
    Try the new UI Toolkit sample – now available on the Asset Store
    In Unity 2021 LTS, UI Toolkit offers a collection of features, resources, and tools to help you build and debug adaptive runtime UIs on a wide range of game applications and Editor extensions. Its intuitive workflow enables Unity creators in different roles – artists, programmers, and designers alike – to get started with UI development as quickly as possible.See our earlier blog post for an explanation of UI Toolkit’s main benefits, such as enhanced scalability and performance, already being leveraged by studios like Mechanistry for their game, Timberborn.While Unity UI remains the go-to solution for positioning and lighting UI in a 3D world or integrating with other Unity systems, UI Toolkit for runtime UI can already benefit game productions seeking performance and scalability as of Unity 2021 LTS. It’s particularly effective for Screen Space – Overlay UI, and scales well on a variety of screen resolutions.That’s why we’re excited to announce two new learning resources to better support UI development with UI Toolkit:UI Toolkit sample – Dragon Crashers: The demo is now available to download for free from the Asset Store.User interface design and implementation in Unity: This free e-book can be download from hereRead on to learn about some key features part of the UI Toolkit sample project.The UI Toolkit sample demonstrates how you can leverage UI Toolkit for your own applications. This demo involves a full-featured interface over a slice of the 2D project Dragon Crashers, a mini RPG, using the Unity 2021 LTS UI Toolkit workflow at runtime.Some of the actions illustrated in the sample project show you how to:Style with selectors in Unity style sheetfiles and use UXML templatesCreate custom controls, such as a circular meter or tabbed viewsCustomize the appearance of elements like sliders and toggle buttonsUse Render Texture for UI overlay effects, USS animations, seasonal themes, and moreTo try out the project after adding it to your assets, enter Play mode. Please note that UI Toolkit interfaces do not appear in the Scene view. Instead, you can view them in the Game view or UI Builder.The menu on the left helps you navigate the modal main menu screens. This vertical column of buttons provides access to the five modal screens that comprise the main menu.While some interactivity is possible, such as healing the characters by dragging available potions in the scene, gameplay has been kept to a minimum to ensure continued focus on the UI examples.Let’s take a closer look at the UIs in the menu bar:The home screen serves as a landing pad when launching the application. You can use this screen to play the game or receive simulated chat messages.The character screen involves a mix of GameObjects and UI elements. This is where you can explore each of the four Dragon Crashers characters. Use the stats, skills, and bio tabs to read the specific character details, and click on the inventory slots to add or remove items. The preview area shows a 2D lit and rigged character over a tiled background.The resources screen links to documentation, the forum, and other resources for making the most of UI Toolkit.The shop screen simulates an in-game store where you can purchase hard and soft currency, such as gold or gems, as well as virtual goods like healing potions. Each item in the shop screen is a separate VisualTreeAsset. UI Toolkit instantiates these assets at runtime; one for each ScriptableObject in the Resources/GameData.The mail screen is a front-end reader of fictitious messages that uses a tabbed menu to separate the inbox and deleted messages.The game screen is a mini version of the Dragon Crashers project that starts playing automatically. In this project, you’ll notice a few revised elements with UI Toolkit, such as a pause button, health bars, and the capacity to drag a healing potion element to your characters when they take damage.UI Toolkit enables you to build stable and consistent UIs for your entire project. At the same time, it provides flexible tools for adding your own design flourishes and details to further flesh out the game’s theme and style.Let’s go over some of the features used to refine the UI designs in the sample:Render Textures:UI Toolkit interfaces are rendered last in the render queue, meaning you can’t overlay other game graphics on top of a UI Toolkit UI. Render Textures provide a workaround to this limitation, making it possible to integrate in-game effects into UI Toolkit UIs. While these effects based on Render Textures should be used sparingly, you’ll still be able to afford sharp effects within the context of a fullscreen UI, without running gameplay. The following images show a number of Render Textures from the demo.Themes with Theme style sheets: TSS files are Asset files that are similar to regular USS files. They serve as a starting point for defining your own custom theme via USS selectors as well as property and variable settings. In the demo, we duplicated the default theme files and modified the copies to offer seasonal variations.Custom UI elements: Since designers are trained to think outside the box, UI Toolkit gives you plenty of room to customize or extend the standard library. The demo project highlights a few custom-built elements in the tabbed menus, slide toggles, and drop-down lists, plus a radial counter to demonstrate what UI artists are capable of alongside developers.USS transitions for animated UI state changes: Adding transitions to the menu screens can polish and smooth out your visuals. UI Toolkit makes this more straightforward with the Transition Animations property, part of the UI Builder’s Inspector. Adjust the Property, Duration, Easing, and Delay properties to set up the animation. Then simply change styles for UI Toolkit to apply the animated transition at runtime.Post-processing volume for a background blur: A popular effect in games is to blur a crowded gameplay scene to draw the player’s attention to a particular pop-up message or dialog window. You can achieve this effect by enabling Depth of Field in the Volume framework.We made sure that efficient workflows were used to fortify the UI. Here are a few recommendations for keeping the project well-organized:Consistent naming conventions: It’s important to adopt naming conventions that align with your visual elements and style sheets. Clear naming conventions not only maintain the hierarchy’s organization in UI Builder, they make it more accessible to your teammates, and keep the code clean and readable. More specifically, we suggest the Block Element Modifiernaming convention for visual elements and style sheets. Just at a glance, an element’s BEM naming can tell you what it does, how it appears, and how it relates to the other elements around it. See the following BEM naming examples:Responsive UI layout: Similar to web technologies, UI Toolkit offers the possibility of creating layouts where “child” visual elements adapt to the current available size inside their “parent” visual elements, and others where each element has an absolute position anchored to a reference point, akin to the Unity UI system. The sample uses both options as needed through the visual elements of the UI.PSD Importer: One of the most effective tools for creating the demo, PSD Importer allows artists to work in a master document without having to manually export every sprite separately. When changes are needed, they can be done in the original PSD file and updated automatically in Unity.ScriptableObjects: In order to focus on UI design and implementation, the sample project simulates backend data, such as in-app purchases and mail messages, using ScriptableObjects. You can conveniently customize this stand-in data from the Resources/GameData folder and use the example to create similar data assets, like inventory items and character or dialog data in UI Toolkit.Remember that with UI Toolkit, UI layouts and styles are decoupled from code. This means that rewriting the backend data can occur independently from the UI design. If your development team replaces those systems, the interface should continue to work.Additional tools used in the demo include particle systems created with the Built-in Particle System for special effects, and the 2D toolset, among others. Feel free to review the project via the Inspector to see how these different elements come into play.You can find reference art made by the UI artists under UI/Reference, as replicated in UI Builder. The whole process, from mockups to wireframes, is also documented in the e-book. Finally, all of the content in the sample can be added to your own Unity project.You can download the UI Toolkit sample – Dragon Crashers from the Asset Store. Once you’ve explored its different UI designs, please provide your feedback on the forum.Then be sure to check out our e-book, User interface design and implementation in Unity. Download #try #new #toolkit #sample #now
    UNITY.COM
    Try the new UI Toolkit sample – now available on the Asset Store
    In Unity 2021 LTS, UI Toolkit offers a collection of features, resources, and tools to help you build and debug adaptive runtime UIs on a wide range of game applications and Editor extensions. Its intuitive workflow enables Unity creators in different roles – artists, programmers, and designers alike – to get started with UI development as quickly as possible.See our earlier blog post for an explanation of UI Toolkit’s main benefits, such as enhanced scalability and performance, already being leveraged by studios like Mechanistry for their game, Timberborn.While Unity UI remains the go-to solution for positioning and lighting UI in a 3D world or integrating with other Unity systems, UI Toolkit for runtime UI can already benefit game productions seeking performance and scalability as of Unity 2021 LTS. It’s particularly effective for Screen Space – Overlay UI, and scales well on a variety of screen resolutions.That’s why we’re excited to announce two new learning resources to better support UI development with UI Toolkit:UI Toolkit sample – Dragon Crashers: The demo is now available to download for free from the Asset Store.User interface design and implementation in Unity: This free e-book can be download from hereRead on to learn about some key features part of the UI Toolkit sample project.The UI Toolkit sample demonstrates how you can leverage UI Toolkit for your own applications. This demo involves a full-featured interface over a slice of the 2D project Dragon Crashers, a mini RPG, using the Unity 2021 LTS UI Toolkit workflow at runtime.Some of the actions illustrated in the sample project show you how to:Style with selectors in Unity style sheet (USS) files and use UXML templatesCreate custom controls, such as a circular meter or tabbed viewsCustomize the appearance of elements like sliders and toggle buttonsUse Render Texture for UI overlay effects, USS animations, seasonal themes, and moreTo try out the project after adding it to your assets, enter Play mode. Please note that UI Toolkit interfaces do not appear in the Scene view. Instead, you can view them in the Game view or UI Builder.The menu on the left helps you navigate the modal main menu screens. This vertical column of buttons provides access to the five modal screens that comprise the main menu (they stay active while switching between screens).While some interactivity is possible, such as healing the characters by dragging available potions in the scene, gameplay has been kept to a minimum to ensure continued focus on the UI examples.Let’s take a closer look at the UIs in the menu bar:The home screen serves as a landing pad when launching the application. You can use this screen to play the game or receive simulated chat messages.The character screen involves a mix of GameObjects and UI elements. This is where you can explore each of the four Dragon Crashers characters. Use the stats, skills, and bio tabs to read the specific character details, and click on the inventory slots to add or remove items. The preview area shows a 2D lit and rigged character over a tiled background.The resources screen links to documentation, the forum, and other resources for making the most of UI Toolkit.The shop screen simulates an in-game store where you can purchase hard and soft currency, such as gold or gems, as well as virtual goods like healing potions. Each item in the shop screen is a separate VisualTreeAsset. UI Toolkit instantiates these assets at runtime; one for each ScriptableObject in the Resources/GameData.The mail screen is a front-end reader of fictitious messages that uses a tabbed menu to separate the inbox and deleted messages.The game screen is a mini version of the Dragon Crashers project that starts playing automatically. In this project, you’ll notice a few revised elements with UI Toolkit, such as a pause button, health bars, and the capacity to drag a healing potion element to your characters when they take damage.UI Toolkit enables you to build stable and consistent UIs for your entire project. At the same time, it provides flexible tools for adding your own design flourishes and details to further flesh out the game’s theme and style.Let’s go over some of the features used to refine the UI designs in the sample:Render Textures:UI Toolkit interfaces are rendered last in the render queue, meaning you can’t overlay other game graphics on top of a UI Toolkit UI. Render Textures provide a workaround to this limitation, making it possible to integrate in-game effects into UI Toolkit UIs. While these effects based on Render Textures should be used sparingly, you’ll still be able to afford sharp effects within the context of a fullscreen UI, without running gameplay. The following images show a number of Render Textures from the demo.Themes with Theme style sheets (TSS): TSS files are Asset files that are similar to regular USS files. They serve as a starting point for defining your own custom theme via USS selectors as well as property and variable settings. In the demo, we duplicated the default theme files and modified the copies to offer seasonal variations.Custom UI elements: Since designers are trained to think outside the box, UI Toolkit gives you plenty of room to customize or extend the standard library. The demo project highlights a few custom-built elements in the tabbed menus, slide toggles, and drop-down lists, plus a radial counter to demonstrate what UI artists are capable of alongside developers.USS transitions for animated UI state changes: Adding transitions to the menu screens can polish and smooth out your visuals. UI Toolkit makes this more straightforward with the Transition Animations property, part of the UI Builder’s Inspector. Adjust the Property, Duration, Easing, and Delay properties to set up the animation. Then simply change styles for UI Toolkit to apply the animated transition at runtime.Post-processing volume for a background blur: A popular effect in games is to blur a crowded gameplay scene to draw the player’s attention to a particular pop-up message or dialog window. You can achieve this effect by enabling Depth of Field in the Volume framework (available in the Universal Render Pipeline).We made sure that efficient workflows were used to fortify the UI. Here are a few recommendations for keeping the project well-organized:Consistent naming conventions: It’s important to adopt naming conventions that align with your visual elements and style sheets. Clear naming conventions not only maintain the hierarchy’s organization in UI Builder, they make it more accessible to your teammates, and keep the code clean and readable. More specifically, we suggest the Block Element Modifier (BEM) naming convention for visual elements and style sheets. Just at a glance, an element’s BEM naming can tell you what it does, how it appears, and how it relates to the other elements around it. See the following BEM naming examples:Responsive UI layout: Similar to web technologies, UI Toolkit offers the possibility of creating layouts where “child” visual elements adapt to the current available size inside their “parent” visual elements, and others where each element has an absolute position anchored to a reference point, akin to the Unity UI system. The sample uses both options as needed through the visual elements of the UI.PSD Importer: One of the most effective tools for creating the demo, PSD Importer allows artists to work in a master document without having to manually export every sprite separately. When changes are needed, they can be done in the original PSD file and updated automatically in Unity.ScriptableObjects: In order to focus on UI design and implementation, the sample project simulates backend data, such as in-app purchases and mail messages, using ScriptableObjects. You can conveniently customize this stand-in data from the Resources/GameData folder and use the example to create similar data assets, like inventory items and character or dialog data in UI Toolkit.Remember that with UI Toolkit, UI layouts and styles are decoupled from code. This means that rewriting the backend data can occur independently from the UI design. If your development team replaces those systems, the interface should continue to work.Additional tools used in the demo include particle systems created with the Built-in Particle System for special effects, and the 2D toolset, among others. Feel free to review the project via the Inspector to see how these different elements come into play.You can find reference art made by the UI artists under UI/Reference, as replicated in UI Builder. The whole process, from mockups to wireframes, is also documented in the e-book. Finally, all of the content in the sample can be added to your own Unity project.You can download the UI Toolkit sample – Dragon Crashers from the Asset Store. Once you’ve explored its different UI designs, please provide your feedback on the forum.Then be sure to check out our e-book, User interface design and implementation in Unity. Download
    0 Reacties 0 aandelen
  • Advanced Editor scripting hacks to save you time, part 1

    On most of the projects I’ve seen, there are a lot of tasks developers go through that are repetitive and error-prone, especially when it comes to integrating new art assets. For instance, setting up a character often involves dragging and dropping many asset references, checking checkboxes, and clicking buttons: Set the rig of the model to Humanoid, disable the sRGB of the SDF texture, set the normal maps as normal maps, and the UI textures as sprites. In other words, valuable time is spent and crucial steps can still be missed.In this two-part article, I’ll walk you through hacks that can help improve this workflow so that your next project runs smoother than your last. To further illustrate this, I’ve created a simple prototype – similar to an RTS – where the units of one team automatically attack enemy buildings and other units. With each scripting hack, I’ll improve one aspect of this process, whether that be the textures or models.Here’s what the prototype looks like:The main reason developers have to set up so many small details when importing assets is simple: Unity doesn’t know how you are going to use an asset, so it can’t know what the best settings for it are. If you want to automate some of these tasks, this is the first problem that needs to be addressed.The simplest way to find out what an asset is for and how it relates to others is by sticking to a specific naming convention and folder structure, such as:Naming convention: We can append things to the name of the asset itself, therefore Shield_BC.png is the base color while Shield_N.png is the normal map.Folder structure: Knight/Animations/Walk.fbx is clearly an animation, while Knight/Models/Knight.fbx is a model, even though they both share the same format.The issue with this is that it only works well in one direction. So while you might already know what an asset is for when given its path, you can’t deduce its path if only given information on what the asset does. Being able to find an asset – for example, the material for a character – is useful when trying to automate the setup for some aspects of the assets. While this can be solved by using a rigid naming convention to ensure that the path is easy to deduce, it’s still susceptible to error. Even if you remember the convention, typos are common.An interesting approach to solve this is by using labels. You can use an Editor script that parses the paths of assets and assigns them labels accordingly. As the labels are automated, it’s possible to figure out the exact label that an asset will have. You can even look up assets by their label using AssetDatabase.FindAssets.If you want to automate this sequence, there is a class that can be very handy called the AssetPostprocessor. The AssetPostprocessor receives various messages when Unity imports assets. One of those is OnPostprocessAllAssets, a method that’s called whenever Unity finishes importing assets. It will give you all the paths to the imported assets, providing an opportunity to process those paths. You can write a simple method, like the following, to process them:In the case of the prototype, let’s focus on the list of imported assets – both to try and catch new assets, as well as moved assets. After all, as the path changes, we might want to update the labels.To create the labels, parse the path and look for relevant folders, prefixes, and suffixes of the name, as well as the extensions. Once you have generated the labels, combine them into a single string and set them to the asset.To assign the labels, load the asset using AssetDatabase.LoadAssetAtPath, then assign its labels with AssetDatabase.SetLabels.Remember, it’s important to only set labels if they have actually changed. Setting labels will trigger a reimport of the asset, so you don’t want this to happen unless it’s strictly necessary.If you check this, then the reimport won’t be an issue: Labels are set the first time you import an asset and saved in the .meta file, which means they’re also saved in your version control. A reimport will only be triggered if you rename or move your assets.With the above steps complete, all assets are automatically labeled, as in the example pictured below.Importing textures into a project usually involves tweaking the settings for each texture. Is it a regular texture? A normal map? A sprite? Is it linear or sRGB? If you want to change the settings of an asset importer, you can use the AssetPostprocessor once more.In this case, you’ll want to use the OnPreprocessTexture message, which is called right before importing a texture. This allows you to change the settings of the importer.When it comes to selecting the right settings for every texture, you need to verify what type of textures you’re working with – which is exactly why labels are key in the first step.With this information, you can write a simple TexturePreprocessor:It’s important to ensure that you only run this for textures that have the art label. You’ll then get a reference to the importer so that you can set everything up – starting with the texture size.The AssetPostprocessor has a context property from which you can determine the target platform. As such, you can complete platform-specific changes, like setting the textures to a lower resolution for mobile:Next, check the label to see if the texture is a UI texture, and set it accordingly:For the rest of the textures, set the values to a default. It’s worth noting that Albedo is the only texture that will have sRGB enabled:Thanks to the above script, when you drag and drop the new textures into the Editor, they will automatically have the right settings in place.“Channel packing” refers to the combination of diverse textures into one by using the different channels. It is common and offers many advantages. For instance, the value of the Red channel is metallic and the value of the Green channel is its smoothness.However, combining all textures into one requires some extra work from the art team. If the packing needs to change for some reason, the art team will have to redo all the textures that are used with that shader.As you can see, there’s room for improvement here. The approach that I like to use for channel packing is to create a special asset type where you set the “raw” textures and generate a channel-packed texture to use in your materials.First, I create a dummy file with a specific extension and then use a Scripted Importer that does all the heavy lifting when importing that asset. This is how it works:The importers can have parameters, such as the textures you need to combine.From the importer, you can set the textures as a dependency, which allows the dummy asset to be reimported every time one of the source textures changes. This lets you rebuild the generated textures accordingly.The importer has a version. If you need to change the way that textures are packed, you can modify the importer and bump the version. This will force a regeneration of all the packed textures in your project and everything will be packed in the new way, immediately.A nice side effect of generating things in an importer is that the generated assets only live in the Library folder, so it doesn’t fill up your version control.To implement this, create a ScriptableObject that will hold the created textures and serve as the result of the importer. In the example, I called this class TexturePack.With this created, you can begin by declaring the importer class and adding the ScriptedImporterAttribute to define the version and extension associated with the importer:In the importer, declare the fields you want to use. They will appear in the Inspector, just as MonoBehaviours and ScriptableObjects do:With the parameters ready, create new textures from the ones you have set as parameters. Note, however, that in the Preprocessor, we set isReadable to True to do this.In this prototype, you’ll notice two textures: the Albedo, which has the Albedo in the RGB and a mask for applying the player color in the Alpha, and the Mask texture, which includes the metallic in the Red channel and the smoothness in the Green channel.While this is perhaps outside the scope of this article, let’s look at how to combine the Albedo and the player mask as an example. First, check to see if the textures are set, and if they are, get their color data. Then set the textures as dependencies using AssetImportContext.DependsOnArtifact. As mentioned above, this will force the object to be recalculated if any of the textures end up changing.You also need to create a new texture. To do this, get the size from the TexturePreprocessor that you created in the previous section so that it follows the preset restrictions:Next, fill in all the data for the new texture. This could be massively optimized by using Jobs and Burst. Here we’ll use a simple loop:Set this data in the texture:Now, you can create the method for generating another texture in a very similar way. Once this is ready, create the main body of the importer. In this case, we’ll only create the ScriptableObject that holds the results, creates the textures, and sets the result of the importer through the AssetImportContext.When you write an importer, all of the assets generated must be registered using AssetImportContext.AddObjectToAsset so that they appear in the project window. Select a main asset using AssetImportContext.SetMainObject. This is what it looks like:The only thing left to do is to create the dummy assets. As these are custom, you can’t use the CreateAssetMenuattribute. You must make them manually instead.Using the MenuItem attribute, specify the full path to the create the asset menu, Assets/Create. To create the asset, use ProjectWindowUtil.CreateAssetWithContent, which generates a file with the content you’ve specified and allows the user to input a name for it. It looks like this:Finally, create the channel-packed textures.Most projects use custom shaders. Sometimes they’re used to add extra effects, like a dissolve effect to fade out defeated enemies, and other times, the shaders implement a custom art style, like toon shaders. Whatever the use case, Unity will create new materials with the default shader, and you will need to change it to use the custom shader.In this example, the shader used for units has two added features: the dissolve effect and the player color. When implementing these in your project, you must ensure that all the buildings and units use the appropriate shader.To validate that an asset matches certain requirements – in this case, that it uses the right shader – there is another useful class: the AssetModificationProcessor. With AssetModificationProcessor.OnWillSaveAssets, in particular, you’ll be notified when Unity is about to write an asset to disk. This will give you the opportunity to check if the asset is correct and fix it before it’s saved.Additionally, you can “tell” Unity not to save the asset, which is effective for when the problem you detect cannot be fixed automatically. To accomplish this, create the OnWillSaveAssets method:To process the assets, check whether they are materials and if they have the right labels. If they match the code below, then you have the correct shader:What’s convenient here is that this code is also called when the asset is created, meaning the new material will have the correct shader.As a new feature in Unity 2022, we also have Material Variants. Material Variants are incredibly useful when creating materials for units. In fact, you can create a base material and derive the materials for each unit from there – overriding the relevant fieldsand inheriting the rest of the properties. This allows for solid defaults for our materials, which can be updated as needed.Importing animations is similar to importing textures. There are various settings that need to be established, and some of them can be automated.Unity imports the materials of all the FBXfiles by default. For animations, the materials you want to use will either be in the project or in the FBX of the mesh. The extra materials from the animation FBX appear every time you search for materials in the project, adding quite a bit of noise, so it’s worth disabling them.To set up the rig – that is, choosing between Humanoid and Generic, and in cases where we are using a carefully setup avatar, assigning it – apply the same approach that was applied to textures. But for animations, the message you’ll use is AssetPostprocessor.OnPreprocessModel. This will be called for all FBX files, so you need to discern animation FBX files from model FBX files.Thanks to the labels you set up earlier, this shouldn’t be too complicated. The method starts much like the one for textures:Next up, you’ll want to use the rig from the mesh FBX, so you need to find that asset. To locate the asset, use the labels once more. In the case of this prototype, animations have labels that end with “animation,” whereas meshes have labels that end with “model.” You can complete a simple replacement to get the label for your model. Once you have the label, find your asset using AssetDatabase.FindAssets with “l:label-name.”When accessing other assets, there’s something else to consider: It’s possible that, in the middle of the import process, the avatar has not yet been imported when this method is called. If this occurs, the LoadAssetAtPath will return null and you won’t be able to set the avatar. To work around this issue, set a dependency to the path of the avatar. The animation will be imported again once the avatar is imported, and you will be able to set it there.Putting all of this into code will look something like this:Now you can drag the animations into the right folder, and if your mesh is ready, each one will be set up automatically. But if there isn’t an avatar available when you import the animations, the project won’t be able to pick it up once it’s created. Instead, you’ll need to reimport the animation manually after creating it. This can be done by right-clicking the folder with the animations and selecting Reimport.You can see all of this in the sample video below.Using exactly the same ideas from the previous sections, you’ll want to set up the models you are going to use. In this case, employ AssetPostrocessor.OnPreprocessModel to set the importer settings for this model.For the prototype, I’ve set the importer to not generate materialsand checked whether the model is a unit or a building. The units are set to generate an avatar, but the avatar creation for the buildings is disabled, as the buildings aren’t animated.For your project, you might want to set the materials and animatorswhen importing the model. This way, the Prefab generated by the importer is ready for immediate use.To do this, use the AssetPostprocessor.OnPostprocessModel method. This method is called after a model is finished importing. It receives the Prefab that has been generated as a parameter, which lets us modify the Prefab however we want.For the prototype, I found the material and Animation Controller by matching the label, just as I located the avatar for the animations. With the Renderer and Animator in the Prefab, I set the material and the controller as in normal gameplay.You can then drop the model into your project and it will be ready to drop into any scene. Except we haven’t set any gameplay-related components, which I’ll address in the second part of this blog.With these advanced scripting tips, you’re just about game ready. Stay tuned for the next installment in this two-part Tech from the Trenches article, which will cover hacks for balancing game data and more.If you would like to discuss the article, or share your ideas after reading it, head on over to our Scripting forum. You can also connect with me on Twitter at @CaballolD.
    #advanced #editor #scripting #hacks #save
    Advanced Editor scripting hacks to save you time, part 1
    On most of the projects I’ve seen, there are a lot of tasks developers go through that are repetitive and error-prone, especially when it comes to integrating new art assets. For instance, setting up a character often involves dragging and dropping many asset references, checking checkboxes, and clicking buttons: Set the rig of the model to Humanoid, disable the sRGB of the SDF texture, set the normal maps as normal maps, and the UI textures as sprites. In other words, valuable time is spent and crucial steps can still be missed.In this two-part article, I’ll walk you through hacks that can help improve this workflow so that your next project runs smoother than your last. To further illustrate this, I’ve created a simple prototype – similar to an RTS – where the units of one team automatically attack enemy buildings and other units. With each scripting hack, I’ll improve one aspect of this process, whether that be the textures or models.Here’s what the prototype looks like:The main reason developers have to set up so many small details when importing assets is simple: Unity doesn’t know how you are going to use an asset, so it can’t know what the best settings for it are. If you want to automate some of these tasks, this is the first problem that needs to be addressed.The simplest way to find out what an asset is for and how it relates to others is by sticking to a specific naming convention and folder structure, such as:Naming convention: We can append things to the name of the asset itself, therefore Shield_BC.png is the base color while Shield_N.png is the normal map.Folder structure: Knight/Animations/Walk.fbx is clearly an animation, while Knight/Models/Knight.fbx is a model, even though they both share the same format.The issue with this is that it only works well in one direction. So while you might already know what an asset is for when given its path, you can’t deduce its path if only given information on what the asset does. Being able to find an asset – for example, the material for a character – is useful when trying to automate the setup for some aspects of the assets. While this can be solved by using a rigid naming convention to ensure that the path is easy to deduce, it’s still susceptible to error. Even if you remember the convention, typos are common.An interesting approach to solve this is by using labels. You can use an Editor script that parses the paths of assets and assigns them labels accordingly. As the labels are automated, it’s possible to figure out the exact label that an asset will have. You can even look up assets by their label using AssetDatabase.FindAssets.If you want to automate this sequence, there is a class that can be very handy called the AssetPostprocessor. The AssetPostprocessor receives various messages when Unity imports assets. One of those is OnPostprocessAllAssets, a method that’s called whenever Unity finishes importing assets. It will give you all the paths to the imported assets, providing an opportunity to process those paths. You can write a simple method, like the following, to process them:In the case of the prototype, let’s focus on the list of imported assets – both to try and catch new assets, as well as moved assets. After all, as the path changes, we might want to update the labels.To create the labels, parse the path and look for relevant folders, prefixes, and suffixes of the name, as well as the extensions. Once you have generated the labels, combine them into a single string and set them to the asset.To assign the labels, load the asset using AssetDatabase.LoadAssetAtPath, then assign its labels with AssetDatabase.SetLabels.Remember, it’s important to only set labels if they have actually changed. Setting labels will trigger a reimport of the asset, so you don’t want this to happen unless it’s strictly necessary.If you check this, then the reimport won’t be an issue: Labels are set the first time you import an asset and saved in the .meta file, which means they’re also saved in your version control. A reimport will only be triggered if you rename or move your assets.With the above steps complete, all assets are automatically labeled, as in the example pictured below.Importing textures into a project usually involves tweaking the settings for each texture. Is it a regular texture? A normal map? A sprite? Is it linear or sRGB? If you want to change the settings of an asset importer, you can use the AssetPostprocessor once more.In this case, you’ll want to use the OnPreprocessTexture message, which is called right before importing a texture. This allows you to change the settings of the importer.When it comes to selecting the right settings for every texture, you need to verify what type of textures you’re working with – which is exactly why labels are key in the first step.With this information, you can write a simple TexturePreprocessor:It’s important to ensure that you only run this for textures that have the art label. You’ll then get a reference to the importer so that you can set everything up – starting with the texture size.The AssetPostprocessor has a context property from which you can determine the target platform. As such, you can complete platform-specific changes, like setting the textures to a lower resolution for mobile:Next, check the label to see if the texture is a UI texture, and set it accordingly:For the rest of the textures, set the values to a default. It’s worth noting that Albedo is the only texture that will have sRGB enabled:Thanks to the above script, when you drag and drop the new textures into the Editor, they will automatically have the right settings in place.“Channel packing” refers to the combination of diverse textures into one by using the different channels. It is common and offers many advantages. For instance, the value of the Red channel is metallic and the value of the Green channel is its smoothness.However, combining all textures into one requires some extra work from the art team. If the packing needs to change for some reason, the art team will have to redo all the textures that are used with that shader.As you can see, there’s room for improvement here. The approach that I like to use for channel packing is to create a special asset type where you set the “raw” textures and generate a channel-packed texture to use in your materials.First, I create a dummy file with a specific extension and then use a Scripted Importer that does all the heavy lifting when importing that asset. This is how it works:The importers can have parameters, such as the textures you need to combine.From the importer, you can set the textures as a dependency, which allows the dummy asset to be reimported every time one of the source textures changes. This lets you rebuild the generated textures accordingly.The importer has a version. If you need to change the way that textures are packed, you can modify the importer and bump the version. This will force a regeneration of all the packed textures in your project and everything will be packed in the new way, immediately.A nice side effect of generating things in an importer is that the generated assets only live in the Library folder, so it doesn’t fill up your version control.To implement this, create a ScriptableObject that will hold the created textures and serve as the result of the importer. In the example, I called this class TexturePack.With this created, you can begin by declaring the importer class and adding the ScriptedImporterAttribute to define the version and extension associated with the importer:In the importer, declare the fields you want to use. They will appear in the Inspector, just as MonoBehaviours and ScriptableObjects do:With the parameters ready, create new textures from the ones you have set as parameters. Note, however, that in the Preprocessor, we set isReadable to True to do this.In this prototype, you’ll notice two textures: the Albedo, which has the Albedo in the RGB and a mask for applying the player color in the Alpha, and the Mask texture, which includes the metallic in the Red channel and the smoothness in the Green channel.While this is perhaps outside the scope of this article, let’s look at how to combine the Albedo and the player mask as an example. First, check to see if the textures are set, and if they are, get their color data. Then set the textures as dependencies using AssetImportContext.DependsOnArtifact. As mentioned above, this will force the object to be recalculated if any of the textures end up changing.You also need to create a new texture. To do this, get the size from the TexturePreprocessor that you created in the previous section so that it follows the preset restrictions:Next, fill in all the data for the new texture. This could be massively optimized by using Jobs and Burst. Here we’ll use a simple loop:Set this data in the texture:Now, you can create the method for generating another texture in a very similar way. Once this is ready, create the main body of the importer. In this case, we’ll only create the ScriptableObject that holds the results, creates the textures, and sets the result of the importer through the AssetImportContext.When you write an importer, all of the assets generated must be registered using AssetImportContext.AddObjectToAsset so that they appear in the project window. Select a main asset using AssetImportContext.SetMainObject. This is what it looks like:The only thing left to do is to create the dummy assets. As these are custom, you can’t use the CreateAssetMenuattribute. You must make them manually instead.Using the MenuItem attribute, specify the full path to the create the asset menu, Assets/Create. To create the asset, use ProjectWindowUtil.CreateAssetWithContent, which generates a file with the content you’ve specified and allows the user to input a name for it. It looks like this:Finally, create the channel-packed textures.Most projects use custom shaders. Sometimes they’re used to add extra effects, like a dissolve effect to fade out defeated enemies, and other times, the shaders implement a custom art style, like toon shaders. Whatever the use case, Unity will create new materials with the default shader, and you will need to change it to use the custom shader.In this example, the shader used for units has two added features: the dissolve effect and the player color. When implementing these in your project, you must ensure that all the buildings and units use the appropriate shader.To validate that an asset matches certain requirements – in this case, that it uses the right shader – there is another useful class: the AssetModificationProcessor. With AssetModificationProcessor.OnWillSaveAssets, in particular, you’ll be notified when Unity is about to write an asset to disk. This will give you the opportunity to check if the asset is correct and fix it before it’s saved.Additionally, you can “tell” Unity not to save the asset, which is effective for when the problem you detect cannot be fixed automatically. To accomplish this, create the OnWillSaveAssets method:To process the assets, check whether they are materials and if they have the right labels. If they match the code below, then you have the correct shader:What’s convenient here is that this code is also called when the asset is created, meaning the new material will have the correct shader.As a new feature in Unity 2022, we also have Material Variants. Material Variants are incredibly useful when creating materials for units. In fact, you can create a base material and derive the materials for each unit from there – overriding the relevant fieldsand inheriting the rest of the properties. This allows for solid defaults for our materials, which can be updated as needed.Importing animations is similar to importing textures. There are various settings that need to be established, and some of them can be automated.Unity imports the materials of all the FBXfiles by default. For animations, the materials you want to use will either be in the project or in the FBX of the mesh. The extra materials from the animation FBX appear every time you search for materials in the project, adding quite a bit of noise, so it’s worth disabling them.To set up the rig – that is, choosing between Humanoid and Generic, and in cases where we are using a carefully setup avatar, assigning it – apply the same approach that was applied to textures. But for animations, the message you’ll use is AssetPostprocessor.OnPreprocessModel. This will be called for all FBX files, so you need to discern animation FBX files from model FBX files.Thanks to the labels you set up earlier, this shouldn’t be too complicated. The method starts much like the one for textures:Next up, you’ll want to use the rig from the mesh FBX, so you need to find that asset. To locate the asset, use the labels once more. In the case of this prototype, animations have labels that end with “animation,” whereas meshes have labels that end with “model.” You can complete a simple replacement to get the label for your model. Once you have the label, find your asset using AssetDatabase.FindAssets with “l:label-name.”When accessing other assets, there’s something else to consider: It’s possible that, in the middle of the import process, the avatar has not yet been imported when this method is called. If this occurs, the LoadAssetAtPath will return null and you won’t be able to set the avatar. To work around this issue, set a dependency to the path of the avatar. The animation will be imported again once the avatar is imported, and you will be able to set it there.Putting all of this into code will look something like this:Now you can drag the animations into the right folder, and if your mesh is ready, each one will be set up automatically. But if there isn’t an avatar available when you import the animations, the project won’t be able to pick it up once it’s created. Instead, you’ll need to reimport the animation manually after creating it. This can be done by right-clicking the folder with the animations and selecting Reimport.You can see all of this in the sample video below.Using exactly the same ideas from the previous sections, you’ll want to set up the models you are going to use. In this case, employ AssetPostrocessor.OnPreprocessModel to set the importer settings for this model.For the prototype, I’ve set the importer to not generate materialsand checked whether the model is a unit or a building. The units are set to generate an avatar, but the avatar creation for the buildings is disabled, as the buildings aren’t animated.For your project, you might want to set the materials and animatorswhen importing the model. This way, the Prefab generated by the importer is ready for immediate use.To do this, use the AssetPostprocessor.OnPostprocessModel method. This method is called after a model is finished importing. It receives the Prefab that has been generated as a parameter, which lets us modify the Prefab however we want.For the prototype, I found the material and Animation Controller by matching the label, just as I located the avatar for the animations. With the Renderer and Animator in the Prefab, I set the material and the controller as in normal gameplay.You can then drop the model into your project and it will be ready to drop into any scene. Except we haven’t set any gameplay-related components, which I’ll address in the second part of this blog.With these advanced scripting tips, you’re just about game ready. Stay tuned for the next installment in this two-part Tech from the Trenches article, which will cover hacks for balancing game data and more.If you would like to discuss the article, or share your ideas after reading it, head on over to our Scripting forum. You can also connect with me on Twitter at @CaballolD. #advanced #editor #scripting #hacks #save
    UNITY.COM
    Advanced Editor scripting hacks to save you time, part 1
    On most of the projects I’ve seen, there are a lot of tasks developers go through that are repetitive and error-prone, especially when it comes to integrating new art assets. For instance, setting up a character often involves dragging and dropping many asset references, checking checkboxes, and clicking buttons: Set the rig of the model to Humanoid, disable the sRGB of the SDF texture, set the normal maps as normal maps, and the UI textures as sprites. In other words, valuable time is spent and crucial steps can still be missed.In this two-part article, I’ll walk you through hacks that can help improve this workflow so that your next project runs smoother than your last. To further illustrate this, I’ve created a simple prototype – similar to an RTS – where the units of one team automatically attack enemy buildings and other units. With each scripting hack, I’ll improve one aspect of this process, whether that be the textures or models.Here’s what the prototype looks like:The main reason developers have to set up so many small details when importing assets is simple: Unity doesn’t know how you are going to use an asset, so it can’t know what the best settings for it are. If you want to automate some of these tasks, this is the first problem that needs to be addressed.The simplest way to find out what an asset is for and how it relates to others is by sticking to a specific naming convention and folder structure, such as:Naming convention: We can append things to the name of the asset itself, therefore Shield_BC.png is the base color while Shield_N.png is the normal map.Folder structure: Knight/Animations/Walk.fbx is clearly an animation, while Knight/Models/Knight.fbx is a model, even though they both share the same format (.fbx).The issue with this is that it only works well in one direction. So while you might already know what an asset is for when given its path, you can’t deduce its path if only given information on what the asset does. Being able to find an asset – for example, the material for a character – is useful when trying to automate the setup for some aspects of the assets. While this can be solved by using a rigid naming convention to ensure that the path is easy to deduce, it’s still susceptible to error. Even if you remember the convention, typos are common.An interesting approach to solve this is by using labels. You can use an Editor script that parses the paths of assets and assigns them labels accordingly. As the labels are automated, it’s possible to figure out the exact label that an asset will have. You can even look up assets by their label using AssetDatabase.FindAssets.If you want to automate this sequence, there is a class that can be very handy called the AssetPostprocessor. The AssetPostprocessor receives various messages when Unity imports assets. One of those is OnPostprocessAllAssets, a method that’s called whenever Unity finishes importing assets. It will give you all the paths to the imported assets, providing an opportunity to process those paths. You can write a simple method, like the following, to process them:In the case of the prototype, let’s focus on the list of imported assets – both to try and catch new assets, as well as moved assets. After all, as the path changes, we might want to update the labels.To create the labels, parse the path and look for relevant folders, prefixes, and suffixes of the name, as well as the extensions. Once you have generated the labels, combine them into a single string and set them to the asset.To assign the labels, load the asset using AssetDatabase.LoadAssetAtPath, then assign its labels with AssetDatabase.SetLabels.Remember, it’s important to only set labels if they have actually changed. Setting labels will trigger a reimport of the asset, so you don’t want this to happen unless it’s strictly necessary.If you check this, then the reimport won’t be an issue: Labels are set the first time you import an asset and saved in the .meta file, which means they’re also saved in your version control. A reimport will only be triggered if you rename or move your assets.With the above steps complete, all assets are automatically labeled, as in the example pictured below.Importing textures into a project usually involves tweaking the settings for each texture. Is it a regular texture? A normal map? A sprite? Is it linear or sRGB? If you want to change the settings of an asset importer, you can use the AssetPostprocessor once more.In this case, you’ll want to use the OnPreprocessTexture message, which is called right before importing a texture. This allows you to change the settings of the importer.When it comes to selecting the right settings for every texture, you need to verify what type of textures you’re working with – which is exactly why labels are key in the first step.With this information, you can write a simple TexturePreprocessor:It’s important to ensure that you only run this for textures that have the art label (our own textures). You’ll then get a reference to the importer so that you can set everything up – starting with the texture size.The AssetPostprocessor has a context property from which you can determine the target platform. As such, you can complete platform-specific changes, like setting the textures to a lower resolution for mobile:Next, check the label to see if the texture is a UI texture, and set it accordingly:For the rest of the textures, set the values to a default. It’s worth noting that Albedo is the only texture that will have sRGB enabled:Thanks to the above script, when you drag and drop the new textures into the Editor, they will automatically have the right settings in place.“Channel packing” refers to the combination of diverse textures into one by using the different channels. It is common and offers many advantages. For instance, the value of the Red channel is metallic and the value of the Green channel is its smoothness.However, combining all textures into one requires some extra work from the art team. If the packing needs to change for some reason (i.e., a change in the shader), the art team will have to redo all the textures that are used with that shader.As you can see, there’s room for improvement here. The approach that I like to use for channel packing is to create a special asset type where you set the “raw” textures and generate a channel-packed texture to use in your materials.First, I create a dummy file with a specific extension and then use a Scripted Importer that does all the heavy lifting when importing that asset. This is how it works:The importers can have parameters, such as the textures you need to combine.From the importer, you can set the textures as a dependency, which allows the dummy asset to be reimported every time one of the source textures changes. This lets you rebuild the generated textures accordingly.The importer has a version. If you need to change the way that textures are packed, you can modify the importer and bump the version. This will force a regeneration of all the packed textures in your project and everything will be packed in the new way, immediately.A nice side effect of generating things in an importer is that the generated assets only live in the Library folder, so it doesn’t fill up your version control.To implement this, create a ScriptableObject that will hold the created textures and serve as the result of the importer. In the example, I called this class TexturePack.With this created, you can begin by declaring the importer class and adding the ScriptedImporterAttribute to define the version and extension associated with the importer:In the importer, declare the fields you want to use. They will appear in the Inspector, just as MonoBehaviours and ScriptableObjects do:With the parameters ready, create new textures from the ones you have set as parameters. Note, however, that in the Preprocessor (from the previous section), we set isReadable to True to do this.In this prototype, you’ll notice two textures: the Albedo, which has the Albedo in the RGB and a mask for applying the player color in the Alpha, and the Mask texture, which includes the metallic in the Red channel and the smoothness in the Green channel.While this is perhaps outside the scope of this article, let’s look at how to combine the Albedo and the player mask as an example. First, check to see if the textures are set, and if they are, get their color data. Then set the textures as dependencies using AssetImportContext.DependsOnArtifact. As mentioned above, this will force the object to be recalculated if any of the textures end up changing.You also need to create a new texture. To do this, get the size from the TexturePreprocessor that you created in the previous section so that it follows the preset restrictions:Next, fill in all the data for the new texture. This could be massively optimized by using Jobs and Burst (but that would require an entire article on its own). Here we’ll use a simple loop:Set this data in the texture:Now, you can create the method for generating another texture in a very similar way. Once this is ready, create the main body of the importer. In this case, we’ll only create the ScriptableObject that holds the results, creates the textures, and sets the result of the importer through the AssetImportContext.When you write an importer, all of the assets generated must be registered using AssetImportContext.AddObjectToAsset so that they appear in the project window. Select a main asset using AssetImportContext.SetMainObject. This is what it looks like:The only thing left to do is to create the dummy assets. As these are custom, you can’t use the CreateAssetMenuattribute. You must make them manually instead.Using the MenuItem attribute, specify the full path to the create the asset menu, Assets/Create. To create the asset, use ProjectWindowUtil.CreateAssetWithContent, which generates a file with the content you’ve specified and allows the user to input a name for it. It looks like this:Finally, create the channel-packed textures.Most projects use custom shaders. Sometimes they’re used to add extra effects, like a dissolve effect to fade out defeated enemies, and other times, the shaders implement a custom art style, like toon shaders. Whatever the use case, Unity will create new materials with the default shader, and you will need to change it to use the custom shader.In this example, the shader used for units has two added features: the dissolve effect and the player color (red and blue in the video prototype). When implementing these in your project, you must ensure that all the buildings and units use the appropriate shader.To validate that an asset matches certain requirements – in this case, that it uses the right shader – there is another useful class: the AssetModificationProcessor. With AssetModificationProcessor.OnWillSaveAssets, in particular, you’ll be notified when Unity is about to write an asset to disk. This will give you the opportunity to check if the asset is correct and fix it before it’s saved.Additionally, you can “tell” Unity not to save the asset, which is effective for when the problem you detect cannot be fixed automatically. To accomplish this, create the OnWillSaveAssets method:To process the assets, check whether they are materials and if they have the right labels. If they match the code below, then you have the correct shader:What’s convenient here is that this code is also called when the asset is created, meaning the new material will have the correct shader.As a new feature in Unity 2022, we also have Material Variants. Material Variants are incredibly useful when creating materials for units. In fact, you can create a base material and derive the materials for each unit from there – overriding the relevant fields (like the textures) and inheriting the rest of the properties. This allows for solid defaults for our materials, which can be updated as needed.Importing animations is similar to importing textures. There are various settings that need to be established, and some of them can be automated.Unity imports the materials of all the FBX (.fbx) files by default. For animations, the materials you want to use will either be in the project or in the FBX of the mesh. The extra materials from the animation FBX appear every time you search for materials in the project, adding quite a bit of noise, so it’s worth disabling them.To set up the rig – that is, choosing between Humanoid and Generic, and in cases where we are using a carefully setup avatar, assigning it – apply the same approach that was applied to textures. But for animations, the message you’ll use is AssetPostprocessor.OnPreprocessModel. This will be called for all FBX files, so you need to discern animation FBX files from model FBX files.Thanks to the labels you set up earlier, this shouldn’t be too complicated. The method starts much like the one for textures:Next up, you’ll want to use the rig from the mesh FBX, so you need to find that asset. To locate the asset, use the labels once more. In the case of this prototype, animations have labels that end with “animation,” whereas meshes have labels that end with “model.” You can complete a simple replacement to get the label for your model. Once you have the label, find your asset using AssetDatabase.FindAssets with “l:label-name.”When accessing other assets, there’s something else to consider: It’s possible that, in the middle of the import process, the avatar has not yet been imported when this method is called. If this occurs, the LoadAssetAtPath will return null and you won’t be able to set the avatar. To work around this issue, set a dependency to the path of the avatar. The animation will be imported again once the avatar is imported, and you will be able to set it there.Putting all of this into code will look something like this:Now you can drag the animations into the right folder, and if your mesh is ready, each one will be set up automatically. But if there isn’t an avatar available when you import the animations, the project won’t be able to pick it up once it’s created. Instead, you’ll need to reimport the animation manually after creating it. This can be done by right-clicking the folder with the animations and selecting Reimport.You can see all of this in the sample video below.Using exactly the same ideas from the previous sections, you’ll want to set up the models you are going to use. In this case, employ AssetPostrocessor.OnPreprocessModel to set the importer settings for this model.For the prototype, I’ve set the importer to not generate materials (I will use the ones I’ve created in the project) and checked whether the model is a unit or a building (by verifying the label, as always). The units are set to generate an avatar, but the avatar creation for the buildings is disabled, as the buildings aren’t animated.For your project, you might want to set the materials and animators (and anything else you want to add) when importing the model. This way, the Prefab generated by the importer is ready for immediate use.To do this, use the AssetPostprocessor.OnPostprocessModel method. This method is called after a model is finished importing. It receives the Prefab that has been generated as a parameter, which lets us modify the Prefab however we want.For the prototype, I found the material and Animation Controller by matching the label, just as I located the avatar for the animations. With the Renderer and Animator in the Prefab, I set the material and the controller as in normal gameplay.You can then drop the model into your project and it will be ready to drop into any scene. Except we haven’t set any gameplay-related components, which I’ll address in the second part of this blog.With these advanced scripting tips, you’re just about game ready. Stay tuned for the next installment in this two-part Tech from the Trenches article, which will cover hacks for balancing game data and more.If you would like to discuss the article, or share your ideas after reading it, head on over to our Scripting forum. You can also connect with me on Twitter at @CaballolD.
    0 Reacties 0 aandelen
  • Addressables: Planning and best practices

    Games today are bigger than ever. As they continue to explore the limits of modern device hardware, it becomes increasingly critical for developers to manage content efficiently at runtime. And, as publishers look to optimize their games’ retention and monetization metrics, a small game client and dynamic over-the-air content updates have become baseline requirements for many successful games.Unity provides an end-to-end pipeline to help developers and publishers succeed in today’s gaming marketplace. That pipeline starts and ends with Addressables, a Unity package that launched in 2019 and now powers thousands of successful live games and tens of thousands more in development.The Addressables package provides a user interfaceand API for organizing Unity assets to be built into AssetBundles and loaded and unloaded dynamically at runtime. Whether AssetBundles are shipped with your base game or hosted and delivered from a remote content delivery networklike Cloud Content Delivery, Addressables helps you load the assets you need, only when you need them.While the Addressables system can simplify many aspects of content management, it’s not a “set it and forget it” feature. The choices you make about how to organize, build, load, and unload addressable assets have significant implications for your game’s size and performance.This guide explores some of the most important factors to consider so that you can get the most out of the Addressables system. At the end of this blog, you’ll find helpful “cheat sheets” that provide general settings and strategy recommendations based on common Addressables use cases.Of course, the best strategy will depend on the game you’re building and your goals. Treat this guide as a reference to be used together with Unity Learn materials, Unity Manual documentation, and the community-driven forum for Addressables.At its core, Addressables is a tool for building and working with AssetBundles. Before diving into the Addressables UI and API, it’s important to get familiar with the AssetBundles archive file format and some of the runtime implications.You can think of AssetBundles as containers – they are archive files built for your target platforms that can contain assets like models, textures, prefabs, ScriptableObjects, audio clips, and even entire scenes that Unity can load at runtime.A key feature of AssetBundles is that they can express dependencies between one another. For example, AssetBundle 1 might contain a prefab that depends on a texture in AssetBundle 2. When you use Addressables to load the prefab at runtime, the Addressables system will automatically load AssetBundle 2 and the dependent texture into memory. And, if AssetBundle 1 has another asset that depends on an asset in AssetBundle 3, AssetBundle 3 will also be loaded into memory, and so on.When your game is running, the Addressables system tracks active references for all assets – including dependent assets like the texture discussed above – to determine which ones need to be in memory. An asset loaded from an AssetBundle cannot be released from memory until both its reference count and all other asset reference counts in the same AssetBundle are at 0. The AssetBundle itself can be released from memory only when all asset reference counts in the AssetBundle are at 0.Keeping in mind this tight relationship between Addressables and AssetBundles, the most important rule when organizing your Addressables content is to create AssetBundles that contain discrete sets of assets that you expect to be loaded and unloaded together.The most important decision you’ll likely make while using Addressables is how to organize your assets into Addressables groups. Here are a few questions to consider:Should you create many small groups or a smaller number of large groups?For each group, how many AssetBundles should you aim to generate?Should you use labels?Should you give your groups local or remote load paths?While we would love to give a single answer, the best Addressables grouping strategy will depend on several factors that are specific to your game.Remember: Addressables groups provide the organizational structure for your addressable assets that determines how those assets will be built into AssetBundles. So the best organizational strategy will be the one that packs, loads, and unloads your AssetBundles most effectively based on your game’s unique structure, goals, and limitations.Before you start organizing your Addressables content, make sure you have a solid grasp on the following:1. Your game’s structure and roadmap2. Your game’s platform strengths and limitations3. Your primary goalin using Addressables to optimize your game’s performanceWe’ll tackle each of these factors below.The first factor to consider is your game’s structure and roadmap.By “structure,” we mean the actual architecture of your game. Is your game a linear, single-player journey where the player will progress through a predictable set of levels or environments? Is it a multiplatform PvP game with thousands of vanity items that could be instantiated at unpredictable times? Your game’s structure will determine when you will need to have assets loaded and ready to use, and when you’ll be able to unload assets and AssetBundles from memory.Remember, try to create AssetBundles that contain only the assets that need to be loaded together and can be unloaded together. If your game is a linear journey with distinct break points, consider organizing Addressables groups into larger subsets of content associated with each section of your game. That way, those assets can be loaded and unloaded together.If your game is non-linear and more unpredictable, opt for smaller groups that will generate smaller AssetBundles, allowing you to load and unload more dynamically. Always aim to use logical and meaningful names for your groups to help you quickly locate assets and optimize your layout.“Roadmap” refers to how your game will evolve over time. Once your game ships to players, will it remain mostly unchanged aside from occasional bug fixes or game balance patches? Or do you expect to add new content on a regular basis without requiring your players to install a large client update?Your content roadmap helps inform your grouping strategy. If your game’s content will be self-contained and not updated after launch, focus your grouping strategy around the structural considerations discussed above. If your game will require frequent content updates, group your content in a way that will allow players to download exactly what they need, when they need it.Consider using labels to help identify content from distinct bundles that will be needed together at runtime, such as a set of cosmetic items that will grow over time as your game matures. You can also use the “Pack Together By Label” Bundle Mode in your Groups Settings to subdivide content you’ve logically grouped together.For example, perhaps you plan to launch a new “Halloween 2023” event with some cosmetic items for players to collect. Your “Halloween 2023 Outfits” group might contain assets with the labels “Hats,” “Shoes,” and “Masks.” You could then add a “Halloween 2023” label to all the assets in this group. Using the “Pack Together By Label” Bundle Mode for this group will create three AssetBundles at build time.At runtime, you could then load all addressable assets with the Label “Hats” in your character customization screen to ensure all assets with that label are downloaded, loaded into memory, and ready for players to view. Or you could load all addressable assets with the label “Halloween 2023” on your promotional page for your event, ensuring they are ready to be displayed to your players.Having a deep understanding of your game’s structure and roadmap will help you make informed decisions about your content organization that will be beneficial throughout your game’s lifecycle.Next, we’ll tackle your platforms’ specific strengths and limitations and what they mean for your content strategy.The next factor to consider is the strengths and limitations of the platforms you’re targeting for distribution. In this section, we’ve outlined common platform targets for Addressables users, as well as some key considerations for each.Mobile and VRFor mobile and VR platforms, the most important considerations to keep in mind are app size, bundled content size, and download speeds.For your groups, consider the sets of content that your players will need immediately after install. Ensure this content is organized into groups with local load paths so that it will be included with your base game. Organize all other content into groups with remote load paths so that you can deliver this content over the air to your players.Opt for a group strategy that will build relatively small AssetBundles. The exact balance will depend on your game. Avoid extremely large bundles that will consume a substantial amount of memory and will be difficult to release once loaded. Similarly, avoid a huge number of tiny bundles that may create a very large Addressables catalog file that will be downloaded for every content update. Many tiny bundles can also have an impact on the speed at which your players can download the content they need, so be mindful of these pros and cons when determining the right balance for your game.Desktop and ConsolesFor desktop and consoles, the most important consideration is performance. Compared to mobile devices and wireless VR hardware, desktop and console hardware typically has fewer constraints around memory and disk storage. With this in mind, consider a group setting that will build uncompressed AssetBundles. This will provide the fastest possible loading time and can even provide for efficient patching on certain platforms.When developing for consoles specifically, pay close attention to any platform-specific caching restrictions that may apply. While mobile platforms allow you to take advantage of Unity’s AssetBundle Cache for downloaded content, this functionality is disabled by default at the Unity engine level for certain consoles and WebGL. Consider updating your base game with the new content on those platforms rather than attempting to deliver remote content over the air. Otherwise, you will need to create your own custom AssetBundle caching system and determine whether your solution complies with those platforms’ terms of service.After evaluating the strengths and limitations of your target platforms, identify one or two primary goals you’re trying to achieve by using the Addressables system. For example: Are you mainly aiming to reduce your base game’s size, or are you planning to deliver over-the-air content updates to players? To demonstrate, let’s discuss these options, and more, in detail below.Minimizing base game sizeIf your primary goal is to minimize your base game’s size, and you aren’t as concerned about memory limitations or large downloads after install, then your primary focus should be migrating as many assets as possible from scenes and Resources into one or more Addressables groups with remote load paths.Consider making the scenes in your project addressable and determine which, if any, must be included with the main player build. For those that can be delivered to players after install, include those scenes in groups with remote load paths. You can even build a player with one almost-empty scene, and load the rest of your game dynamically from there, as explained in this Open Projects Devlog video.If you make any scenes addressable, it’s best to make all of them addressable to reduce the chance and volume of unnecessary asset duplication.For groups that will generate AssetBundles to be hosted remotely, be sure to enable the AssetBundle Cache. This setting will ensure that downloaded AssetBundles will be cached on your players’ devices, preventing them from having to redownload each session.While it’s always good to keep in mind the runtime implications of many small bundles versus few large bundles, these considerations become more relevant when considering other goals you may have.Efficiently delivering remote content to playersIf your primary goal is the efficient delivery of remote content, your group structure should reflect how you aim to split content between “local”and “remote” content. Again, be sure to enable the AssetBundle Cache to cache downloaded content on players’ devices.The size, number, and Bundle Mode of these groups will depend on when you expect to deliver remote content to your players and how long you’re willing to let them wait for downloads to complete. For example, if your game’s structure will allow for delivery of all remote content shortly after they install the base game, you can opt for larger groups with Pack Together or Pack Together By Label, which will result in a small number of large downloads.If you expect to deliver smaller sets of remote content to players throughout their sessions that will be less disruptive to the experience, you can opt for smaller groups and/or a Bundle Mode setting that will generate smaller AssetBundles that will download much more quickly.In most cases, for groups containing remote content, consider Enabled, Excluding Cached for your AssetBundle Cyclic Redundancy Checkoption. This will provide additional assurances of your remote content’s integrity as it’s being cached to players’ devices, while avoiding the additional overhead of performing a CRC for loading content that’s already on player devices.Optimizing runtime memory usage and performanceIf your primary goal is optimizing the game’s runtime performance and memory usage, remember the most important rule of Addressables groups organization: Assets that you plan to load and unload at the same time should be grouped together.Generally speaking, this will mean creating smaller AssetBundles. You can achieve this in several ways, including creating smaller groups and/or avoiding the “Pack Together” Bundle Mode in your Group Settings for large groups that contain assets that won’t always be needed at the same time in your game.You should also keep an eye on runtime performance to help you spot potential issues or areas of optimization. Take advantage of official Unity tools like the Unity Profiler, the Memory Profiler package, or the Addressables Event Viewer, which can all help optimize your game’s performance.Be on the lookout for the upcoming Addressables Profiler Module, which will replace the Addressables Event Viewer. This new tool will provide even more in-depth information about how your code is loading and unloading addressable assets and AssetBundles, including detailed information about dependencies among your assets and AssetBundles.Multiple goalsOf course, most projects will have a number of goals associated with Addressables. In this case, there is truly no one-size-fits-all approach. You will need to evaluate the tradeoffs outlined above and find the group structure and settings that will best achieve the success you’ve defined.We recommend that you take advantage of the Addressables Build Report and the Addressables Profiler Module, available soon in Addressables 1.21.3. The Addressables Build Report will provide you with detailed information about the AssetBundles that were generated from your Addressables builds, including file size, potential duplicates, and in-depth dependency information. The Addressables Profiler Module is a new runtime analysis tool that takes advantage of this new dependency data, providing precise information about what was loaded by your Addressables code and why it was loaded.Below we’ve provided some handy “cheat sheets” for our recommended Addressables settings and strategies based on some of the most common use cases. Of course, these are just suggestions – it’s up to you to determine whether a suggestion aligns with your project’s unique structure and your specific goals.A mobile game with frequent content updatesA standalone, self-contained desktop or console gameA VR game built for Meta Quest 2If you have questions or want to learn more about the Addressables package, visit us in the Addressables forum. You can also connect with me directly on Twitter at @Unity_Jeff. Be sure to watch for new technical blogs from other Unity developers as part of the ongoing Tech from the Trenches series.
    #addressables #planning #best #practices
    Addressables: Planning and best practices
    Games today are bigger than ever. As they continue to explore the limits of modern device hardware, it becomes increasingly critical for developers to manage content efficiently at runtime. And, as publishers look to optimize their games’ retention and monetization metrics, a small game client and dynamic over-the-air content updates have become baseline requirements for many successful games.Unity provides an end-to-end pipeline to help developers and publishers succeed in today’s gaming marketplace. That pipeline starts and ends with Addressables, a Unity package that launched in 2019 and now powers thousands of successful live games and tens of thousands more in development.The Addressables package provides a user interfaceand API for organizing Unity assets to be built into AssetBundles and loaded and unloaded dynamically at runtime. Whether AssetBundles are shipped with your base game or hosted and delivered from a remote content delivery networklike Cloud Content Delivery, Addressables helps you load the assets you need, only when you need them.While the Addressables system can simplify many aspects of content management, it’s not a “set it and forget it” feature. The choices you make about how to organize, build, load, and unload addressable assets have significant implications for your game’s size and performance.This guide explores some of the most important factors to consider so that you can get the most out of the Addressables system. At the end of this blog, you’ll find helpful “cheat sheets” that provide general settings and strategy recommendations based on common Addressables use cases.Of course, the best strategy will depend on the game you’re building and your goals. Treat this guide as a reference to be used together with Unity Learn materials, Unity Manual documentation, and the community-driven forum for Addressables.At its core, Addressables is a tool for building and working with AssetBundles. Before diving into the Addressables UI and API, it’s important to get familiar with the AssetBundles archive file format and some of the runtime implications.You can think of AssetBundles as containers – they are archive files built for your target platforms that can contain assets like models, textures, prefabs, ScriptableObjects, audio clips, and even entire scenes that Unity can load at runtime.A key feature of AssetBundles is that they can express dependencies between one another. For example, AssetBundle 1 might contain a prefab that depends on a texture in AssetBundle 2. When you use Addressables to load the prefab at runtime, the Addressables system will automatically load AssetBundle 2 and the dependent texture into memory. And, if AssetBundle 1 has another asset that depends on an asset in AssetBundle 3, AssetBundle 3 will also be loaded into memory, and so on.When your game is running, the Addressables system tracks active references for all assets – including dependent assets like the texture discussed above – to determine which ones need to be in memory. An asset loaded from an AssetBundle cannot be released from memory until both its reference count and all other asset reference counts in the same AssetBundle are at 0. The AssetBundle itself can be released from memory only when all asset reference counts in the AssetBundle are at 0.Keeping in mind this tight relationship between Addressables and AssetBundles, the most important rule when organizing your Addressables content is to create AssetBundles that contain discrete sets of assets that you expect to be loaded and unloaded together.The most important decision you’ll likely make while using Addressables is how to organize your assets into Addressables groups. Here are a few questions to consider:Should you create many small groups or a smaller number of large groups?For each group, how many AssetBundles should you aim to generate?Should you use labels?Should you give your groups local or remote load paths?While we would love to give a single answer, the best Addressables grouping strategy will depend on several factors that are specific to your game.Remember: Addressables groups provide the organizational structure for your addressable assets that determines how those assets will be built into AssetBundles. So the best organizational strategy will be the one that packs, loads, and unloads your AssetBundles most effectively based on your game’s unique structure, goals, and limitations.Before you start organizing your Addressables content, make sure you have a solid grasp on the following:1. Your game’s structure and roadmap2. Your game’s platform strengths and limitations3. Your primary goalin using Addressables to optimize your game’s performanceWe’ll tackle each of these factors below.The first factor to consider is your game’s structure and roadmap.By “structure,” we mean the actual architecture of your game. Is your game a linear, single-player journey where the player will progress through a predictable set of levels or environments? Is it a multiplatform PvP game with thousands of vanity items that could be instantiated at unpredictable times? Your game’s structure will determine when you will need to have assets loaded and ready to use, and when you’ll be able to unload assets and AssetBundles from memory.Remember, try to create AssetBundles that contain only the assets that need to be loaded together and can be unloaded together. If your game is a linear journey with distinct break points, consider organizing Addressables groups into larger subsets of content associated with each section of your game. That way, those assets can be loaded and unloaded together.If your game is non-linear and more unpredictable, opt for smaller groups that will generate smaller AssetBundles, allowing you to load and unload more dynamically. Always aim to use logical and meaningful names for your groups to help you quickly locate assets and optimize your layout.“Roadmap” refers to how your game will evolve over time. Once your game ships to players, will it remain mostly unchanged aside from occasional bug fixes or game balance patches? Or do you expect to add new content on a regular basis without requiring your players to install a large client update?Your content roadmap helps inform your grouping strategy. If your game’s content will be self-contained and not updated after launch, focus your grouping strategy around the structural considerations discussed above. If your game will require frequent content updates, group your content in a way that will allow players to download exactly what they need, when they need it.Consider using labels to help identify content from distinct bundles that will be needed together at runtime, such as a set of cosmetic items that will grow over time as your game matures. You can also use the “Pack Together By Label” Bundle Mode in your Groups Settings to subdivide content you’ve logically grouped together.For example, perhaps you plan to launch a new “Halloween 2023” event with some cosmetic items for players to collect. Your “Halloween 2023 Outfits” group might contain assets with the labels “Hats,” “Shoes,” and “Masks.” You could then add a “Halloween 2023” label to all the assets in this group. Using the “Pack Together By Label” Bundle Mode for this group will create three AssetBundles at build time.At runtime, you could then load all addressable assets with the Label “Hats” in your character customization screen to ensure all assets with that label are downloaded, loaded into memory, and ready for players to view. Or you could load all addressable assets with the label “Halloween 2023” on your promotional page for your event, ensuring they are ready to be displayed to your players.Having a deep understanding of your game’s structure and roadmap will help you make informed decisions about your content organization that will be beneficial throughout your game’s lifecycle.Next, we’ll tackle your platforms’ specific strengths and limitations and what they mean for your content strategy.The next factor to consider is the strengths and limitations of the platforms you’re targeting for distribution. In this section, we’ve outlined common platform targets for Addressables users, as well as some key considerations for each.Mobile and VRFor mobile and VR platforms, the most important considerations to keep in mind are app size, bundled content size, and download speeds.For your groups, consider the sets of content that your players will need immediately after install. Ensure this content is organized into groups with local load paths so that it will be included with your base game. Organize all other content into groups with remote load paths so that you can deliver this content over the air to your players.Opt for a group strategy that will build relatively small AssetBundles. The exact balance will depend on your game. Avoid extremely large bundles that will consume a substantial amount of memory and will be difficult to release once loaded. Similarly, avoid a huge number of tiny bundles that may create a very large Addressables catalog file that will be downloaded for every content update. Many tiny bundles can also have an impact on the speed at which your players can download the content they need, so be mindful of these pros and cons when determining the right balance for your game.Desktop and ConsolesFor desktop and consoles, the most important consideration is performance. Compared to mobile devices and wireless VR hardware, desktop and console hardware typically has fewer constraints around memory and disk storage. With this in mind, consider a group setting that will build uncompressed AssetBundles. This will provide the fastest possible loading time and can even provide for efficient patching on certain platforms.When developing for consoles specifically, pay close attention to any platform-specific caching restrictions that may apply. While mobile platforms allow you to take advantage of Unity’s AssetBundle Cache for downloaded content, this functionality is disabled by default at the Unity engine level for certain consoles and WebGL. Consider updating your base game with the new content on those platforms rather than attempting to deliver remote content over the air. Otherwise, you will need to create your own custom AssetBundle caching system and determine whether your solution complies with those platforms’ terms of service.After evaluating the strengths and limitations of your target platforms, identify one or two primary goals you’re trying to achieve by using the Addressables system. For example: Are you mainly aiming to reduce your base game’s size, or are you planning to deliver over-the-air content updates to players? To demonstrate, let’s discuss these options, and more, in detail below.Minimizing base game sizeIf your primary goal is to minimize your base game’s size, and you aren’t as concerned about memory limitations or large downloads after install, then your primary focus should be migrating as many assets as possible from scenes and Resources into one or more Addressables groups with remote load paths.Consider making the scenes in your project addressable and determine which, if any, must be included with the main player build. For those that can be delivered to players after install, include those scenes in groups with remote load paths. You can even build a player with one almost-empty scene, and load the rest of your game dynamically from there, as explained in this Open Projects Devlog video.If you make any scenes addressable, it’s best to make all of them addressable to reduce the chance and volume of unnecessary asset duplication.For groups that will generate AssetBundles to be hosted remotely, be sure to enable the AssetBundle Cache. This setting will ensure that downloaded AssetBundles will be cached on your players’ devices, preventing them from having to redownload each session.While it’s always good to keep in mind the runtime implications of many small bundles versus few large bundles, these considerations become more relevant when considering other goals you may have.Efficiently delivering remote content to playersIf your primary goal is the efficient delivery of remote content, your group structure should reflect how you aim to split content between “local”and “remote” content. Again, be sure to enable the AssetBundle Cache to cache downloaded content on players’ devices.The size, number, and Bundle Mode of these groups will depend on when you expect to deliver remote content to your players and how long you’re willing to let them wait for downloads to complete. For example, if your game’s structure will allow for delivery of all remote content shortly after they install the base game, you can opt for larger groups with Pack Together or Pack Together By Label, which will result in a small number of large downloads.If you expect to deliver smaller sets of remote content to players throughout their sessions that will be less disruptive to the experience, you can opt for smaller groups and/or a Bundle Mode setting that will generate smaller AssetBundles that will download much more quickly.In most cases, for groups containing remote content, consider Enabled, Excluding Cached for your AssetBundle Cyclic Redundancy Checkoption. This will provide additional assurances of your remote content’s integrity as it’s being cached to players’ devices, while avoiding the additional overhead of performing a CRC for loading content that’s already on player devices.Optimizing runtime memory usage and performanceIf your primary goal is optimizing the game’s runtime performance and memory usage, remember the most important rule of Addressables groups organization: Assets that you plan to load and unload at the same time should be grouped together.Generally speaking, this will mean creating smaller AssetBundles. You can achieve this in several ways, including creating smaller groups and/or avoiding the “Pack Together” Bundle Mode in your Group Settings for large groups that contain assets that won’t always be needed at the same time in your game.You should also keep an eye on runtime performance to help you spot potential issues or areas of optimization. Take advantage of official Unity tools like the Unity Profiler, the Memory Profiler package, or the Addressables Event Viewer, which can all help optimize your game’s performance.Be on the lookout for the upcoming Addressables Profiler Module, which will replace the Addressables Event Viewer. This new tool will provide even more in-depth information about how your code is loading and unloading addressable assets and AssetBundles, including detailed information about dependencies among your assets and AssetBundles.Multiple goalsOf course, most projects will have a number of goals associated with Addressables. In this case, there is truly no one-size-fits-all approach. You will need to evaluate the tradeoffs outlined above and find the group structure and settings that will best achieve the success you’ve defined.We recommend that you take advantage of the Addressables Build Report and the Addressables Profiler Module, available soon in Addressables 1.21.3. The Addressables Build Report will provide you with detailed information about the AssetBundles that were generated from your Addressables builds, including file size, potential duplicates, and in-depth dependency information. The Addressables Profiler Module is a new runtime analysis tool that takes advantage of this new dependency data, providing precise information about what was loaded by your Addressables code and why it was loaded.Below we’ve provided some handy “cheat sheets” for our recommended Addressables settings and strategies based on some of the most common use cases. Of course, these are just suggestions – it’s up to you to determine whether a suggestion aligns with your project’s unique structure and your specific goals.A mobile game with frequent content updatesA standalone, self-contained desktop or console gameA VR game built for Meta Quest 2If you have questions or want to learn more about the Addressables package, visit us in the Addressables forum. You can also connect with me directly on Twitter at @Unity_Jeff. Be sure to watch for new technical blogs from other Unity developers as part of the ongoing Tech from the Trenches series. #addressables #planning #best #practices
    UNITY.COM
    Addressables: Planning and best practices
    Games today are bigger than ever. As they continue to explore the limits of modern device hardware, it becomes increasingly critical for developers to manage content efficiently at runtime. And, as publishers look to optimize their games’ retention and monetization metrics, a small game client and dynamic over-the-air content updates have become baseline requirements for many successful games.Unity provides an end-to-end pipeline to help developers and publishers succeed in today’s gaming marketplace. That pipeline starts and ends with Addressables, a Unity package that launched in 2019 and now powers thousands of successful live games and tens of thousands more in development.The Addressables package provides a user interface (UI) and API for organizing Unity assets to be built into AssetBundles and loaded and unloaded dynamically at runtime. Whether AssetBundles are shipped with your base game or hosted and delivered from a remote content delivery network (CDN) like Cloud Content Delivery, Addressables helps you load the assets you need, only when you need them.While the Addressables system can simplify many aspects of content management, it’s not a “set it and forget it” feature. The choices you make about how to organize, build, load, and unload addressable assets have significant implications for your game’s size and performance.This guide explores some of the most important factors to consider so that you can get the most out of the Addressables system. At the end of this blog, you’ll find helpful “cheat sheets” that provide general settings and strategy recommendations based on common Addressables use cases.Of course, the best strategy will depend on the game you’re building and your goals. Treat this guide as a reference to be used together with Unity Learn materials, Unity Manual documentation, and the community-driven forum for Addressables.At its core, Addressables is a tool for building and working with AssetBundles. Before diving into the Addressables UI and API, it’s important to get familiar with the AssetBundles archive file format and some of the runtime implications.You can think of AssetBundles as containers – they are archive files built for your target platforms that can contain assets like models, textures, prefabs, ScriptableObjects, audio clips, and even entire scenes that Unity can load at runtime.A key feature of AssetBundles is that they can express dependencies between one another. For example, AssetBundle 1 might contain a prefab that depends on a texture in AssetBundle 2. When you use Addressables to load the prefab at runtime, the Addressables system will automatically load AssetBundle 2 and the dependent texture into memory. And, if AssetBundle 1 has another asset that depends on an asset in AssetBundle 3, AssetBundle 3 will also be loaded into memory, and so on.When your game is running, the Addressables system tracks active references for all assets – including dependent assets like the texture discussed above – to determine which ones need to be in memory. An asset loaded from an AssetBundle cannot be released from memory until both its reference count and all other asset reference counts in the same AssetBundle are at 0. The AssetBundle itself can be released from memory only when all asset reference counts in the AssetBundle are at 0.Keeping in mind this tight relationship between Addressables and AssetBundles, the most important rule when organizing your Addressables content is to create AssetBundles that contain discrete sets of assets that you expect to be loaded and unloaded together.The most important decision you’ll likely make while using Addressables is how to organize your assets into Addressables groups. Here are a few questions to consider:Should you create many small groups or a smaller number of large groups?For each group, how many AssetBundles should you aim to generate (i.e., should you pack the assets in that group together, separately, or by label)?Should you use labels?Should you give your groups local or remote load paths?While we would love to give a single answer, the best Addressables grouping strategy will depend on several factors that are specific to your game.Remember: Addressables groups provide the organizational structure for your addressable assets that determines how those assets will be built into AssetBundles. So the best organizational strategy will be the one that packs, loads, and unloads your AssetBundles most effectively based on your game’s unique structure, goals, and limitations.Before you start organizing your Addressables content, make sure you have a solid grasp on the following:1. Your game’s structure and roadmap2. Your game’s platform strengths and limitations3. Your primary goal(s) in using Addressables to optimize your game’s performanceWe’ll tackle each of these factors below.The first factor to consider is your game’s structure and roadmap.By “structure,” we mean the actual architecture of your game. Is your game a linear, single-player journey where the player will progress through a predictable set of levels or environments? Is it a multiplatform PvP game with thousands of vanity items that could be instantiated at unpredictable times? Your game’s structure will determine when you will need to have assets loaded and ready to use, and when you’ll be able to unload assets and AssetBundles from memory.Remember, try to create AssetBundles that contain only the assets that need to be loaded together and can be unloaded together. If your game is a linear journey with distinct break points, consider organizing Addressables groups into larger subsets of content associated with each section of your game. That way, those assets can be loaded and unloaded together.If your game is non-linear and more unpredictable, opt for smaller groups that will generate smaller AssetBundles, allowing you to load and unload more dynamically. Always aim to use logical and meaningful names for your groups to help you quickly locate assets and optimize your layout.“Roadmap” refers to how your game will evolve over time. Once your game ships to players, will it remain mostly unchanged aside from occasional bug fixes or game balance patches? Or do you expect to add new content on a regular basis without requiring your players to install a large client update?Your content roadmap helps inform your grouping strategy. If your game’s content will be self-contained and not updated after launch, focus your grouping strategy around the structural considerations discussed above. If your game will require frequent content updates, group your content in a way that will allow players to download exactly what they need, when they need it.Consider using labels to help identify content from distinct bundles that will be needed together at runtime, such as a set of cosmetic items that will grow over time as your game matures. You can also use the “Pack Together By Label” Bundle Mode in your Groups Settings to subdivide content you’ve logically grouped together.For example, perhaps you plan to launch a new “Halloween 2023” event with some cosmetic items for players to collect. Your “Halloween 2023 Outfits” group might contain assets with the labels “Hats,” “Shoes,” and “Masks.” You could then add a “Halloween 2023” label to all the assets in this group. Using the “Pack Together By Label” Bundle Mode for this group will create three AssetBundles at build time.At runtime, you could then load all addressable assets with the Label “Hats” in your character customization screen to ensure all assets with that label are downloaded, loaded into memory, and ready for players to view. Or you could load all addressable assets with the label “Halloween 2023” on your promotional page for your event, ensuring they are ready to be displayed to your players.Having a deep understanding of your game’s structure and roadmap will help you make informed decisions about your content organization that will be beneficial throughout your game’s lifecycle.Next, we’ll tackle your platforms’ specific strengths and limitations and what they mean for your content strategy.The next factor to consider is the strengths and limitations of the platforms you’re targeting for distribution. In this section, we’ve outlined common platform targets for Addressables users, as well as some key considerations for each.Mobile and VRFor mobile and VR platforms, the most important considerations to keep in mind are app size, bundled content size, and download speeds.For your groups, consider the sets of content that your players will need immediately after install (e.g., to be able to complete your tutorial). Ensure this content is organized into groups with local load paths so that it will be included with your base game. Organize all other content into groups with remote load paths so that you can deliver this content over the air to your players.Opt for a group strategy that will build relatively small AssetBundles. The exact balance will depend on your game. Avoid extremely large bundles that will consume a substantial amount of memory and will be difficult to release once loaded. Similarly, avoid a huge number of tiny bundles that may create a very large Addressables catalog file that will be downloaded for every content update. Many tiny bundles can also have an impact on the speed at which your players can download the content they need, so be mindful of these pros and cons when determining the right balance for your game.Desktop and ConsolesFor desktop and consoles, the most important consideration is performance. Compared to mobile devices and wireless VR hardware, desktop and console hardware typically has fewer constraints around memory and disk storage. With this in mind, consider a group setting that will build uncompressed AssetBundles. This will provide the fastest possible loading time and can even provide for efficient patching on certain platforms.When developing for consoles specifically, pay close attention to any platform-specific caching restrictions that may apply. While mobile platforms allow you to take advantage of Unity’s AssetBundle Cache for downloaded content, this functionality is disabled by default at the Unity engine level for certain consoles and WebGL. Consider updating your base game with the new content on those platforms rather than attempting to deliver remote content over the air. Otherwise, you will need to create your own custom AssetBundle caching system and determine whether your solution complies with those platforms’ terms of service.After evaluating the strengths and limitations of your target platforms, identify one or two primary goals you’re trying to achieve by using the Addressables system. For example: Are you mainly aiming to reduce your base game’s size, or are you planning to deliver over-the-air content updates to players? To demonstrate, let’s discuss these options, and more, in detail below.Minimizing base game sizeIf your primary goal is to minimize your base game’s size, and you aren’t as concerned about memory limitations or large downloads after install, then your primary focus should be migrating as many assets as possible from scenes and Resources into one or more Addressables groups with remote load paths.Consider making the scenes in your project addressable and determine which, if any, must be included with the main player build. For those that can be delivered to players after install, include those scenes in groups with remote load paths. You can even build a player with one almost-empty scene, and load the rest of your game dynamically from there, as explained in this Open Projects Devlog video.If you make any scenes addressable, it’s best to make all of them addressable to reduce the chance and volume of unnecessary asset duplication.For groups that will generate AssetBundles to be hosted remotely, be sure to enable the AssetBundle Cache. This setting will ensure that downloaded AssetBundles will be cached on your players’ devices, preventing them from having to redownload each session.While it’s always good to keep in mind the runtime implications of many small bundles versus few large bundles, these considerations become more relevant when considering other goals you may have.Efficiently delivering remote content to playersIf your primary goal is the efficient delivery of remote content, your group structure should reflect how you aim to split content between “local” (i.e., assets included with your player build) and “remote” content (i.e., assets hosted on an external content delivery network). Again, be sure to enable the AssetBundle Cache to cache downloaded content on players’ devices.The size, number, and Bundle Mode of these groups will depend on when you expect to deliver remote content to your players and how long you’re willing to let them wait for downloads to complete. For example, if your game’s structure will allow for delivery of all remote content shortly after they install the base game, you can opt for larger groups with Pack Together or Pack Together By Label, which will result in a small number of large downloads.If you expect to deliver smaller sets of remote content to players throughout their sessions that will be less disruptive to the experience, you can opt for smaller groups and/or a Bundle Mode setting that will generate smaller AssetBundles that will download much more quickly.In most cases, for groups containing remote content, consider Enabled, Excluding Cached for your AssetBundle Cyclic Redundancy Check (CRC) option. This will provide additional assurances of your remote content’s integrity as it’s being cached to players’ devices, while avoiding the additional overhead of performing a CRC for loading content that’s already on player devices.Optimizing runtime memory usage and performanceIf your primary goal is optimizing the game’s runtime performance and memory usage, remember the most important rule of Addressables groups organization: Assets that you plan to load and unload at the same time should be grouped together.Generally speaking, this will mean creating smaller AssetBundles. You can achieve this in several ways, including creating smaller groups and/or avoiding the “Pack Together” Bundle Mode in your Group Settings for large groups that contain assets that won’t always be needed at the same time in your game.You should also keep an eye on runtime performance to help you spot potential issues or areas of optimization. Take advantage of official Unity tools like the Unity Profiler, the Memory Profiler package, or the Addressables Event Viewer, which can all help optimize your game’s performance.Be on the lookout for the upcoming Addressables Profiler Module, which will replace the Addressables Event Viewer. This new tool will provide even more in-depth information about how your code is loading and unloading addressable assets and AssetBundles, including detailed information about dependencies among your assets and AssetBundles.Multiple goalsOf course, most projects will have a number of goals associated with Addressables. In this case, there is truly no one-size-fits-all approach. You will need to evaluate the tradeoffs outlined above and find the group structure and settings that will best achieve the success you’ve defined.We recommend that you take advantage of the Addressables Build Report and the Addressables Profiler Module, available soon in Addressables 1.21.3. The Addressables Build Report will provide you with detailed information about the AssetBundles that were generated from your Addressables builds, including file size, potential duplicates, and in-depth dependency information. The Addressables Profiler Module is a new runtime analysis tool that takes advantage of this new dependency data, providing precise information about what was loaded by your Addressables code and why it was loaded.Below we’ve provided some handy “cheat sheets” for our recommended Addressables settings and strategies based on some of the most common use cases. Of course, these are just suggestions – it’s up to you to determine whether a suggestion aligns with your project’s unique structure and your specific goals.A mobile game with frequent content updatesA standalone, self-contained desktop or console gameA VR game built for Meta Quest 2If you have questions or want to learn more about the Addressables package, visit us in the Addressables forum. You can also connect with me directly on Twitter at @Unity_Jeff. Be sure to watch for new technical blogs from other Unity developers as part of the ongoing Tech from the Trenches series.
    0 Reacties 0 aandelen
  • Game Dev Digest Issue #282 - Unity 6.2 Beta, Level/Character Design, and more

    Game Dev Digest Issue #282 - Unity 6.2 Beta, Level/Character Design, and more

    posted in GameDevDigest Newsletter

    Published May 16, 2025

    Advertisement

    This article was originally published on GameDevDigest.comEnjoy!Unity 6.2 Beta is now available - Test the latest features, including Unity AI, Mesh LOD, and World Space UI for UI Toolkit. Dive in today and help shape the future of Unity!discussions.unity.comSpace is not a wall: toward a less architectural level design - People want to do level design. They grow up playing games like Minecraft, Roblox, Fortnite — all 3D games with 3D worlds. And to create 3D worlds, supposedly you need this thing called “level design.” Then when you search YouTube, you'll be told that level design is about implanting secret lines that "guide the player" into walking down hallways. Such is the power of ARCHITECTURE!blog.radiator.debacle.usSound and Music in Warhammer 40,000: Rogue Trader | An Audio Director's Perspective - In this article, I will discuss the approach to sound design and music that we took in our latest game: Warhammer 40,000: Rogue Trader.audiokinetic.comCastle Kellmore rendering - Since Castle Kellmore released on Playdate, I have had a lot of interest in the technical aspects of its rendering system. So I thought I would give a brief insight into how I made it look as good as possible, whilekeeping to 50 frames per second.ligeiagames.comUnity-Advanced-Engineering-Guide - Unity Software Engineering GuideMfaXyz
    VideosDesigning and Creating Video Game Zombie AI ft. PikPok - James and Sarah from PikPokare here to share their process for designing zombie behavior and bringing them to life in Unity!UnityThe GOOD, The BAD, and The BIZARRE of Unity 6.1's XR Updates - Unity 6.1 brings major XR updates, but not all features are created equal! This breakdown reveals which VR/AR features are genuinely useful. Learn about Variable Rate Shading, the new Mixed Multiplayer Tabletop Template, and why Deferred+ rendering is great tech you'll rarely use unless you're making a PC VR experience. I also dive into Unity's strange decision to support Android XR devices that don't actually exist yet!Fist Full of ShrimpHow to Generate Random Tilemap Decorations in Unity - In this continuation of the "How to Make a 2D Platformer Game in Unity" series we'll be generating random tilemap decorations using a rule tile.Wild Cockatiel GamesDiscover the HIDDEN POWER of Unity Property Bags and Visitors - The Property bag is the cornerstone of Unity.Properties—a powerful system that lets you generically access, inspect, and modify object data at runtime without reflection. In this video, we’ll show you how property bags, visitors, and adapters work together to build flexible, high-performance systems for tooling, UI binding, data validation, and more. You’ll learn how to write your own visitors, construct property paths, and use these patterns to create runtime features that adapt to any data structure.git-amendUnderstanding shaders is easy, actually - Shader code can be scary but... Well, it is scary, but it's also quite simple!tEEvy gamezBeginner mistakes when drawing assets | 2D Game Art - If you're a beginner to game art all of this art stuff might feel a bit dauntingNonsensical 2DEnemies in Unity ECS - Fundamentals & ICleanupComponentData - Build a high-performance Enemy System in Unity using ECS and DOTS!Tale ForgeI’m a Caver Making a Cave Game with Custom Tech. It’s Complicated. - This video is a longer discussion and explanation about the tech I'm developing for my caving game.Fredrik Andersson
    AssetsLevel Up: 5K World Building Assets Bundle - Build the game of your dreams in any setting or scenario with our Level Up: 5K World Building Assets Bundle.__Character Art Tutorial Bundle - Flash Sale - Create stylized AAA characters today Say hi to summer with a scorching hot FLASH SALE! Learn how to create original AAA-quality characters from the pros at FastTrackTutorials. Build warriors, ninjas, and more with a suite of lesson videos. Pay what you want and help support One Tree Planted with your purchase.Humble Bundle AffiliateThe-Fluid-Toy - An Opensource, GPU-Accelerated, Particle-Based, Multi-phase, Real-time Fluid Simulation Engine for Unity and a game which showcases its features.Victor2266 Open SourceFree spritesheets - Download our free CC0 spritesheet pack. Explosions, lightning, smoke, confetti, and slashes ready to use —no restrictions, no attribution required!jettelly.comSpatial-Rumble - Allows you to emit pre-defined controller vibrations/rumbles in a spatialized way, with attenuation over distance.RoyTheunissen Open SourceUnity-SplineRoadUtils - A set of spline tools to build a simple road network in unityelrod Open SourcePicLet - Handy right-click tools for everyday image tasksmuammar-yacoob Open SourceTidy-Monkey - Blender Add-On for Game Developers. Productivity Tools for Blender 3D Artistsmuammar-yacoob Open Sourcemassive-ecs - Sparse set ECS with rollbacks. C# library and Unity package.nilpunch Open SourceUIMaterialPropertyInjector - This package provides a component that allows easy modification/animation of material properties for Unity UIwithout the need for shader-specific custom components.mob-sakai Open SourceInputGlyphs - Displays glyphsof keyboard & mouse or controller buttons detected by Unity's InputSystem.eviltwo Open SourceSpoke - Spoke is a tiny declarative reactivity engine for Unity.Adam4lexander Open SourceGiLight2D - Experimental 2D Raytracing for Unity UrpNullTale Open SourceSoCreator - Tool for convenient ScriptableObject's creationNullTale Open SourceBasis - Basis is an open-source social framework for VR and Desktop usage.BasisVR Open SourceUnityLocalizationEditor - Localization Editor A handy Unity Editor tool for managing localization keys and language files directly within the Editor. Easily find, edit, and save localization keys, auto-attach components, and generate language files with zero hassle.SinlessDevil Open SourceSaveSystemToolkit - A modular, extensible and editor-friendly System for Unity, supporting multiple serialization formats,SinlessDevil Open SourceTypedMigrate.NET - Fully statically typed data migration system for C# and Unity.dmitrybaltin Open SourceMeshia.MeshSimplification - Burst accelerated mesh simplification.RamType0 Open Sourceunity-kataru - Unity integration for Kataru, the minimal interactive dialogue language.kataru-lang Open SourceMega Bundle – Must-Have New Assets - Up To 90% Off - Discover a curated collection of must-have new assets, including versatile game templates, powerful tools, beautiful environments, dynamic animations, and innovative VFX. Get the entire bundle now for just !Unity AffiliateShop up to 50% off ithappy - Publisher Sale - A 3D studio specializing in low-poly model packs with a consistent, high-quality art style. Modular locations and characters let you bring any idea to life. Create stunning worlds with ease! PLUS get Furniture Cute - Low Poly 3D Models Pack for FREE with code ITHAPPY2025Unity Affiliatecom.moonlitstudios.immediatestyle - Allows you to interact with Unity UI GameObjects in an immediate Style and fashionhopeforsenegal Open SourceEasy-Text-Effects-for-Unity - An open-source Unity package for animating TextMeshPro text with customizable effects. Includes ready-to-use samples, real-time previews, and per-vertex animation capabilities.LeiQiaoZhi Open SourceStereoCancer - An open-source stereo-correct screen-space shader for Unity, mainly intended for usage in animations and games such as VRChat.xwidghet Open SourceMobileConsoleKit - Mobile Console Kit is a Unity Asset Store that help you not just viewing logs in mobile devices, but helping you monitor, do experiment and speed up development time.pixeption Open SourceDevAccelerationSystem - The DevAccelerationSystem helps to enable features to speed up development iteration from code perspective. It includes ProjectCompilation checks for all your target platforms with different scripting define symbols combinations in your project.FoxsterDev Open Sourcenvim-unity-sync - nvim-unity is a Neovim plugin that helps you keep your .csproj files up to date when working on Unity projects.apyra Open SourceSavable-ScriptableObjects-Unity - Unity plugin that enables saving and loading ScriptableObjects using JSON serializationand PlayerPrefsEduardMalkhasyan Open SourceUltimate World Building Asset Bundle - Imagine it—build it—love it Elevate your next project with elite 3D assets, textures, references, and more from the Ultimate World Building Asset Bundle by ScansMatter—featuring 300 free commercial credits on ScansMatter.com, Rooftop Asset Kit, Office Environment Kit, and much more. This limited-time partnership with ScansMatter gives Humble Bundle members a unique opportunity to access countless professional-quality assets at a fraction of the price. Get the assets you need to bring your next visual project to life—and help support the World Wildlife Fund with your purchase!Humble Bundle AffiliateLearn To Make Games In Godot 4 Bundle - Godot 4 just got a lot easier Been sitting on your game dev ambitions? Jump into this bundle of online courses from GameDev.tv, packed with expert instruction on the skills you need to develop both 2D and 3D games using Godot 4. Learn the fundamentals of game mechanics, animation, scripting, and more with hot courses like Complete Godot 3D Course: Develop Your Own 3D Games Using Godot 4. Get the expert advice and knowledge you’re looking for—and help support Oceana with your purchase!Humble Bundle AffiliateUnlock Pro 3D Modeling Skills With Blender - Software Bundle - Unlock awesome 3D tools for Blender__
    SpotlightDystopia Punk - Zero Hour - Dystopia Punk: Zero Hour is a single-player cyberpunk rogue-lite where you fight to reclaim a city ruled by Megacorps. Infiltrate, sabotage, and seize districts in a world that fights back. Unlock abilities, recruit allies, and shape the resistance-one mission at a time. Will you rise or be crushed?__My game, Call Of Dookie. Demo available on SteamYou can subscribe to the free weekly newsletter on GameDevDigest.comThis post includes affiliate links; I may receive compensation if you purchase products or services from the different links provided in this article.

    Comments

    Nobody has left a comment. You can be the first!

    You must log in to join the conversation.
    Don't have a GameDev.net account? Sign up!
    #game #dev #digest #issue #unity
    Game Dev Digest Issue #282 - Unity 6.2 Beta, Level/Character Design, and more
    Game Dev Digest Issue #282 - Unity 6.2 Beta, Level/Character Design, and more posted in GameDevDigest Newsletter Published May 16, 2025 Advertisement This article was originally published on GameDevDigest.comEnjoy!Unity 6.2 Beta is now available - Test the latest features, including Unity AI, Mesh LOD, and World Space UI for UI Toolkit. Dive in today and help shape the future of Unity!discussions.unity.comSpace is not a wall: toward a less architectural level design - People want to do level design. They grow up playing games like Minecraft, Roblox, Fortnite — all 3D games with 3D worlds. And to create 3D worlds, supposedly you need this thing called “level design.” Then when you search YouTube, you'll be told that level design is about implanting secret lines that "guide the player" into walking down hallways. Such is the power of ARCHITECTURE!blog.radiator.debacle.usSound and Music in Warhammer 40,000: Rogue Trader | An Audio Director's Perspective - In this article, I will discuss the approach to sound design and music that we took in our latest game: Warhammer 40,000: Rogue Trader.audiokinetic.comCastle Kellmore rendering - Since Castle Kellmore released on Playdate, I have had a lot of interest in the technical aspects of its rendering system. So I thought I would give a brief insight into how I made it look as good as possible, whilekeeping to 50 frames per second.ligeiagames.comUnity-Advanced-Engineering-Guide - Unity Software Engineering GuideMfaXyz VideosDesigning and Creating Video Game Zombie AI ft. PikPok - James and Sarah from PikPokare here to share their process for designing zombie behavior and bringing them to life in Unity!UnityThe GOOD, The BAD, and The BIZARRE of Unity 6.1's XR Updates - Unity 6.1 brings major XR updates, but not all features are created equal! This breakdown reveals which VR/AR features are genuinely useful. Learn about Variable Rate Shading, the new Mixed Multiplayer Tabletop Template, and why Deferred+ rendering is great tech you'll rarely use unless you're making a PC VR experience. I also dive into Unity's strange decision to support Android XR devices that don't actually exist yet!Fist Full of ShrimpHow to Generate Random Tilemap Decorations in Unity - In this continuation of the "How to Make a 2D Platformer Game in Unity" series we'll be generating random tilemap decorations using a rule tile.Wild Cockatiel GamesDiscover the HIDDEN POWER of Unity Property Bags and Visitors - The Property bag is the cornerstone of Unity.Properties—a powerful system that lets you generically access, inspect, and modify object data at runtime without reflection. In this video, we’ll show you how property bags, visitors, and adapters work together to build flexible, high-performance systems for tooling, UI binding, data validation, and more. You’ll learn how to write your own visitors, construct property paths, and use these patterns to create runtime features that adapt to any data structure.git-amendUnderstanding shaders is easy, actually - Shader code can be scary but... Well, it is scary, but it's also quite simple!tEEvy gamezBeginner mistakes when drawing assets | 2D Game Art - If you're a beginner to game art all of this art stuff might feel a bit dauntingNonsensical 2DEnemies in Unity ECS - Fundamentals & ICleanupComponentData - Build a high-performance Enemy System in Unity using ECS and DOTS!Tale ForgeI’m a Caver Making a Cave Game with Custom Tech. It’s Complicated. - This video is a longer discussion and explanation about the tech I'm developing for my caving game.Fredrik Andersson AssetsLevel Up: 5K World Building Assets Bundle - Build the game of your dreams in any setting or scenario with our Level Up: 5K World Building Assets Bundle.__Character Art Tutorial Bundle - Flash Sale - Create stylized AAA characters today Say hi to summer with a scorching hot FLASH SALE! Learn how to create original AAA-quality characters from the pros at FastTrackTutorials. Build warriors, ninjas, and more with a suite of lesson videos. Pay what you want and help support One Tree Planted with your purchase.Humble Bundle AffiliateThe-Fluid-Toy - An Opensource, GPU-Accelerated, Particle-Based, Multi-phase, Real-time Fluid Simulation Engine for Unity and a game which showcases its features.Victor2266 Open SourceFree spritesheets - Download our free CC0 spritesheet pack. Explosions, lightning, smoke, confetti, and slashes ready to use —no restrictions, no attribution required!jettelly.comSpatial-Rumble - Allows you to emit pre-defined controller vibrations/rumbles in a spatialized way, with attenuation over distance.RoyTheunissen Open SourceUnity-SplineRoadUtils - A set of spline tools to build a simple road network in unityelrod Open SourcePicLet - Handy right-click tools for everyday image tasksmuammar-yacoob Open SourceTidy-Monkey - Blender Add-On for Game Developers. Productivity Tools for Blender 3D Artistsmuammar-yacoob Open Sourcemassive-ecs - Sparse set ECS with rollbacks. C# library and Unity package.nilpunch Open SourceUIMaterialPropertyInjector - This package provides a component that allows easy modification/animation of material properties for Unity UIwithout the need for shader-specific custom components.mob-sakai Open SourceInputGlyphs - Displays glyphsof keyboard & mouse or controller buttons detected by Unity's InputSystem.eviltwo Open SourceSpoke - Spoke is a tiny declarative reactivity engine for Unity.Adam4lexander Open SourceGiLight2D - Experimental 2D Raytracing for Unity UrpNullTale Open SourceSoCreator - Tool for convenient ScriptableObject's creationNullTale Open SourceBasis - Basis is an open-source social framework for VR and Desktop usage.BasisVR Open SourceUnityLocalizationEditor - Localization Editor A handy Unity Editor tool for managing localization keys and language files directly within the Editor. Easily find, edit, and save localization keys, auto-attach components, and generate language files with zero hassle.SinlessDevil Open SourceSaveSystemToolkit - A modular, extensible and editor-friendly System for Unity, supporting multiple serialization formats,SinlessDevil Open SourceTypedMigrate.NET - Fully statically typed data migration system for C# and Unity.dmitrybaltin Open SourceMeshia.MeshSimplification - Burst accelerated mesh simplification.RamType0 Open Sourceunity-kataru - Unity integration for Kataru, the minimal interactive dialogue language.kataru-lang Open SourceMega Bundle – Must-Have New Assets - Up To 90% Off - Discover a curated collection of must-have new assets, including versatile game templates, powerful tools, beautiful environments, dynamic animations, and innovative VFX. Get the entire bundle now for just !Unity AffiliateShop up to 50% off ithappy - Publisher Sale - A 3D studio specializing in low-poly model packs with a consistent, high-quality art style. Modular locations and characters let you bring any idea to life. Create stunning worlds with ease! PLUS get Furniture Cute - Low Poly 3D Models Pack for FREE with code ITHAPPY2025Unity Affiliatecom.moonlitstudios.immediatestyle - Allows you to interact with Unity UI GameObjects in an immediate Style and fashionhopeforsenegal Open SourceEasy-Text-Effects-for-Unity - An open-source Unity package for animating TextMeshPro text with customizable effects. Includes ready-to-use samples, real-time previews, and per-vertex animation capabilities.LeiQiaoZhi Open SourceStereoCancer - An open-source stereo-correct screen-space shader for Unity, mainly intended for usage in animations and games such as VRChat.xwidghet Open SourceMobileConsoleKit - Mobile Console Kit is a Unity Asset Store that help you not just viewing logs in mobile devices, but helping you monitor, do experiment and speed up development time.pixeption Open SourceDevAccelerationSystem - The DevAccelerationSystem helps to enable features to speed up development iteration from code perspective. It includes ProjectCompilation checks for all your target platforms with different scripting define symbols combinations in your project.FoxsterDev Open Sourcenvim-unity-sync - nvim-unity is a Neovim plugin that helps you keep your .csproj files up to date when working on Unity projects.apyra Open SourceSavable-ScriptableObjects-Unity - Unity plugin that enables saving and loading ScriptableObjects using JSON serializationand PlayerPrefsEduardMalkhasyan Open SourceUltimate World Building Asset Bundle - Imagine it—build it—love it Elevate your next project with elite 3D assets, textures, references, and more from the Ultimate World Building Asset Bundle by ScansMatter—featuring 300 free commercial credits on ScansMatter.com, Rooftop Asset Kit, Office Environment Kit, and much more. This limited-time partnership with ScansMatter gives Humble Bundle members a unique opportunity to access countless professional-quality assets at a fraction of the price. Get the assets you need to bring your next visual project to life—and help support the World Wildlife Fund with your purchase!Humble Bundle AffiliateLearn To Make Games In Godot 4 Bundle - Godot 4 just got a lot easier Been sitting on your game dev ambitions? Jump into this bundle of online courses from GameDev.tv, packed with expert instruction on the skills you need to develop both 2D and 3D games using Godot 4. Learn the fundamentals of game mechanics, animation, scripting, and more with hot courses like Complete Godot 3D Course: Develop Your Own 3D Games Using Godot 4. Get the expert advice and knowledge you’re looking for—and help support Oceana with your purchase!Humble Bundle AffiliateUnlock Pro 3D Modeling Skills With Blender - Software Bundle - Unlock awesome 3D tools for Blender__ SpotlightDystopia Punk - Zero Hour - Dystopia Punk: Zero Hour is a single-player cyberpunk rogue-lite where you fight to reclaim a city ruled by Megacorps. Infiltrate, sabotage, and seize districts in a world that fights back. Unlock abilities, recruit allies, and shape the resistance-one mission at a time. Will you rise or be crushed?__My game, Call Of Dookie. Demo available on SteamYou can subscribe to the free weekly newsletter on GameDevDigest.comThis post includes affiliate links; I may receive compensation if you purchase products or services from the different links provided in this article. Comments Nobody has left a comment. You can be the first! You must log in to join the conversation. Don't have a GameDev.net account? Sign up! #game #dev #digest #issue #unity
    Game Dev Digest Issue #282 - Unity 6.2 Beta, Level/Character Design, and more
    Game Dev Digest Issue #282 - Unity 6.2 Beta, Level/Character Design, and more posted in GameDevDigest Newsletter Published May 16, 2025 Advertisement This article was originally published on GameDevDigest.comEnjoy!Unity 6.2 Beta is now available - Test the latest features, including Unity AI, Mesh LOD, and World Space UI for UI Toolkit. Dive in today and help shape the future of Unity!discussions.unity.comSpace is not a wall: toward a less architectural level design - People want to do level design. They grow up playing games like Minecraft, Roblox, Fortnite — all 3D games with 3D worlds. And to create 3D worlds, supposedly you need this thing called “level design.” Then when you search YouTube, you'll be told that level design is about implanting secret lines that "guide the player" into walking down hallways. Such is the power of ARCHITECTURE!blog.radiator.debacle.usSound and Music in Warhammer 40,000: Rogue Trader | An Audio Director's Perspective - In this article, I will discuss the approach to sound design and music that we took in our latest game: Warhammer 40,000: Rogue Trader.audiokinetic.comCastle Kellmore rendering - Since Castle Kellmore released on Playdate, I have had a lot of interest in the technical aspects of its rendering system. So I thought I would give a brief insight into how I made it look as good as possible, while (mostly) keeping to 50 frames per second.ligeiagames.comUnity-Advanced-Engineering-Guide - Unity Software Engineering Guide (Design Patterns, Software Architecture, Algorithms and Data Structure)MfaXyz VideosDesigning and Creating Video Game Zombie AI ft. PikPok - James and Sarah from PikPok (creators of Into the Dead: Our Darkest Days) are here to share their process for designing zombie behavior and bringing them to life in Unity!UnityThe GOOD, The BAD, and The BIZARRE of Unity 6.1's XR Updates - Unity 6.1 brings major XR updates, but not all features are created equal! This breakdown reveals which VR/AR features are genuinely useful. Learn about Variable Rate Shading, the new Mixed Multiplayer Tabletop Template, and why Deferred+ rendering is great tech you'll rarely use unless you're making a PC VR experience. I also dive into Unity's strange decision to support Android XR devices that don't actually exist yet!Fist Full of ShrimpHow to Generate Random Tilemap Decorations in Unity - In this continuation of the "How to Make a 2D Platformer Game in Unity" series we'll be generating random tilemap decorations using a rule tile.Wild Cockatiel GamesDiscover the HIDDEN POWER of Unity Property Bags and Visitors - The Property bag is the cornerstone of Unity.Properties—a powerful system that lets you generically access, inspect, and modify object data at runtime without reflection. In this video, we’ll show you how property bags, visitors, and adapters work together to build flexible, high-performance systems for tooling, UI binding, data validation, and more. You’ll learn how to write your own visitors, construct property paths, and use these patterns to create runtime features that adapt to any data structure.git-amendUnderstanding shaders is easy, actually - Shader code can be scary but... Well, it is scary, but it's also quite simple!tEEvy gamezBeginner mistakes when drawing assets | 2D Game Art - If you're a beginner to game art all of this art stuff might feel a bit dauntingNonsensical 2DEnemies in Unity ECS - Fundamentals & ICleanupComponentData - Build a high-performance Enemy System in Unity using ECS and DOTS!Tale ForgeI’m a Caver Making a Cave Game with Custom Tech. It’s Complicated. - This video is a longer discussion and explanation about the tech I'm developing for my caving game.Fredrik Andersson AssetsLevel Up: 5K World Building Assets Bundle - Build the game of your dreams in any setting or scenario with our Level Up: 5K World Building Assets Bundle.__Character Art Tutorial Bundle - Flash Sale - Create stylized AAA characters today Say hi to summer with a scorching hot FLASH SALE! Learn how to create original AAA-quality characters from the pros at FastTrackTutorials. Build warriors, ninjas, and more with a suite of lesson videos. Pay what you want and help support One Tree Planted with your purchase.Humble Bundle AffiliateThe-Fluid-Toy - An Opensource, GPU-Accelerated, Particle-Based, Multi-phase, Real-time Fluid Simulation Engine for Unity and a game which showcases its features. [Play with it here]Victor2266 Open SourceFree spritesheets - Download our free CC0 spritesheet pack. Explosions, lightning, smoke, confetti, and slashes ready to use —no restrictions, no attribution required!jettelly.comSpatial-Rumble - Allows you to emit pre-defined controller vibrations/rumbles in a spatialized way, with attenuation over distance.RoyTheunissen Open SourceUnity-SplineRoadUtils - A set of spline tools to build a simple road network in unityelrod Open SourcePicLet - Handy right-click tools for everyday image tasksmuammar-yacoob Open SourceTidy-Monkey - Blender Add-On for Game Developers. Productivity Tools for Blender 3D Artistsmuammar-yacoob Open Sourcemassive-ecs - Sparse set ECS with rollbacks. C# library and Unity package.nilpunch Open SourceUIMaterialPropertyInjector - This package provides a component that allows easy modification/animation of material properties for Unity UI (uGUI) without the need for shader-specific custom components.mob-sakai Open SourceInputGlyphs - Displays glyphs (icons) of keyboard & mouse or controller buttons detected by Unity's InputSystem.eviltwo Open SourceSpoke - Spoke is a tiny declarative reactivity engine for Unity.Adam4lexander Open SourceGiLight2D - Experimental 2D Raytracing for Unity UrpNullTale Open SourceSoCreator - Tool for convenient ScriptableObject's creationNullTale Open SourceBasis - Basis is an open-source social framework for VR and Desktop usage.BasisVR Open SourceUnityLocalizationEditor - Localization Editor A handy Unity Editor tool for managing localization keys and language files directly within the Editor. Easily find, edit, and save localization keys, auto-attach components, and generate language files with zero hassle.SinlessDevil Open SourceSaveSystemToolkit - A modular, extensible and editor-friendly Save System for Unity, supporting multiple serialization formats (PlayerPrefs, JSON, XML),SinlessDevil Open SourceTypedMigrate.NET - Fully statically typed data migration system for C# and Unity.dmitrybaltin Open SourceMeshia.MeshSimplification - Burst accelerated mesh simplification.RamType0 Open Sourceunity-kataru - Unity integration for Kataru, the minimal interactive dialogue language.kataru-lang Open SourceMega Bundle – Must-Have New Assets - Up To 90% Off - Discover a curated collection of must-have new assets, including versatile game templates, powerful tools, beautiful environments, dynamic animations, and innovative VFX. Get the entire bundle now for just $99!Unity AffiliateShop up to 50% off ithappy - Publisher Sale - A 3D studio specializing in low-poly model packs with a consistent, high-quality art style. Modular locations and characters let you bring any idea to life. Create stunning worlds with ease! PLUS get Furniture Cute - Low Poly 3D Models Pack for FREE with code ITHAPPY2025Unity Affiliatecom.moonlitstudios.immediatestyle - Allows you to interact with Unity UI GameObjects in an immediate Style and fashionhopeforsenegal Open SourceEasy-Text-Effects-for-Unity - An open-source Unity package for animating TextMeshPro text with customizable effects. Includes ready-to-use samples, real-time previews, and per-vertex animation capabilities.LeiQiaoZhi Open SourceStereoCancer - An open-source stereo-correct screen-space shader for Unity, mainly intended for usage in animations and games such as VRChat.xwidghet Open SourceMobileConsoleKit - Mobile Console Kit is a Unity Asset Store that help you not just viewing logs in mobile devices, but helping you monitor, do experiment and speed up development time.pixeption Open SourceDevAccelerationSystem - The DevAccelerationSystem helps to enable features to speed up development iteration from code perspective. It includes ProjectCompilation checks for all your target platforms with different scripting define symbols combinations in your project.FoxsterDev Open Sourcenvim-unity-sync - nvim-unity is a Neovim plugin that helps you keep your .csproj files up to date when working on Unity projects.apyra Open SourceSavable-ScriptableObjects-Unity - Unity plugin that enables saving and loading ScriptableObjects using JSON serialization (Newtonsoft.Json) and PlayerPrefsEduardMalkhasyan Open SourceUltimate World Building Asset Bundle - Imagine it—build it—love it Elevate your next project with elite 3D assets, textures, references, and more from the Ultimate World Building Asset Bundle by ScansMatter—featuring 300 free commercial credits on ScansMatter.com, Rooftop Asset Kit, Office Environment Kit, and much more. This limited-time partnership with ScansMatter gives Humble Bundle members a unique opportunity to access countless professional-quality assets at a fraction of the price. Get the assets you need to bring your next visual project to life—and help support the World Wildlife Fund with your purchase!Humble Bundle AffiliateLearn To Make Games In Godot 4 Bundle - Godot 4 just got a lot easier Been sitting on your game dev ambitions? Jump into this bundle of online courses from GameDev.tv, packed with expert instruction on the skills you need to develop both 2D and 3D games using Godot 4. Learn the fundamentals of game mechanics, animation, scripting, and more with hot courses like Complete Godot 3D Course: Develop Your Own 3D Games Using Godot 4. Get the expert advice and knowledge you’re looking for—and help support Oceana with your purchase!Humble Bundle AffiliateUnlock Pro 3D Modeling Skills With Blender - Software Bundle - Unlock awesome 3D tools for Blender__ SpotlightDystopia Punk - Zero Hour - Dystopia Punk: Zero Hour is a single-player cyberpunk rogue-lite where you fight to reclaim a city ruled by Megacorps. Infiltrate, sabotage, and seize districts in a world that fights back. Unlock abilities, recruit allies, and shape the resistance-one mission at a time. Will you rise or be crushed?__My game, Call Of Dookie. Demo available on SteamYou can subscribe to the free weekly newsletter on GameDevDigest.comThis post includes affiliate links; I may receive compensation if you purchase products or services from the different links provided in this article. Comments Nobody has left a comment. You can be the first! You must log in to join the conversation. Don't have a GameDev.net account? Sign up!
    0 Reacties 0 aandelen
  • 6 ways ScriptableObjects can benefit your team and your code

    We’re happy to announce that we’ve launched a new technical e-book, Create modular game architecture in Unity with ScriptableObjects, which provides best practices from professional developers for deploying ScriptableObjects in production.Along with the e-book, you can download a demo project from GitHub inspired by classic ball and paddle arcade game mechanics. The demo shows how ScriptableObjects can help you create components that are testable and scalable, while also being designer-friendly. Although a game like this could be built with far fewer lines of code, this demo shows ScriptableObjects in action.This post explains the benefits of ScriptableObjects, but doesn’t cover the basics or general coding in Unity. If you’re new to programming in Unity, head over to Unity Learn, which offers helpful introductory tutorials. The first chapter in the e-book also offers a solid primer.Let’s look at six ways you can benefit from using ScriptableObjects in your projects. Want to know more? All of these examples are explored further in the e-book and demo project.Although many of the techniques shared here can also be achieved using C# classes, one of the main benefits of ScriptableObjects is the accessibility to artists and designers. They can use ScriptableObjects to configure and apply game logic in a project without having to edit the code.The Editor makes it convenient to view and edit ScriptableObjects, enabling designers to set up gameplay data without heavy support from the developer team. This also applies to game logic, such as applying behavior to an NPC by adding a ScriptableObject.Storing data and logic on a single MonoBehaviour can result in time-consuming merge conflicts if two people change different parts of the same Prefab or scene. By breaking up shared data into smaller files and assets with ScriptableObjects, designers can build gameplay in parallel with developers, instead of having to wait for the latter to finish setting up the gameplay in code before testing it.Issues can arise when colleagues with different roles access the game code and assets at the same time. With ScriptableObjects, the programmer can control what part of the project is editable in the Editor. Additionally, using ScriptableObjects to organize your code leads naturally to a codebase that’s more modular and efficient to test.Christo Nobbs, a senior technical game designer who specializes in systems game design and Unity, contributed to The Unity game designer playbook, and is the main author of a blog post series on designing game systems in Unity. His posts, “Systems that create ecosystems: Emergent game design” and “Unpredictably fun: The value of randomization in game design” provide interesting examples of how designers can use ScriptableObjects.Modularity is a general software principle which can be implemented in C# without using ScriptableObjects. But, as mentioned above, ScriptableObjects help promote clean coding practices by separating data from logic, which is a first step toward modular game code. This separation means it’s easier to make changes without causing unintended side effects, and improves testability.ScriptableObjects excel at storing static data, making them handy for configuring static gameplay values like items or NPC stats, character dialogue, and much more. Because ScriptableObjects are saved as an asset, they persist outside of game mode, making it possible to use them for loading in a static configuration that dynamically changes at runtime.While changes to ScriptableObject data do persist in the Editor, it’s important to note that they are not designed for saving game data. In that case, it’s better to use a serialization system, such as JSON, XML, or a binary solution if performance is critical.MonoBehaviours carry extra overhead since they require a GameObject – and by default a Transform – to act as a host. This means you need to create a lot of unused data before storing a single value. A ScriptableObject slims down this memory footprint and drops the GameObject and Transform. It also stores data at the project level, which is helpful if you need to access the same data from multiple scenes.It’s common to have many GameObjects which rely on duplicate data that does not need to change at runtime. Rather than having this duplicate local data on each GameObject, you can funnel it into a ScriptableObject. Each of the objects stores a reference to the shared data asset, rather than copying the data itself. This can provide significant performance improvements in projects with thousands of objects.In software design, this is an optimization known as the flyweight pattern. Restructuring your code in this way using ScriptableObjects avoids copying values and reduces your memory footprint. Check out our e-book, Level up your code with game programming patterns to learn more about using design patterns in Unity.A good example of how ScriptableObjects can simplify your code is to use them as enums for comparison operations. The ScriptableObject can represent a category or item type, such as a special damage effect – cold, heat, electrical, magic, etc.If your application requires an inventory system to equip gameplay items, ScriptableObjects can represent item types or weapon slots. The fields in the Inspector then function as a drag-and-drop interface for setting them up.Using ScriptableObjects as enums becomes more interesting when you want to extend them and add more data. Unlike normal enums, ScriptableObjects can have extra fields and methods. There’s no need to have a separate lookup table or correlate with a new array of data.While traditional enums have a fixed set of values, ScriptableObject enums can be created and modified at runtime, allowing you to add or remove values as needed.If you have a long list of enum values without explicit numbering, inserting or removing an enum can change their order. This reordering can introduce subtle bugs or unintended behavior. ScriptableObject-based enums don’t have these issues. You can delete or add to your project without having to change the code every time.Suppose you want to make an item equippable in an RPG. You could append an extra boolean field to the ScriptableObject to do that. Are certain characters not allowed to hold certain items? Are some items magical or do they have special abilities? ScriptableObject-based enums can do that.Because you can create methods on a ScriptableObject, they are as useful for containing logic or actions as they are for holding data. Moving logic from your MonoBehaviour into a ScriptableObject enables you to use the latter as a delegate object, making the behavior more modular.If you need to perform specific tasks, you can encapsulate their algorithms into their own objects. The original Gang of Four refers to this general design as the strategy pattern. The example below shows how to make the strategy pattern more useful by using an abstract class to implement EnemyAI. The result is several derived ScriptableObjects with different behavior, which then becomes a pluggable behavior since each asset is interchangeable. You just drag and drop the ScriptableObject of choice into the MonoBehaviour.For a detailed example showing how to use ScriptableObjects to drive behavior, watch the video series Pluggable AI with ScriptableObjects. These sessions demonstrate a finite state machine-based AI system that can be configured using ScriptableObjects for states, actions, and transitions between those states.A common challenge in larger projects is when multiple GameObjects need to share data or states by avoiding direct references between these objects. Managing these dependencies at scale can require significant effort and is often a source of bugs. Many developers use singletons – one global instance of a class that survives scene loading. However, singletons introduce global states and make unit testing difficult. If you’re working with a Prefab that references a singleton, you’ll end up importing all of its dependencies just to test an isolated function. This makes your code less modular and efficient to debug.One solution is to use ScriptableObject-based events to help your GameObjects communicate. In this case, you are using ScriptableObjects to implement a form of the observer design pattern, where a subject broadcasts a message to one or more loosely decoupled observers. Each observing object can react independently from the subject but is unaware of the other observers. The subject can also be referred to as the “publisher” or “broadcaster” and the observers as “subscribers” or “listeners.”You can implement the observer pattern with MonoBehaviours or C# objects. While this is already common practice in Unity development, a script-only approach means your designers will rely on the programming team for every event needed during gameplay.At first glance, it appears that you’ve added a layer of overhead to the observer pattern, but this structure offers some advantages. Since ScriptableObjects are assets, they are accessible to all objects in your hierarchy and don’t disappear on scene loading.Easy, persistent access to certain resources is why many developers use singletons. ScriptableObjects can often provide the same benefits without introducing as many unnecessary dependencies.In ScriptableObject-based events, any object can serve as publisher, and any object can serve as a subscriber. The ScriptableObject sits in the middle and helps relay the signal, acting like a centralized intermediary between the two.One way to think about this is as an “event channel.” Imagine the ScriptableObject as a radio tower that has any number of objects listening for its signals. An interested MonoBehaviour can subscribe to the event channel and respond when something happens.The demo shows how the observer pattern helps you set up game events for UI, sounds, and scoring.At runtime, you’ll often need to track a list of GameObjects or components in your scene. For example, a list of enemies is something you’d need to frequently access, but it’s also a dynamic list that changes as more enemies are spawned or defeated. The singleton offers easy global access, but it has several drawbacks. Instead of using a singleton, consider storing data on a ScriptableObject as a “Runtime Set.” The ScriptableObject instance appears at the project level, which means it can store data that’s available to any object from any scene, offering similar global access. Since the data is located on an asset, its public list of items is accessible at any time.In this use case, you get a specialized data container that maintains a public collection of elements but also provides basic methods to add to and remove from the collection. This can reduce the need for singletons and improve testability and modularity.Reading data directly from a ScriptableObject is also more optimal than searching the Scene Hierarchy with a find operation like Object.FindObjectOfType or GameObject.FindWithTag. Depending on your use case and the size of your hierarchy, these are relatively expensive methods that can be inefficient for per-frame updates.There are several ScriptableObjects frameworks which offer more use cases than these six scenarios. Some teams decide to use ScriptableObjects extensively, while others limit their use to loading in static data and separating logic from data. Ultimately, the needs of your project will determine how you use them.Create modular game architecture in Unity with ScriptableObjects is the third guide in our series for intermediate to advanced Unity programmers. Each guide, authored by experienced programmers, provides best practices for topics that are important to development teams.Create a C# style guide: Write cleaner code that scales assists you with developing a style guide to help unify your approach to creating a more cohesive codebase.Level up your code with game programming patternshighlights best practices for using the SOLID principles and common programming patterns to create scalable game code architecture in your Unity project.We created this series to provide actionable tips and inspiration to our experienced creators, but they aren’t rule books. There are many ways to structure your Unity project and what might seem like a natural fit for one application may not be for another. Evaluate the advantages and disadvantages of each recommendation, tip, and pattern with your colleagues before deploying it.Find more advanced guides and articles on the Unity best practices hub.
    #ways #scriptableobjects #can #benefit #your
    6 ways ScriptableObjects can benefit your team and your code
    We’re happy to announce that we’ve launched a new technical e-book, Create modular game architecture in Unity with ScriptableObjects, which provides best practices from professional developers for deploying ScriptableObjects in production.Along with the e-book, you can download a demo project from GitHub inspired by classic ball and paddle arcade game mechanics. The demo shows how ScriptableObjects can help you create components that are testable and scalable, while also being designer-friendly. Although a game like this could be built with far fewer lines of code, this demo shows ScriptableObjects in action.This post explains the benefits of ScriptableObjects, but doesn’t cover the basics or general coding in Unity. If you’re new to programming in Unity, head over to Unity Learn, which offers helpful introductory tutorials. The first chapter in the e-book also offers a solid primer.Let’s look at six ways you can benefit from using ScriptableObjects in your projects. Want to know more? All of these examples are explored further in the e-book and demo project.Although many of the techniques shared here can also be achieved using C# classes, one of the main benefits of ScriptableObjects is the accessibility to artists and designers. They can use ScriptableObjects to configure and apply game logic in a project without having to edit the code.The Editor makes it convenient to view and edit ScriptableObjects, enabling designers to set up gameplay data without heavy support from the developer team. This also applies to game logic, such as applying behavior to an NPC by adding a ScriptableObject.Storing data and logic on a single MonoBehaviour can result in time-consuming merge conflicts if two people change different parts of the same Prefab or scene. By breaking up shared data into smaller files and assets with ScriptableObjects, designers can build gameplay in parallel with developers, instead of having to wait for the latter to finish setting up the gameplay in code before testing it.Issues can arise when colleagues with different roles access the game code and assets at the same time. With ScriptableObjects, the programmer can control what part of the project is editable in the Editor. Additionally, using ScriptableObjects to organize your code leads naturally to a codebase that’s more modular and efficient to test.Christo Nobbs, a senior technical game designer who specializes in systems game design and Unity, contributed to The Unity game designer playbook, and is the main author of a blog post series on designing game systems in Unity. His posts, “Systems that create ecosystems: Emergent game design” and “Unpredictably fun: The value of randomization in game design” provide interesting examples of how designers can use ScriptableObjects.Modularity is a general software principle which can be implemented in C# without using ScriptableObjects. But, as mentioned above, ScriptableObjects help promote clean coding practices by separating data from logic, which is a first step toward modular game code. This separation means it’s easier to make changes without causing unintended side effects, and improves testability.ScriptableObjects excel at storing static data, making them handy for configuring static gameplay values like items or NPC stats, character dialogue, and much more. Because ScriptableObjects are saved as an asset, they persist outside of game mode, making it possible to use them for loading in a static configuration that dynamically changes at runtime.While changes to ScriptableObject data do persist in the Editor, it’s important to note that they are not designed for saving game data. In that case, it’s better to use a serialization system, such as JSON, XML, or a binary solution if performance is critical.MonoBehaviours carry extra overhead since they require a GameObject – and by default a Transform – to act as a host. This means you need to create a lot of unused data before storing a single value. A ScriptableObject slims down this memory footprint and drops the GameObject and Transform. It also stores data at the project level, which is helpful if you need to access the same data from multiple scenes.It’s common to have many GameObjects which rely on duplicate data that does not need to change at runtime. Rather than having this duplicate local data on each GameObject, you can funnel it into a ScriptableObject. Each of the objects stores a reference to the shared data asset, rather than copying the data itself. This can provide significant performance improvements in projects with thousands of objects.In software design, this is an optimization known as the flyweight pattern. Restructuring your code in this way using ScriptableObjects avoids copying values and reduces your memory footprint. Check out our e-book, Level up your code with game programming patterns to learn more about using design patterns in Unity.A good example of how ScriptableObjects can simplify your code is to use them as enums for comparison operations. The ScriptableObject can represent a category or item type, such as a special damage effect – cold, heat, electrical, magic, etc.If your application requires an inventory system to equip gameplay items, ScriptableObjects can represent item types or weapon slots. The fields in the Inspector then function as a drag-and-drop interface for setting them up.Using ScriptableObjects as enums becomes more interesting when you want to extend them and add more data. Unlike normal enums, ScriptableObjects can have extra fields and methods. There’s no need to have a separate lookup table or correlate with a new array of data.While traditional enums have a fixed set of values, ScriptableObject enums can be created and modified at runtime, allowing you to add or remove values as needed.If you have a long list of enum values without explicit numbering, inserting or removing an enum can change their order. This reordering can introduce subtle bugs or unintended behavior. ScriptableObject-based enums don’t have these issues. You can delete or add to your project without having to change the code every time.Suppose you want to make an item equippable in an RPG. You could append an extra boolean field to the ScriptableObject to do that. Are certain characters not allowed to hold certain items? Are some items magical or do they have special abilities? ScriptableObject-based enums can do that.Because you can create methods on a ScriptableObject, they are as useful for containing logic or actions as they are for holding data. Moving logic from your MonoBehaviour into a ScriptableObject enables you to use the latter as a delegate object, making the behavior more modular.If you need to perform specific tasks, you can encapsulate their algorithms into their own objects. The original Gang of Four refers to this general design as the strategy pattern. The example below shows how to make the strategy pattern more useful by using an abstract class to implement EnemyAI. The result is several derived ScriptableObjects with different behavior, which then becomes a pluggable behavior since each asset is interchangeable. You just drag and drop the ScriptableObject of choice into the MonoBehaviour.For a detailed example showing how to use ScriptableObjects to drive behavior, watch the video series Pluggable AI with ScriptableObjects. These sessions demonstrate a finite state machine-based AI system that can be configured using ScriptableObjects for states, actions, and transitions between those states.A common challenge in larger projects is when multiple GameObjects need to share data or states by avoiding direct references between these objects. Managing these dependencies at scale can require significant effort and is often a source of bugs. Many developers use singletons – one global instance of a class that survives scene loading. However, singletons introduce global states and make unit testing difficult. If you’re working with a Prefab that references a singleton, you’ll end up importing all of its dependencies just to test an isolated function. This makes your code less modular and efficient to debug.One solution is to use ScriptableObject-based events to help your GameObjects communicate. In this case, you are using ScriptableObjects to implement a form of the observer design pattern, where a subject broadcasts a message to one or more loosely decoupled observers. Each observing object can react independently from the subject but is unaware of the other observers. The subject can also be referred to as the “publisher” or “broadcaster” and the observers as “subscribers” or “listeners.”You can implement the observer pattern with MonoBehaviours or C# objects. While this is already common practice in Unity development, a script-only approach means your designers will rely on the programming team for every event needed during gameplay.At first glance, it appears that you’ve added a layer of overhead to the observer pattern, but this structure offers some advantages. Since ScriptableObjects are assets, they are accessible to all objects in your hierarchy and don’t disappear on scene loading.Easy, persistent access to certain resources is why many developers use singletons. ScriptableObjects can often provide the same benefits without introducing as many unnecessary dependencies.In ScriptableObject-based events, any object can serve as publisher, and any object can serve as a subscriber. The ScriptableObject sits in the middle and helps relay the signal, acting like a centralized intermediary between the two.One way to think about this is as an “event channel.” Imagine the ScriptableObject as a radio tower that has any number of objects listening for its signals. An interested MonoBehaviour can subscribe to the event channel and respond when something happens.The demo shows how the observer pattern helps you set up game events for UI, sounds, and scoring.At runtime, you’ll often need to track a list of GameObjects or components in your scene. For example, a list of enemies is something you’d need to frequently access, but it’s also a dynamic list that changes as more enemies are spawned or defeated. The singleton offers easy global access, but it has several drawbacks. Instead of using a singleton, consider storing data on a ScriptableObject as a “Runtime Set.” The ScriptableObject instance appears at the project level, which means it can store data that’s available to any object from any scene, offering similar global access. Since the data is located on an asset, its public list of items is accessible at any time.In this use case, you get a specialized data container that maintains a public collection of elements but also provides basic methods to add to and remove from the collection. This can reduce the need for singletons and improve testability and modularity.Reading data directly from a ScriptableObject is also more optimal than searching the Scene Hierarchy with a find operation like Object.FindObjectOfType or GameObject.FindWithTag. Depending on your use case and the size of your hierarchy, these are relatively expensive methods that can be inefficient for per-frame updates.There are several ScriptableObjects frameworks which offer more use cases than these six scenarios. Some teams decide to use ScriptableObjects extensively, while others limit their use to loading in static data and separating logic from data. Ultimately, the needs of your project will determine how you use them.Create modular game architecture in Unity with ScriptableObjects is the third guide in our series for intermediate to advanced Unity programmers. Each guide, authored by experienced programmers, provides best practices for topics that are important to development teams.Create a C# style guide: Write cleaner code that scales assists you with developing a style guide to help unify your approach to creating a more cohesive codebase.Level up your code with game programming patternshighlights best practices for using the SOLID principles and common programming patterns to create scalable game code architecture in your Unity project.We created this series to provide actionable tips and inspiration to our experienced creators, but they aren’t rule books. There are many ways to structure your Unity project and what might seem like a natural fit for one application may not be for another. Evaluate the advantages and disadvantages of each recommendation, tip, and pattern with your colleagues before deploying it.Find more advanced guides and articles on the Unity best practices hub. #ways #scriptableobjects #can #benefit #your
    UNITY.COM
    6 ways ScriptableObjects can benefit your team and your code
    We’re happy to announce that we’ve launched a new technical e-book, Create modular game architecture in Unity with ScriptableObjects, which provides best practices from professional developers for deploying ScriptableObjects in production.Along with the e-book, you can download a demo project from GitHub inspired by classic ball and paddle arcade game mechanics. The demo shows how ScriptableObjects can help you create components that are testable and scalable, while also being designer-friendly. Although a game like this could be built with far fewer lines of code, this demo shows ScriptableObjects in action.This post explains the benefits of ScriptableObjects, but doesn’t cover the basics or general coding in Unity. If you’re new to programming in Unity, head over to Unity Learn, which offers helpful introductory tutorials. The first chapter in the e-book also offers a solid primer.Let’s look at six ways you can benefit from using ScriptableObjects in your projects. Want to know more? All of these examples are explored further in the e-book and demo project.Although many of the techniques shared here can also be achieved using C# classes, one of the main benefits of ScriptableObjects is the accessibility to artists and designers. They can use ScriptableObjects to configure and apply game logic in a project without having to edit the code.The Editor makes it convenient to view and edit ScriptableObjects, enabling designers to set up gameplay data without heavy support from the developer team. This also applies to game logic, such as applying behavior to an NPC by adding a ScriptableObject (explained in the patterns below).Storing data and logic on a single MonoBehaviour can result in time-consuming merge conflicts if two people change different parts of the same Prefab or scene. By breaking up shared data into smaller files and assets with ScriptableObjects, designers can build gameplay in parallel with developers, instead of having to wait for the latter to finish setting up the gameplay in code before testing it.Issues can arise when colleagues with different roles access the game code and assets at the same time. With ScriptableObjects, the programmer can control what part of the project is editable in the Editor. Additionally, using ScriptableObjects to organize your code leads naturally to a codebase that’s more modular and efficient to test.Christo Nobbs, a senior technical game designer who specializes in systems game design and Unity (C#), contributed to The Unity game designer playbook, and is the main author of a blog post series on designing game systems in Unity. His posts, “Systems that create ecosystems: Emergent game design” and “Unpredictably fun: The value of randomization in game design” provide interesting examples of how designers can use ScriptableObjects.Modularity is a general software principle which can be implemented in C# without using ScriptableObjects. But, as mentioned above, ScriptableObjects help promote clean coding practices by separating data from logic, which is a first step toward modular game code. This separation means it’s easier to make changes without causing unintended side effects, and improves testability.ScriptableObjects excel at storing static data, making them handy for configuring static gameplay values like items or NPC stats, character dialogue, and much more. Because ScriptableObjects are saved as an asset, they persist outside of game mode, making it possible to use them for loading in a static configuration that dynamically changes at runtime.While changes to ScriptableObject data do persist in the Editor, it’s important to note that they are not designed for saving game data. In that case, it’s better to use a serialization system, such as JSON, XML, or a binary solution if performance is critical.MonoBehaviours carry extra overhead since they require a GameObject – and by default a Transform – to act as a host. This means you need to create a lot of unused data before storing a single value. A ScriptableObject slims down this memory footprint and drops the GameObject and Transform. It also stores data at the project level, which is helpful if you need to access the same data from multiple scenes.It’s common to have many GameObjects which rely on duplicate data that does not need to change at runtime. Rather than having this duplicate local data on each GameObject, you can funnel it into a ScriptableObject. Each of the objects stores a reference to the shared data asset, rather than copying the data itself. This can provide significant performance improvements in projects with thousands of objects.In software design, this is an optimization known as the flyweight pattern. Restructuring your code in this way using ScriptableObjects avoids copying values and reduces your memory footprint. Check out our e-book, Level up your code with game programming patterns to learn more about using design patterns in Unity.A good example of how ScriptableObjects can simplify your code is to use them as enums for comparison operations. The ScriptableObject can represent a category or item type, such as a special damage effect – cold, heat, electrical, magic, etc.If your application requires an inventory system to equip gameplay items, ScriptableObjects can represent item types or weapon slots. The fields in the Inspector then function as a drag-and-drop interface for setting them up.Using ScriptableObjects as enums becomes more interesting when you want to extend them and add more data. Unlike normal enums, ScriptableObjects can have extra fields and methods. There’s no need to have a separate lookup table or correlate with a new array of data.While traditional enums have a fixed set of values, ScriptableObject enums can be created and modified at runtime, allowing you to add or remove values as needed.If you have a long list of enum values without explicit numbering, inserting or removing an enum can change their order. This reordering can introduce subtle bugs or unintended behavior. ScriptableObject-based enums don’t have these issues. You can delete or add to your project without having to change the code every time.Suppose you want to make an item equippable in an RPG. You could append an extra boolean field to the ScriptableObject to do that. Are certain characters not allowed to hold certain items? Are some items magical or do they have special abilities? ScriptableObject-based enums can do that.Because you can create methods on a ScriptableObject, they are as useful for containing logic or actions as they are for holding data. Moving logic from your MonoBehaviour into a ScriptableObject enables you to use the latter as a delegate object, making the behavior more modular.If you need to perform specific tasks, you can encapsulate their algorithms into their own objects. The original Gang of Four refers to this general design as the strategy pattern. The example below shows how to make the strategy pattern more useful by using an abstract class to implement EnemyAI. The result is several derived ScriptableObjects with different behavior, which then becomes a pluggable behavior since each asset is interchangeable. You just drag and drop the ScriptableObject of choice into the MonoBehaviour.For a detailed example showing how to use ScriptableObjects to drive behavior, watch the video series Pluggable AI with ScriptableObjects. These sessions demonstrate a finite state machine-based AI system that can be configured using ScriptableObjects for states, actions, and transitions between those states.A common challenge in larger projects is when multiple GameObjects need to share data or states by avoiding direct references between these objects. Managing these dependencies at scale can require significant effort and is often a source of bugs. Many developers use singletons – one global instance of a class that survives scene loading. However, singletons introduce global states and make unit testing difficult. If you’re working with a Prefab that references a singleton, you’ll end up importing all of its dependencies just to test an isolated function. This makes your code less modular and efficient to debug.One solution is to use ScriptableObject-based events to help your GameObjects communicate. In this case, you are using ScriptableObjects to implement a form of the observer design pattern, where a subject broadcasts a message to one or more loosely decoupled observers. Each observing object can react independently from the subject but is unaware of the other observers. The subject can also be referred to as the “publisher” or “broadcaster” and the observers as “subscribers” or “listeners.”You can implement the observer pattern with MonoBehaviours or C# objects. While this is already common practice in Unity development, a script-only approach means your designers will rely on the programming team for every event needed during gameplay.At first glance, it appears that you’ve added a layer of overhead to the observer pattern, but this structure offers some advantages. Since ScriptableObjects are assets, they are accessible to all objects in your hierarchy and don’t disappear on scene loading.Easy, persistent access to certain resources is why many developers use singletons. ScriptableObjects can often provide the same benefits without introducing as many unnecessary dependencies.In ScriptableObject-based events, any object can serve as publisher (which broadcasts the event), and any object can serve as a subscriber (which listens for the event). The ScriptableObject sits in the middle and helps relay the signal, acting like a centralized intermediary between the two.One way to think about this is as an “event channel.” Imagine the ScriptableObject as a radio tower that has any number of objects listening for its signals. An interested MonoBehaviour can subscribe to the event channel and respond when something happens.The demo shows how the observer pattern helps you set up game events for UI, sounds, and scoring.At runtime, you’ll often need to track a list of GameObjects or components in your scene. For example, a list of enemies is something you’d need to frequently access, but it’s also a dynamic list that changes as more enemies are spawned or defeated. The singleton offers easy global access, but it has several drawbacks. Instead of using a singleton, consider storing data on a ScriptableObject as a “Runtime Set.” The ScriptableObject instance appears at the project level, which means it can store data that’s available to any object from any scene, offering similar global access. Since the data is located on an asset, its public list of items is accessible at any time.In this use case, you get a specialized data container that maintains a public collection of elements but also provides basic methods to add to and remove from the collection. This can reduce the need for singletons and improve testability and modularity.Reading data directly from a ScriptableObject is also more optimal than searching the Scene Hierarchy with a find operation like Object.FindObjectOfType or GameObject.FindWithTag. Depending on your use case and the size of your hierarchy, these are relatively expensive methods that can be inefficient for per-frame updates.There are several ScriptableObjects frameworks which offer more use cases than these six scenarios. Some teams decide to use ScriptableObjects extensively, while others limit their use to loading in static data and separating logic from data. Ultimately, the needs of your project will determine how you use them.Create modular game architecture in Unity with ScriptableObjects is the third guide in our series for intermediate to advanced Unity programmers. Each guide, authored by experienced programmers, provides best practices for topics that are important to development teams.Create a C# style guide: Write cleaner code that scales assists you with developing a style guide to help unify your approach to creating a more cohesive codebase.Level up your code with game programming patternshighlights best practices for using the SOLID principles and common programming patterns to create scalable game code architecture in your Unity project.We created this series to provide actionable tips and inspiration to our experienced creators, but they aren’t rule books. There are many ways to structure your Unity project and what might seem like a natural fit for one application may not be for another. Evaluate the advantages and disadvantages of each recommendation, tip, and pattern with your colleagues before deploying it.Find more advanced guides and articles on the Unity best practices hub.
    0 Reacties 0 aandelen
  • Extended Q&A: Optimizing memory and build size with Addressables

    In February, as part of my role as a senior software development consultant for Unity Accelerate Solutions, I led a technical webinar about the Addressables Asset System. During the live session, I demonstrated various profiling tools that you can use to optimize a project’s runtime memory and build size. The webinar ended with a Q&A, and our team received more questions than we had time to answer.The following is an extension of that closing Q&A, so we can answer more of your questions.Q: Is the Addressables system needed for light games – like casual, arcade, or puzzle games – if I don’t have memory issues?
    A: Maybe not, but it’s good to keep in mind that the Addressables system doesn’t only improve memory performance. Having the ability to choose when you load content can improve loading times. Building content in Addressables enables you to have iterative builds that don’t take as long. For example, if you make a small script change, you may not have to rebuild all of your bundles.Q: Are loaded assets released when the scene switches?
    A: Potentially. Loaded assets from Addressables that are ready to be released because they have a ref count of zero might be unloaded from memory during a scene transition. When transitioning from scenes non-additively, call Resources.UnloadUnusedAssets. This is expensive on the CPU, but allows you to partially unload AssetBundles.Q: Do object pooling and Addressables work well together?
    A: Yes. You can load your object once from Addressables and then instantiate multiple copies of it to create your pool. When you are done with the pool, destroy all the objects and release the AsyncOperationHandle that was used to load the asset.Q: Are groups and bundles loaded into memory all at once?
    A: Addressables groups are an Editor-only concept. At runtime, you only deal with bundles. Bundles are loaded into memory only when they are needed and only the desired content is loaded.Example: You have one bundle with 10 characters in it. You ask Addressables to load three characters. The bundle’s metadata and the three characters will be loaded.Q: If I want to release an asset, do I need to keep the AsyncOperationHandle or the AssetReference?
    A: We recommend keeping the handle and using it, since you’re responsible for releasing content when you are done using it.As an example, members of our team will often go the handle route in order to avoid calling Instantiate/Release directly on the AssetReference.Q: What are the disadvantages of many small bundles?
    A: This documentation lists several disadvantages of too many bundles.Q: When an asset in a bundle is needed, what overhead do the other assets in the same bundle have? If it’s a remote bundle it must be downloaded, but is there really no memory overhead from unused assets in the bundle?
    A: Correct, a remote bundle will be fully downloaded before you can use it.Unloaded assets in a loaded asset bundle have minimal overhead at runtime. Whenever you load assets from a bundle, you need to load the bundle’s metadata. Part of this metadata includes a table of contents that lists all the assets in the bundle. More assets in a bundle equates to larger metadata.You can view this memory overhead by taking a capture with the Unity Memory Profiler. In the “All Of Memory” tab, there’s a list of all the “SerializedFile” objects in memory, one for each bundle. These objects are your bundles’ metadata.Learn more about this metadata in our documentation.Q: When working in an open-world setting, what bundling strategies can I use to unload individual assets without half unloading a bundle and relying on Resources.UnloadUnusedAssetsto clean it up, without the overhead of having every asset in its own bundle?
    A: The key thing to remember is that content should be bundled together if you expect to unload it at the same time. If your game world has “static” content, like trees and rocks for a certain biome that will not be moved by the player, that content should be bundled together. Any “dynamic” content, like items the player can pick up, should be bundled separately.This blog post and linked GitHub repo covers splitting bundles for an open-world game. It also features a way to deduplicate bundles to reduce the memory overhead of each bundle. Stages 4 and 5 are particularly relevant to open worlds.Q: When should I leave “AssetBundle CRC” enabled?
    A: The recommended practice is to have this enabled, excluding cached AssetBundles for Remote groups, and disabled for Local groups. The check is only meant to make sure the data wasn’t corrupted on download. There’s almost no reason to do the check for local AssetBundles.Q: When is it not worth it to use Addressables due to CPU performance concerns when loading and unloading assets?
    A: The Addressables system has a positive impact on CPU loading performance due to not needing to load all content up front.If you don’t use Addressables when loading a scene, you’d have to load all content and references. If you move the content to Addressables, you can choose when to load which content.For example, say you have an Inventory Manager in a scene that has a reference to 1,000 inventory items. If you don’t use Addressables, you’ll have to load every mesh, texture, audio clip, etc., for all these inventory items. If you wait to load this content, loading the scene will be faster.Q: Do all dependencies of an addressable asset also need to be Addressables, or is that only necessary if they are shared?
    A: Dependencies do not need to be marked addressable. Dependencies will be pulled into Addressables during the build process if necessary.As an example, if you make a player prefab an addressable, you don’t have to manually mark the player’s mesh, textures, or audio as addressable, too. When the bundle is built, all the dependencies that don’t yet exist in Addressables will be automatically included in the player prefab bundle.Q: If I forgot to release an asset and change scenes, what happens to this asset?
    A: Changing scenes does not inherently interact poorly with handles. But if you load an asset and forget to release its handle, the asset will persist in memory.Addressables has an internal reference-counting system. Handles are how we interact with this system. Loading an asset increments the reference count, and releasing decrements the reference count.Creators are responsible for keeping this reference count up to date. The asset will be in memory as long as the reference count is greater than one.Q: Related to the webinar example, suppose I’m making an open-world game. The boss is present somewhere in the open world. When the player heads to the boss, how do I use Addressables here? Do I send the command to load the sword async, via a trigger, at a certain distance from the enemy, or something else?
    A: It can be a fine line to choose when to load and unload content. You want to be sure the boss is ready when the player needs to see it, but might not want to load it too early when the player is still able to turn around and avoid the boss.The good thing is that you can iterate on when to load and unload content – you don’t have to get it perfectly optimized on the first try.To get started, we suggest loading all content for a particular “zone” when the player gets near. If this causes unnecessary memory pressure, you can add more fine-grained loading and unloading.If the sword is not loading soon enough, consider moving the loading trigger to start earlier, improving the load time of the sword assets by using Unity Profiler’s CPU module to see what is being loaded, or using Addressables synchronously to ensure the load is finished.This documentation includes more details and a code snippet for synchronous Addressables.Q: If I load an addressable when a scene starts, do I need to have a loading screen for it?
    A: Loading from Addressables is typically done in an asynchronous way, like with Addressables.LoadAssetAsync.There may be some content you don’t want to load before leaving a loading screen. You can collect these AsyncOperationHandles and wait for the necessary ones to complete before leaving.Q: What is the memory footprint of the addressables metadata at runtime?
    A: During Addressables initialization, the catalog file is loaded so that Addressables knows how to map labels and addresses to assets on disk or in remote locations. A larger catalog equates to a larger memory overhead at runtime.Catalog size can be reduced by stripping unnecessary data, like not including labels or GUIDs in groups that don’t need them, or by reducing the size of existing data. For example, by setting a group’s Internal Asset Naming Mode to GUID instead of filename or full path. You can view the runtime memory size of the catalog in Unity Memory Profiler.Q: What is the Unity Editor doing in the time it spends building Addressables?
    A: A build report log is output in the /Library folder. This log shows each step of the build process. To add additional details to the log, follow this path to select “Use Detailed Build Log”: Enabling Edit > Preferences > Scriptable Build Pipeline > Use Detailed Build Log.Check out visuals and documentation on how to view the log.Q: Does Resources.Loadalso have a duplication problem?
    A: Yes. It can be useful to think of Addressables content and Resources content as different “worlds.” If you have a texture in /Resources, one copy of that texture is included in the Resources file. If bundles in Addressables depend on that texture, each bundle includes an implicit copy of it. You end up with multiple copies of the texture on disk and potentially multiple copies in memory.To avoid this duplication, move the texture out of /Resources and add it to an Addressables group.Q: Do you get similar size on disk issues that are resolved by removing duplicate bundles when you don’t use Addressables?
    A: Yes. In the webinar and slides we show how deduplicating the two water racing scenes significantly reduced build size.Q: How can I prevent shader variant duplicates?
    A: Shaders can be deduplicated in the same process as any other asset – explicitly declare them in a group.If an asset is explicitly declared in an Addressables group that is going into your build, that asset will not be duplicated across multiple bundles.For shaders specifically, it is common practice for projects to use a “Shared shaders” group to contain shaders that you expect to need in memory for the lifespan of your app, and that are shared across many assets.Q: Do two Unity scenes sharing the same prefab duplicate build size?
    A: This depends on if the prefab the scenes depend on has been explicitly included in Addressables, and if the scenes are in the same or different bundles.See the visual explanation of how duplication occurs in the webinar slides and in this blog post under Stage 4.The key to remember is that all content going into a bundle needs to be able to access all of its dependencies. If you put a scene into a bundle, all of its dependencies need to either be:Explicitly included somewhere in AddressablesImplicitly included in the same bundleQ: Is it possible to compare duplicates in given groups to prevent having all the game assets packed together into an isolated group?
    A: Yes. You can run the built-in deduplication rule and then sort the assets in the Addressables Groups window into better groupings.Or, a more scalable approach is to write your own Addressables AnalyzeRules, which will appear in the Analyze window. The built-in rules are delivered as C# in the Addressables package and can serve as a baseline.For example, you may want to find every duplicate across all of your groups that start with “Character-”. Any implicit duplicates can be placed in a “Shared-Character” group.Q: Are you going to cover remote builds and local paths?
    A: We did not cover remote and local paths, which are called “Addressables Profiles” in the webinar. However, we do describe what Addressables Profiles are and how to use them in this documentation.Q: How does Addressables work with Cloud Content Delivery?
    A: CCD integration is discussed in this documentation.Q: Can you please give pointers on best practices to implement low- and high-resolution Addressables variations?
    A: You can find an example in the Addressables Sample on GitHub.Q: What if bundle content is encrypted? Does the UnityDataTool also decrypt the content?
    A: No. The data will need to be decrypted before UnityDataTool can analyze the content.Q: Is it a supported use case to build bundles from one Unity project and load the bundles at runtime from an app built from a different project?
    A: Yes. This is covered by using multiple catalogs at the same time.Q: Are there drawbacks to using InstantiateAsync, or situations where it is better to use LoadAsync + manual Instantiate?
    A: It is recommended to use Addressables.LoadAssetAsyncand call Object.Instantiate. Addressables.InstantiateAsynchas a larger performance cost.Q: I have a lot of ScriptableObjects with at least 1–2 sprites referenced as variables. If I want to change the sprites to Addressables, do I have to change the references to Addressables one by one, or is there any trick to do this?
    A: An Editor script is probably the way to go to convert these references.You can add the AssetReference fields to your ScriptableObject. Then, you can write an Editor script that iterates through your ScriptableObjects, looks up the Sprite asset in Addressables to find the associated AddressableAssetEntry, and stores the address or creates an AssetReference to be stored on the ScriptableObject.Lastly, you can remove the direct Sprite references and swap any related code to use the AssetReference.Q: Can I use addressables for WebGL games? If yes, are there any specific things to look for?
    A: Yes, and yes. Two things to note: First, WebGL does not support threading, so don’t use Tasks. Second, caching works differently on WebGL – we’ve seen issues with caching remote AssetBundles before.Q: If I use Shader.Find, is this coming from the build or Addressables?
    A: These are coming from the build of the Unity Player, not Addressables. Shader.Finddoes not return results from AssetBundles.Q: How can I organize the Addressables Groups window when I have many similarly-named groups?
    A: For organizing the Addressables Groups UI, you can enable Group Hierarchy with Dashes. This will group similarly-named groups together. For example, “Character-person” and “Character-person2” will appear in the UI under the “Character” grouping.This does not affect how bundles are created. This is only a UI organizational change.Share your feedback with us in the Addressables forum. Be sure to watch for new technical blogs from other Unity developers as part of the ongoing Tech from the Trenches series.
    #extended #qampampa #optimizing #memory #build
    Extended Q&A: Optimizing memory and build size with Addressables
    In February, as part of my role as a senior software development consultant for Unity Accelerate Solutions, I led a technical webinar about the Addressables Asset System. During the live session, I demonstrated various profiling tools that you can use to optimize a project’s runtime memory and build size. The webinar ended with a Q&A, and our team received more questions than we had time to answer.The following is an extension of that closing Q&A, so we can answer more of your questions.Q: Is the Addressables system needed for light games – like casual, arcade, or puzzle games – if I don’t have memory issues? A: Maybe not, but it’s good to keep in mind that the Addressables system doesn’t only improve memory performance. Having the ability to choose when you load content can improve loading times. Building content in Addressables enables you to have iterative builds that don’t take as long. For example, if you make a small script change, you may not have to rebuild all of your bundles.Q: Are loaded assets released when the scene switches? A: Potentially. Loaded assets from Addressables that are ready to be released because they have a ref count of zero might be unloaded from memory during a scene transition. When transitioning from scenes non-additively, call Resources.UnloadUnusedAssets. This is expensive on the CPU, but allows you to partially unload AssetBundles.Q: Do object pooling and Addressables work well together? A: Yes. You can load your object once from Addressables and then instantiate multiple copies of it to create your pool. When you are done with the pool, destroy all the objects and release the AsyncOperationHandle that was used to load the asset.Q: Are groups and bundles loaded into memory all at once? A: Addressables groups are an Editor-only concept. At runtime, you only deal with bundles. Bundles are loaded into memory only when they are needed and only the desired content is loaded.Example: You have one bundle with 10 characters in it. You ask Addressables to load three characters. The bundle’s metadata and the three characters will be loaded.Q: If I want to release an asset, do I need to keep the AsyncOperationHandle or the AssetReference? A: We recommend keeping the handle and using it, since you’re responsible for releasing content when you are done using it.As an example, members of our team will often go the handle route in order to avoid calling Instantiate/Release directly on the AssetReference.Q: What are the disadvantages of many small bundles? A: This documentation lists several disadvantages of too many bundles.Q: When an asset in a bundle is needed, what overhead do the other assets in the same bundle have? If it’s a remote bundle it must be downloaded, but is there really no memory overhead from unused assets in the bundle? A: Correct, a remote bundle will be fully downloaded before you can use it.Unloaded assets in a loaded asset bundle have minimal overhead at runtime. Whenever you load assets from a bundle, you need to load the bundle’s metadata. Part of this metadata includes a table of contents that lists all the assets in the bundle. More assets in a bundle equates to larger metadata.You can view this memory overhead by taking a capture with the Unity Memory Profiler. In the “All Of Memory” tab, there’s a list of all the “SerializedFile” objects in memory, one for each bundle. These objects are your bundles’ metadata.Learn more about this metadata in our documentation.Q: When working in an open-world setting, what bundling strategies can I use to unload individual assets without half unloading a bundle and relying on Resources.UnloadUnusedAssetsto clean it up, without the overhead of having every asset in its own bundle? A: The key thing to remember is that content should be bundled together if you expect to unload it at the same time. If your game world has “static” content, like trees and rocks for a certain biome that will not be moved by the player, that content should be bundled together. Any “dynamic” content, like items the player can pick up, should be bundled separately.This blog post and linked GitHub repo covers splitting bundles for an open-world game. It also features a way to deduplicate bundles to reduce the memory overhead of each bundle. Stages 4 and 5 are particularly relevant to open worlds.Q: When should I leave “AssetBundle CRC” enabled? A: The recommended practice is to have this enabled, excluding cached AssetBundles for Remote groups, and disabled for Local groups. The check is only meant to make sure the data wasn’t corrupted on download. There’s almost no reason to do the check for local AssetBundles.Q: When is it not worth it to use Addressables due to CPU performance concerns when loading and unloading assets? A: The Addressables system has a positive impact on CPU loading performance due to not needing to load all content up front.If you don’t use Addressables when loading a scene, you’d have to load all content and references. If you move the content to Addressables, you can choose when to load which content.For example, say you have an Inventory Manager in a scene that has a reference to 1,000 inventory items. If you don’t use Addressables, you’ll have to load every mesh, texture, audio clip, etc., for all these inventory items. If you wait to load this content, loading the scene will be faster.Q: Do all dependencies of an addressable asset also need to be Addressables, or is that only necessary if they are shared? A: Dependencies do not need to be marked addressable. Dependencies will be pulled into Addressables during the build process if necessary.As an example, if you make a player prefab an addressable, you don’t have to manually mark the player’s mesh, textures, or audio as addressable, too. When the bundle is built, all the dependencies that don’t yet exist in Addressables will be automatically included in the player prefab bundle.Q: If I forgot to release an asset and change scenes, what happens to this asset? A: Changing scenes does not inherently interact poorly with handles. But if you load an asset and forget to release its handle, the asset will persist in memory.Addressables has an internal reference-counting system. Handles are how we interact with this system. Loading an asset increments the reference count, and releasing decrements the reference count.Creators are responsible for keeping this reference count up to date. The asset will be in memory as long as the reference count is greater than one.Q: Related to the webinar example, suppose I’m making an open-world game. The boss is present somewhere in the open world. When the player heads to the boss, how do I use Addressables here? Do I send the command to load the sword async, via a trigger, at a certain distance from the enemy, or something else? A: It can be a fine line to choose when to load and unload content. You want to be sure the boss is ready when the player needs to see it, but might not want to load it too early when the player is still able to turn around and avoid the boss.The good thing is that you can iterate on when to load and unload content – you don’t have to get it perfectly optimized on the first try.To get started, we suggest loading all content for a particular “zone” when the player gets near. If this causes unnecessary memory pressure, you can add more fine-grained loading and unloading.If the sword is not loading soon enough, consider moving the loading trigger to start earlier, improving the load time of the sword assets by using Unity Profiler’s CPU module to see what is being loaded, or using Addressables synchronously to ensure the load is finished.This documentation includes more details and a code snippet for synchronous Addressables.Q: If I load an addressable when a scene starts, do I need to have a loading screen for it? A: Loading from Addressables is typically done in an asynchronous way, like with Addressables.LoadAssetAsync.There may be some content you don’t want to load before leaving a loading screen. You can collect these AsyncOperationHandles and wait for the necessary ones to complete before leaving.Q: What is the memory footprint of the addressables metadata at runtime? A: During Addressables initialization, the catalog file is loaded so that Addressables knows how to map labels and addresses to assets on disk or in remote locations. A larger catalog equates to a larger memory overhead at runtime.Catalog size can be reduced by stripping unnecessary data, like not including labels or GUIDs in groups that don’t need them, or by reducing the size of existing data. For example, by setting a group’s Internal Asset Naming Mode to GUID instead of filename or full path. You can view the runtime memory size of the catalog in Unity Memory Profiler.Q: What is the Unity Editor doing in the time it spends building Addressables? A: A build report log is output in the /Library folder. This log shows each step of the build process. To add additional details to the log, follow this path to select “Use Detailed Build Log”: Enabling Edit > Preferences > Scriptable Build Pipeline > Use Detailed Build Log.Check out visuals and documentation on how to view the log.Q: Does Resources.Loadalso have a duplication problem? A: Yes. It can be useful to think of Addressables content and Resources content as different “worlds.” If you have a texture in /Resources, one copy of that texture is included in the Resources file. If bundles in Addressables depend on that texture, each bundle includes an implicit copy of it. You end up with multiple copies of the texture on disk and potentially multiple copies in memory.To avoid this duplication, move the texture out of /Resources and add it to an Addressables group.Q: Do you get similar size on disk issues that are resolved by removing duplicate bundles when you don’t use Addressables? A: Yes. In the webinar and slides we show how deduplicating the two water racing scenes significantly reduced build size.Q: How can I prevent shader variant duplicates? A: Shaders can be deduplicated in the same process as any other asset – explicitly declare them in a group.If an asset is explicitly declared in an Addressables group that is going into your build, that asset will not be duplicated across multiple bundles.For shaders specifically, it is common practice for projects to use a “Shared shaders” group to contain shaders that you expect to need in memory for the lifespan of your app, and that are shared across many assets.Q: Do two Unity scenes sharing the same prefab duplicate build size? A: This depends on if the prefab the scenes depend on has been explicitly included in Addressables, and if the scenes are in the same or different bundles.See the visual explanation of how duplication occurs in the webinar slides and in this blog post under Stage 4.The key to remember is that all content going into a bundle needs to be able to access all of its dependencies. If you put a scene into a bundle, all of its dependencies need to either be:Explicitly included somewhere in AddressablesImplicitly included in the same bundleQ: Is it possible to compare duplicates in given groups to prevent having all the game assets packed together into an isolated group? A: Yes. You can run the built-in deduplication rule and then sort the assets in the Addressables Groups window into better groupings.Or, a more scalable approach is to write your own Addressables AnalyzeRules, which will appear in the Analyze window. The built-in rules are delivered as C# in the Addressables package and can serve as a baseline.For example, you may want to find every duplicate across all of your groups that start with “Character-”. Any implicit duplicates can be placed in a “Shared-Character” group.Q: Are you going to cover remote builds and local paths? A: We did not cover remote and local paths, which are called “Addressables Profiles” in the webinar. However, we do describe what Addressables Profiles are and how to use them in this documentation.Q: How does Addressables work with Cloud Content Delivery? A: CCD integration is discussed in this documentation.Q: Can you please give pointers on best practices to implement low- and high-resolution Addressables variations? A: You can find an example in the Addressables Sample on GitHub.Q: What if bundle content is encrypted? Does the UnityDataTool also decrypt the content? A: No. The data will need to be decrypted before UnityDataTool can analyze the content.Q: Is it a supported use case to build bundles from one Unity project and load the bundles at runtime from an app built from a different project? A: Yes. This is covered by using multiple catalogs at the same time.Q: Are there drawbacks to using InstantiateAsync, or situations where it is better to use LoadAsync + manual Instantiate? A: It is recommended to use Addressables.LoadAssetAsyncand call Object.Instantiate. Addressables.InstantiateAsynchas a larger performance cost.Q: I have a lot of ScriptableObjects with at least 1–2 sprites referenced as variables. If I want to change the sprites to Addressables, do I have to change the references to Addressables one by one, or is there any trick to do this? A: An Editor script is probably the way to go to convert these references.You can add the AssetReference fields to your ScriptableObject. Then, you can write an Editor script that iterates through your ScriptableObjects, looks up the Sprite asset in Addressables to find the associated AddressableAssetEntry, and stores the address or creates an AssetReference to be stored on the ScriptableObject.Lastly, you can remove the direct Sprite references and swap any related code to use the AssetReference.Q: Can I use addressables for WebGL games? If yes, are there any specific things to look for? A: Yes, and yes. Two things to note: First, WebGL does not support threading, so don’t use Tasks. Second, caching works differently on WebGL – we’ve seen issues with caching remote AssetBundles before.Q: If I use Shader.Find, is this coming from the build or Addressables? A: These are coming from the build of the Unity Player, not Addressables. Shader.Finddoes not return results from AssetBundles.Q: How can I organize the Addressables Groups window when I have many similarly-named groups? A: For organizing the Addressables Groups UI, you can enable Group Hierarchy with Dashes. This will group similarly-named groups together. For example, “Character-person” and “Character-person2” will appear in the UI under the “Character” grouping.This does not affect how bundles are created. This is only a UI organizational change.Share your feedback with us in the Addressables forum. Be sure to watch for new technical blogs from other Unity developers as part of the ongoing Tech from the Trenches series. #extended #qampampa #optimizing #memory #build
    UNITY.COM
    Extended Q&A: Optimizing memory and build size with Addressables
    In February, as part of my role as a senior software development consultant for Unity Accelerate Solutions, I led a technical webinar about the Addressables Asset System. During the live session, I demonstrated various profiling tools that you can use to optimize a project’s runtime memory and build size. The webinar ended with a Q&A, and our team received more questions than we had time to answer.The following is an extension of that closing Q&A, so we can answer more of your questions.Q: Is the Addressables system needed for light games – like casual, arcade, or puzzle games – if I don’t have memory issues? A: Maybe not, but it’s good to keep in mind that the Addressables system doesn’t only improve memory performance. Having the ability to choose when you load content can improve loading times. Building content in Addressables enables you to have iterative builds that don’t take as long. For example, if you make a small script change, you may not have to rebuild all of your bundles.Q: Are loaded assets released when the scene switches? A: Potentially. Loaded assets from Addressables that are ready to be released because they have a ref count of zero might be unloaded from memory during a scene transition. When transitioning from scenes non-additively, call Resources.UnloadUnusedAssets(). This is expensive on the CPU, but allows you to partially unload AssetBundles.Q: Do object pooling and Addressables work well together? A: Yes. You can load your object once from Addressables and then instantiate multiple copies of it to create your pool. When you are done with the pool, destroy all the objects and release the AsyncOperationHandle that was used to load the asset.Q: Are groups and bundles loaded into memory all at once? A: Addressables groups are an Editor-only concept. At runtime, you only deal with bundles. Bundles are loaded into memory only when they are needed and only the desired content is loaded.Example: You have one bundle with 10 characters in it. You ask Addressables to load three characters. The bundle’s metadata and the three characters will be loaded.Q: If I want to release an asset, do I need to keep the AsyncOperationHandle or the AssetReference? A: We recommend keeping the handle and using it, since you’re responsible for releasing content when you are done using it.As an example, members of our team will often go the handle route in order to avoid calling Instantiate/Release directly on the AssetReference.Q: What are the disadvantages of many small bundles? A: This documentation lists several disadvantages of too many bundles.Q: When an asset in a bundle is needed, what overhead do the other assets in the same bundle have? If it’s a remote bundle it must be downloaded, but is there really no memory overhead from unused assets in the bundle? A: Correct, a remote bundle will be fully downloaded before you can use it.Unloaded assets in a loaded asset bundle have minimal overhead at runtime. Whenever you load assets from a bundle, you need to load the bundle’s metadata. Part of this metadata includes a table of contents that lists all the assets in the bundle. More assets in a bundle equates to larger metadata.You can view this memory overhead by taking a capture with the Unity Memory Profiler. In the “All Of Memory” tab, there’s a list of all the “SerializedFile” objects in memory, one for each bundle. These objects are your bundles’ metadata.Learn more about this metadata in our documentation.Q: When working in an open-world setting, what bundling strategies can I use to unload individual assets without half unloading a bundle and relying on Resources.UnloadUnusedAssets() to clean it up, without the overhead of having every asset in its own bundle? A: The key thing to remember is that content should be bundled together if you expect to unload it at the same time. If your game world has “static” content, like trees and rocks for a certain biome that will not be moved by the player, that content should be bundled together. Any “dynamic” content, like items the player can pick up, should be bundled separately.This blog post and linked GitHub repo covers splitting bundles for an open-world game. It also features a way to deduplicate bundles to reduce the memory overhead of each bundle. Stages 4 and 5 are particularly relevant to open worlds.Q: When should I leave “AssetBundle CRC” enabled? A: The recommended practice is to have this enabled, excluding cached AssetBundles for Remote groups, and disabled for Local groups. The check is only meant to make sure the data wasn’t corrupted on download. There’s almost no reason to do the check for local AssetBundles.Q: When is it not worth it to use Addressables due to CPU performance concerns when loading and unloading assets? A: The Addressables system has a positive impact on CPU loading performance due to not needing to load all content up front.If you don’t use Addressables when loading a scene, you’d have to load all content and references. If you move the content to Addressables, you can choose when to load which content.For example, say you have an Inventory Manager in a scene that has a reference to 1,000 inventory items. If you don’t use Addressables, you’ll have to load every mesh, texture, audio clip, etc., for all these inventory items. If you wait to load this content, loading the scene will be faster.Q: Do all dependencies of an addressable asset also need to be Addressables, or is that only necessary if they are shared? A: Dependencies do not need to be marked addressable. Dependencies will be pulled into Addressables during the build process if necessary.As an example, if you make a player prefab an addressable, you don’t have to manually mark the player’s mesh, textures, or audio as addressable, too. When the bundle is built, all the dependencies that don’t yet exist in Addressables will be automatically included in the player prefab bundle.Q: If I forgot to release an asset and change scenes, what happens to this asset? A: Changing scenes does not inherently interact poorly with handles. But if you load an asset and forget to release its handle, the asset will persist in memory.Addressables has an internal reference-counting system. Handles are how we interact with this system. Loading an asset increments the reference count, and releasing decrements the reference count.Creators are responsible for keeping this reference count up to date. The asset will be in memory as long as the reference count is greater than one.Q: Related to the webinar example, suppose I’m making an open-world game. The boss is present somewhere in the open world. When the player heads to the boss, how do I use Addressables here? Do I send the command to load the sword async, via a trigger, at a certain distance from the enemy, or something else? A: It can be a fine line to choose when to load and unload content. You want to be sure the boss is ready when the player needs to see it, but might not want to load it too early when the player is still able to turn around and avoid the boss.The good thing is that you can iterate on when to load and unload content – you don’t have to get it perfectly optimized on the first try.To get started, we suggest loading all content for a particular “zone” when the player gets near (e.g., the player approaches a dungeon entrance which causes everything inside the dungeon to load). If this causes unnecessary memory pressure, you can add more fine-grained loading and unloading.If the sword is not loading soon enough, consider moving the loading trigger to start earlier, improving the load time of the sword assets by using Unity Profiler’s CPU module to see what is being loaded, or using Addressables synchronously to ensure the load is finished.This documentation includes more details and a code snippet for synchronous Addressables.Q: If I load an addressable when a scene starts, do I need to have a loading screen for it? A: Loading from Addressables is typically done in an asynchronous way, like with Addressables.LoadAssetAsync().There may be some content you don’t want to load before leaving a loading screen. You can collect these AsyncOperationHandles and wait for the necessary ones to complete before leaving.Q: What is the memory footprint of the addressables metadata at runtime (before loading any of its data)? A: During Addressables initialization, the catalog file is loaded so that Addressables knows how to map labels and addresses to assets on disk or in remote locations. A larger catalog equates to a larger memory overhead at runtime.Catalog size can be reduced by stripping unnecessary data, like not including labels or GUIDs in groups that don’t need them, or by reducing the size of existing data. For example, by setting a group’s Internal Asset Naming Mode to GUID instead of filename or full path (which can be longer). You can view the runtime memory size of the catalog in Unity Memory Profiler.Q: What is the Unity Editor doing in the time it spends building Addressables? A: A build report log is output in the /Library folder. This log shows each step of the build process. To add additional details to the log, follow this path to select “Use Detailed Build Log”: Enabling Edit > Preferences > Scriptable Build Pipeline > Use Detailed Build Log.Check out visuals and documentation on how to view the log.Q: Does Resources.Load() also have a duplication problem? A: Yes. It can be useful to think of Addressables content and Resources content as different “worlds.” If you have a texture in /Resources, one copy of that texture is included in the Resources file. If bundles in Addressables depend on that texture, each bundle includes an implicit copy of it. You end up with multiple copies of the texture on disk and potentially multiple copies in memory.To avoid this duplication, move the texture out of /Resources and add it to an Addressables group.Q: Do you get similar size on disk issues that are resolved by removing duplicate bundles when you don’t use Addressables? A: Yes. In the webinar and slides we show how deduplicating the two water racing scenes significantly reduced build size.Q: How can I prevent shader variant duplicates? A: Shaders can be deduplicated in the same process as any other asset – explicitly declare them in a group.If an asset is explicitly declared in an Addressables group that is going into your build, that asset will not be duplicated across multiple bundles.For shaders specifically, it is common practice for projects to use a “Shared shaders” group to contain shaders that you expect to need in memory for the lifespan of your app, and that are shared across many assets.Q: Do two Unity scenes sharing the same prefab duplicate build size? A: This depends on if the prefab the scenes depend on has been explicitly included in Addressables, and if the scenes are in the same or different bundles.See the visual explanation of how duplication occurs in the webinar slides and in this blog post under Stage 4.The key to remember is that all content going into a bundle needs to be able to access all of its dependencies. If you put a scene into a bundle, all of its dependencies need to either be:Explicitly included somewhere in AddressablesImplicitly included in the same bundleQ: Is it possible to compare duplicates in given groups to prevent having all the game assets packed together into an isolated group? A: Yes. You can run the built-in deduplication rule and then sort the assets in the Addressables Groups window into better groupings.Or, a more scalable approach is to write your own Addressables AnalyzeRules, which will appear in the Analyze window. The built-in rules are delivered as C# in the Addressables package and can serve as a baseline.For example, you may want to find every duplicate across all of your groups that start with “Character-”. Any implicit duplicates can be placed in a “Shared-Character” group.Q: Are you going to cover remote builds and local paths? A: We did not cover remote and local paths, which are called “Addressables Profiles” in the webinar. However, we do describe what Addressables Profiles are and how to use them in this documentation.Q: How does Addressables work with Cloud Content Delivery (CCD)? A: CCD integration is discussed in this documentation.Q: Can you please give pointers on best practices to implement low- and high-resolution Addressables variations? A: You can find an example in the Addressables Sample on GitHub.Q: What if bundle content is encrypted? Does the UnityDataTool also decrypt the content? A: No. The data will need to be decrypted before UnityDataTool can analyze the content.Q: Is it a supported use case to build bundles from one Unity project and load the bundles at runtime from an app built from a different project? A: Yes. This is covered by using multiple catalogs at the same time.Q: Are there drawbacks to using InstantiateAsync, or situations where it is better to use LoadAsync + manual Instantiate? A: It is recommended to use Addressables.LoadAssetAsync() and call Object.Instantiate(). Addressables.InstantiateAsync() has a larger performance cost.Q: I have a lot of ScriptableObjects with at least 1–2 sprites referenced as variables. If I want to change the sprites to Addressables, do I have to change the references to Addressables one by one, or is there any trick to do this? A: An Editor script is probably the way to go to convert these references.You can add the AssetReference fields to your ScriptableObject (and temporarily keep the Sprite fields). Then, you can write an Editor script that iterates through your ScriptableObjects, looks up the Sprite asset in Addressables to find the associated AddressableAssetEntry, and stores the address or creates an AssetReference to be stored on the ScriptableObject.Lastly, you can remove the direct Sprite references and swap any related code to use the AssetReference.Q: Can I use addressables for WebGL games? If yes, are there any specific things to look for? A: Yes, and yes. Two things to note: First, WebGL does not support threading, so don’t use Tasks. Second, caching works differently on WebGL – we’ve seen issues with caching remote AssetBundles before.Q: If I use Shader.Find(“ShaderName”), is this coming from the build or Addressables? A: These are coming from the build of the Unity Player, not Addressables. Shader.Find() does not return results from AssetBundles.Q: How can I organize the Addressables Groups window when I have many similarly-named groups? A: For organizing the Addressables Groups UI, you can enable Group Hierarchy with Dashes. This will group similarly-named groups together. For example, “Character-person” and “Character-person2” will appear in the UI under the “Character” grouping.This does not affect how bundles are created. This is only a UI organizational change.Share your feedback with us in the Addressables forum. Be sure to watch for new technical blogs from other Unity developers as part of the ongoing Tech from the Trenches series.
    0 Reacties 0 aandelen