ProgrammingPro #67: Unity Prefab Management with C#, Rust 1.80's Lazy Types, and TypeScript 5.6 Bug Fixes
Bite-sized actionable content, practical tutorials, and resources for programmers.
Welcome to this week’s edition of ProgrammingPro!
In today’s Expert Insight, we bring you an excerpt from the recently published book,
Mastering Unity Game Development with C#, which takes you through strategies to effectively manage prefabs, improve reusability, and maintain consistency across your Unity project.
News Highlights: Rust 1.80 adds Lazy types for memory safety; TypeScript 5.6 enhances bug detection; Shiny for Python 1.0 introduces AI chatbot support; and Google launches an Android app vulnerability knowledge base.
My top 5 picks from today’s learning resources:
With this issue, we have also finished covering all the requests you made in July. But there’s more, so dive right in.
Stay Awesome!
Divya Anne Selvaraj
Editor-in-Chief
PS: This month’s survey is now live! Do take the oppotunity to give us your feedback on ProgrammingPro, request specific learning resources, and get your one Packt Credit for the month. If you feel we did not cover something you requested for last month, do reply to this email and let me know and we will cover it in next week’s issue.
🗞️News and Analysis🔎
CAST simplifies Software Bills of Materials (SBOM) creation with new free tool: This tool facilitates the generation of SBOMs from code repositories, editing details, and adding metadata. Read to learn about all its features and benefits.
Google launches new knowledge base for remediating vulnerabilities in Android apps: The database will comprise of common coding issues and remediation guidance from experts, aligned with the OWASP standards.
Rust 1.80 adds lazy types: LazyCell and LazyLock, will delay data initialization until first access, enhancing memory safety. Read to learn more about the update which also includes new lints to avoid common coding errors.
Get ready for more Java licensing changes: In September 2024, Oracle JDK 17 will switch to the Oracle Technology Network License Agreement, requiring users to pay for updates, upgrade to JDK 21, or switch to alternative OpenJDK distributions.
TypeScript takes aim at truthy and nullish bugs: This release, following TypeScript 5.5, aims to eliminate common bugs by improving syntactic checks. Read to learn about TypeScript 5.6's new features designed to improve reliability.
Shiny for Python adds chat component for generative AI chatbots: Version 1.0 also features a testing framework, data frame enhancements, and new interactive table styling options. Read to learn about the broader capabilities of this framework.
Uno Platform 5.3 released with full JetBrains Rider support and ‘350 enhancements’: This update includes new UI controls, enhanced hot reload support, and expanded IDE compatibility. Read to learn about more components.
🎓Tutorials and Learning Resources💡
Python
📖Open Access Book | Full Stack Python: Covers everything needed to build, deploy, and manage Python-based applications. Read to learn how to transition from basic Python programming to full-scale application development.
🎓Tutorial | How to Create a Data Visualization Dashboard with Python: A step-by-step guide to creating interactive dashboards using Python libraries like Plotly, Dash, and Streamlit. Read to learn how to create dynamic charts and more.
For more Python resources go to PythonPro
C# and .NET
C# (almost) has implicit interfaces: Explores the concept of implicit interfaces in Go and how C# can simulate similar functionality. Read to learn how.
🎓Tutorial | Creating Bindings for .NET MAUI with Native Library Interop: Discusses enhancing .NET MAUI applications by integrating native libraries. Read to learn how to use the approach to incorporate native functionalities.
Practical Tips for Optimizing Performance in C# Applications: Key Recommendations include using StringBuilder for efficient string manipulation, and optimizing LINQ queries. Read to learn how to optimize without complex algorithms.
C and C++
🎓Tutorial | Counting Success - Utilizing Frequency Arrays & Maps for Optimal Coding Solutions: Explains the use of frequency arrays and maps in coding for efficient data management. Read to learn how to choose between them.
🎓Tutorial | Inside C++ Classes and Objects — How They Really Work: Covers their creation, initialization, and lifecycle. Read to learn about fundamental object-oriented programming concepts like encapsulation, abstraction, and inheritance.
🎓Tutorial | Essential Guide to Variables in C Programming - Understanding Local, Global, and Static: Explains three main types of variables. Read to learn when and how to use each type of variable optimally.
Java
Java 21 Virtual Threads - Dude, Where’s My Lock?: Netflix's JVM Ecosystem team is exploring Java 21's virtual threads, aiming to improve system performance across microservices. Read to learn how they refined their implementation.
🎓Tutorial | Java String.format vs MessageFormat: Explores differences between the two, highlighting how MessageFormat.format provides advanced features. Read to learn about the advantages and specific applications of each.
You can run Java like Python now: Discusses a major update in Java 22, allowing Java code to run like interpreted languages, such as Python, without ahead-of-time compilation. Read to learn about potential future impacts.
JavaScript and TypeScript
Garbage collection and closures: Documents the discovery of unexpected garbage collection behavior, revealing that a bigArrayBuffer in a function with a timeout, leaks memory. Read to learn about garbage collection nuances.
Making JS deterministic for fun and glory: Explores how Dusk, a multiplayer gaming platform, addresses JavaScript's non-determinism to ensure consistent game behavior. Read to learn how to achieve more deterministic outcomes.
A different way to think about typescript: Presents TypeScript's type system as a functional programming language focused on operating over sets of types. Read to learn how to view and manipulate TypeScript types.
Go
🎓Tutorial | Building static binaries with Go on Linux: Details the conditions under which Go defaults to producing static or dynamic binaries. Read to learn how to enhance portability and reduce runtime dependencies.
🎓Tutorial | Coroutines in Go: Examines the implementation and practical use of coroutines in Go, particularly through the iter package. Read to understand the mechanics and advantages of using coroutines in Go.
Rust
Crafting Interpreters with Rust - On Garbage Collection: Discusses reimplementing the Lox programming language interpreter using Rust, with a focus on developing a mark-and-sweep GC. Read for insights into memory management.
💼Case Study | Debugging distributed database mysteries with Rust, packet capture and Polars: Delves into debugging a network bandwidth issue in QuestDB's replication feature. Read to learn how to handle network performance.
Swift
📢Announcing Swift Homomorphic Encryption (HE): This open source package supports scenarios like cloud services where user data privacy is paramount. Read to learn how HE allows computations on encrypted data without exposing it.
🎓Tutorial | Memory consumption when loading UIImage from disk: Outlines the default caching behavior of UIImage. Read to learn how to mitigate memory issues, such as using UIImage(contentsOfFile:) for non-caching image loading.
PHP
🎓Tutorial | 18 Must-Know Techniques for Advanced Routing in Laravel: Offers valuable insights for optimizing and enhancing the routing capabilities of web applications. Read to learn about route parameters to versioning with examples.
SQL
🎓Tutorial | Doing Hybrid Search in CrateDB: Provides a detailed guide on using full-text search and vector search with examples on setting up and executing these searches within a database. Read to learn how to optimize search functionalities.
Ruby
How it became like this? Ruby Range class: Discusses how different versions of Ruby have treated range boundaries and the inclusion criteria. Read to understand the importance of these evolutions to master Ruby effectively.
Kotlin
Advanced Kotlin Coroutine Cheat sheet (for Android Engineers): Offers an in-depth guide for Android engineers looking to refine their usage of coroutines in more complex scenarios. Read to learn advanced coroutine management.
🌟Best Practices and Advice🚀
Q&A - Solving the issue of stale feature flags: Discusses the risks of stale or 'zombie' flags that remain in code, causing maintenance challenges and potential bugs.
Thinking Like an Architect: Emphasizes that architects amplify the team's intelligence, not by being the smartest, but by enhancing everyone's capacity to make better decisions.
Beyond Clean Code: Differentiates between clean code as outlined in Uncle Bob's "Clean Code" and the more generic use of the term, addressing criticisms that clean code leads to poor performance.
The Factorio Architecture: Explores the parallels between Factorio, a game about building factories, and software architecture, arguing that Factorio illustrates core principles of software design.
Take the Survey, Get a Packt Credit!
🧠 Expert Insight 📚
Here’s an excerpt from “Chapter 10: Tips and Tricks in Unity” in the book, Mastering Unity Game Development with C# by Mohamed Essam, published in July 2024.
Prefab workflow optimization
Prefab workflow optimization encompasses various techniques and strategies to effectively manage prefabs, improve reusability, and maintain consistency across your Unity project. The following are some techniques you can implement to improve your workflow:
Prefab variants: Use prefab variants to create variations of a base prefab with overridden properties or components. This allows you to maintain consistency while customizing specific instances of prefabs.
To create a prefab variant, first, select the base prefab you want to derive from. Then, right-click on it in the Project window and choose Create | Prefab Variant. This will create a new variant of the base prefab. You can customize the properties, components, and hierarchy of the variant while maintaining a connection to the base prefab. This allows you to make changes that are specific to the variant without them affecting other instances of the base prefab.
Nested prefabs: Utilize Unity’s nested prefab feature to create modular and reusable components with nested hierarchies. This allows for better organization and easier updating of complex prefab structures.
To create a nested prefab, simply drag one prefab onto another in the Unity hierarchy. This will make the dragged prefab a child of the other prefab, creating a nested relationship. Nested prefabs allow you to encapsulate reusable components or objects within a parent prefab, making it easier to manage and update complex prefab structures. Changes that are made to nested prefabs are automatically reflected in all instances of the parent prefab.
ScriptableObjects with prefabs: Combine ScriptableObjects with prefabs to create data-driven prefabs. Store configuration data, parameters, or references to other assets in ScriptableObjects and apply them to prefabs dynamically at runtime or in the editor.
To use ScriptableObjects with prefabs, you can create a ScriptableObject asset that holds configuration data, parameters, or references to other assets. Then, you can apply these ScriptableObject assets to prefabs by assigning them as properties or parameters in scripts attached to the prefab instances. This allows for data-driven prefab customization and flexibility.
Prefab PrefabUtility events: Utilize PrefabUtility events such as Prefab InstanceUpdatedCallback or PrefabInstanceRemovedCallback to perform custom actions or validations when prefabs are modified or removed in the editor. This allows for custom workflow automation and validation checks.
You can utilize PrefabUtility events such as PrefabInstanceUpdatedCallback or PrefabInstanceRemovedCallback to perform custom actions or validations when prefabs are modified or removed in the editor. By subscribing to these events in your editor scripts, you can trigger custom logic or workflows based on prefab modifications, allowing for automated validation checks or workflow optimizations.
Let’s explore a practical example demonstrating the implementation of one of these techniques.
Updating component properties across prefab instances
Let’s consider a scenario where you have a large number of prefabs in your Unity project, and you need to update a specific component or property across all instances of a particular prefab in the scene. Manually updating each instance can be time-consuming and error-prone. However, with the use of C# scripting and Unity’s PrefabUtility API, you can automate this process efficiently.
Problem: You have a game with hundreds of enemy prefabs scattered throughout your scenes. Due to a gameplay change, you need to update the movement speed property of the EnemyMovement component in all enemy prefabs.
Solution: You can create a C# script to iterate through all instances of the enemy prefab in the scenes and update the movement speed property of the EnemyMovement component programmatically, like so:
using UnityEngine;
using UnityEditor;
public class EnemyPrefabUpdater : MonoBehaviour
{
public float newMovementSpeed = 10f; // New movement speed value
[MenuItem("Tools/Update Enemy Prefabs")]
static void UpdateEnemyPrefabs()
{
GameObject[] enemyPrefabs = Resources.LoadAll<GameObject>("Prefabs/Enemies"); // Load all enemy prefabs from Resources folder
foreach (GameObject prefab in enemyPrefabs)
{
// Instantiate prefab to apply changes
GameObject instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
// Update movement speed property of EnemyMovement component
EnemyMovement enemyMovement = instance.GetComponent<EnemyMovement>();
if (enemyMovement != null)
{
enemyMovement.movementSpeed = newMovementSpeed;
}
// Save changes to prefab
PrefabUtility.ApplyPrefabInstance(instance, InteractionMode.UserAction);
// Destroy temporary instance
DestroyImmediate(instance);
}
Debug.Log("Enemy prefabs updated successfully.");
}
}
Let’s take a closer look at the UpdateEnemyPrefabs method.
This method is marked as static and is decorated with the [MenuItem] attribute, making it a custom menu item that can be accessed from Unity Editor’s Tools menu:
static void UpdateEnemyPrefabs(): This static method iterates through all enemy prefabs located in the Prefabs/Enemies folder within the Unity project’s Resources directory
GameObject[] enemyPrefabs = Resources.LoadAll<GameObject>("Prefabs/Enemies");: This line loads all GameObject prefabs from the Prefabs/Enemies folder using the Resources.LoadAll() method
foreach (GameObject prefab in enemyPrefabs) { ... }: This foreach loop iterates through each enemy prefab that’s loaded from the Resources folder.
Follow these steps to utilize this component effectively and achieve the desired solution:
Attach the EnemyPrefabUpdater script to any GameObject in your scene.
Set the newMovementSpeed variable to the desired value for the movement speed property.
In the Editor, go to Tools | Update Enemy Prefabs to execute the script.
The script will iterate through all enemy prefabs in the specified folder, update the movement speed property of the EnemyMovement component, and save the changes back to the prefabs.
Overall, this script provides a convenient way to update the properties of multiple enemy prefabs in Unity Editor with a single menu command, enhancing workflow efficiency and productivity.
Mastering Unity Game Development with C# was published in July 2024. Packt library subscribers can continue reading the entire book for free or you can buy the book here!
🛠️ Useful Tools ⚒️
hoppscotch: an open-source API development tool with a minimalistic UI and extensive collaboration features, positioned as an alternative to Postman and Insomnia.
patchwork: an open-source tool that automates development tasks like PR reviews and bug fixing using a CLI agent integrated with LLMs, offering customizable prompts and predefined workflows for streamlined automation.
Shadow IT Scan: a free tool that identifies SaaS apps, users, and risky OAuth scopes in your organization for enhanced security and compliance.
That’s all for today.
We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most useful here. Complete ProgrammingPro archives can be found here. Complete PythonPro archives are here.
If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want to advertise with us.
If you have any comments or feedback, take the survey, or leave a comment below.