Game Development in Unity Wiki Article Final Draft Keaton Smith - ECE-180D-WS-2023/Knowledge-Base-Wiki GitHub Wiki

Keaton Smith March 22, 2023

Basic Game Development in Unity

Introduction:

Unity is a free, industry proven cross-platform game engine whose powerful 3d-modeling software makes game development simple. With its user-friendly editor, you can create professional looking games easily, regardless of your level of experience or genre of interest. This article will familiarize you with the Unity editor and teach you the basic skills you need to start making your own game. For more information on each section, refer to the appendix or references.

Table of Contents:

  1. Downloads
  2. Unity Editor: UI
  3. GameObjects and Components:
  4. Lighting
  5. Music
  6. User-Input
  7. Collisions
  8. Scripting
  9. Rendering
  10. References
  11. Appendix
  12. Downloads

Download Unity**, Microsoft Visual Studio or Atom, libraries for C# and Winrar to unzip files.

  1. Unity Editor UI

This section covers the basic modules within the editor including: Hierarchy Menu, Inspector, Assets, Navigating the Scene and Game Window, Pause/Play, Console and more.

  1. Hierarchy Menu

The Hierarchy window can be found on the left side of the Unity editor and contains all of the scenes and GameObjects that make up your project. GameObjects are organized into a tree structure, with parent GameObjects listed above their children. This feature makes it easy to create, delete, and rename GameObjects, or change their child-parent relationships.

Right click in the empty space to add a new scene or GameObject such as a light source, camera, or 3d shape. You can also create an Empty object and attach a script to it if you want to program some logic within the scene.

  1. Inspector

The Inspector window can be found on the right side of the Unity editor whenever you select a GameObject from the Hierarchy window or an Asset from your assets folder.

This is where you can manipulate various properties of - and add components to - your GameObject or asset. Components such as scripts and renderers can be used to manipulate the behavior or appearance of your GameObject.

  1. Assets

Go to Project > Assets as shown to see all of the assets in your project including textures, audio files, models, scripts, and prefabs. To create a new material or other asset, right click in the empty space and select your desired asset type.

  1. Scenes

Scenes are like different levels in a game. Each has its own set of GameObjects and assets. Use multiple scenes to add depth to your game and expedite its development.

To add a new scene to your project click File > New Scene. Rename the scene and save it to the Assets folder of your project by clicking File > Save Scene.

To transition from one scene to another you can use the SceneManger like so:

  1. Navigate to File > Build Settings.
  2. Click “Add Open Scenes” to add all of the scenes in your project to the build list.
  3. Specify the starting scene by clicking on it in the build list and then clicking “**Set as Start Scene.**”
  4. Transition from one scene to the scene named “EndScreen” as shown:

using UnityEngine.SceneManagement; SceneManager.LoadScene(“EndScreen”);

Scene and Game Window

The Scene and Game displays are used to develop and playtest your game. You can toggle between the two views in the top left of the window as shown below.

Game View

Scene View

The scene view is used to navigate your player environment and is where you can design prefabs and transform objects within your scene. Use the tools from the menu on the left to transform objects. To change your point of view use the orientation buttons in the upper-right or left click+drag with the hand tool.

  1. Pause and Play

To start your game, click the play button at the top-center part of the screen. The button to the right of the pause button will make the game step forward by one frame (if the game is already running and paused).

  1. Console

Select “Console” at the bottom of the Unity editor to see warnings, compiler errors and debug logs related to your scripts.

This window is highly useful for debugging purposes. To write to the console in your code use:

> Debug.Log(“Your message goes here.”);

In the above picture you can see the warning: “...Assets\Spawner.cs(19,11): …”. This gives you the particular script, line (19), and character index (11), to which the warning refers.

3. GameObjects and Components

This section will cover the basics of creating objects, materials, and prefabs with a demonstration.

In Unity Engine, GameObjects are the fundamental building blocks that comprise every object or item in a game. Initially, a GameObject is empty with only a name and a position in the scene space. However, the GameObject class is highly versatile as different components can be added that wildly change the GameObjects functionality. For example, you can add a Mesh Filter and Mesh render component, which gives the GameObject a 3D shape and renders it. From here you could assign a Material, to give the object a certain material. If you want to detect collisions with the object, you can add a box collider component. There are also components that make the object a camera or a light source or a camera or a text box. One key component that you can assign is a script. By assigning a script to the object, you can make a script that manipulates the object or even the whole scene itself. This is just a sampling of the many components you can add to GameObjects.
  1. Prefabs

Prefabs are like copies of GameObjects that you can create in your asset folder. Below you can see an example of a square target prefab with an indicator at the top.

To create this:

  1. Right click in the Hierarchy window and select 3D Object > Cube
  2. In the Inspector window change the x, y and z scale to 0.4 in the Transform component.
  3. Right click in the Assets window and select Create > Material
  4. Select the Material in the Assets window and find Main Maps in the Inspector.
  5. Find Albedo and click on the white color to change the Material’s color as shown:
  6. Create a second material but with the color orange instead of gray.
  7. Right click on the GameObject > 3D Object > Cube. This will create a child GameObject of the original cube. Repeat so that you have three total cubes (two of which are child objects of the original).
  8. Select each child cube and drag the orange material into the Inspector window.
  9. Resize the two new objects using the Transform component in the Inspector or the Transform Tool in the Scene view to recreate the above prefab. Click and drag on one of the (red or green) arrows to translate the position of the object or click and drag on one of the (red or green) squares to resize the object.
  10. Click and drag the original GameObject from the Hierarchy window into the Assets window to create a prefab automatically.
  11. Player Environment

To create a box for the player to exist in, add a new GameObject cube to your scene. Navigate to the Inspector window and increase the scale of the cube. Add a material to the cube and select Particles/Standard Surface as the shader. Finally, check the “Two Sided” box under “Main Options.” This will effectively hollow the cube to serve as your player space. The Inspector window can be seen below.

  1. Lighting

To set up your light right click in the Hierarchy window and select “Light”. Select Point Light or other source type. You can alter intensity and color among other parameters in the Inspector window as shown:

  1. Music
  2. Add your audio sample to the Assets folder via drag and drop.
  3. Right click and select Audio > Audio Source in the Hierarchy window.
  4. Drag the Audio Source to your GameObject in the Inspector window.

To play the audio source use:

using System;

public AudioSource audioSource; // in your MonoBehaviour derived class

audioSource = GameObject.Find(“AudioObject”).GetComponent(); // in void Start() {}

audioSource.Play();

6. Reading User-Input

This section will show some basic ways in which we can get user-generated data at runtime to allow players to interact with our game. Some methods include:

  • Keystrokes
  • Mouse Clicks
  • Speech Recognition

Install the new Unity input system like so:

  1. Navigate to Window > Package Manager > Packages*: In *Project > Unity Registry
  2. Scroll down until you see “Input System.”
  3. Click Input System and then click Install in the bottom right.
  4. Save your project and restart the Unity editor.

Now you can check for a user’s keyboard inputs as shown in the script below.

For more information on user-inputs refer to the Appendix or References.

  1. Collisions

Triggers are a useful way to create an interactive experience for players. They allow us to make one event trigger another. In the following example I used the passing of a moving target through a collision region to change the object’s color.

First, add a box collider component to your GameObject and click the “Is Trigger” box. Add a script component to this trigger object which will check if other objects pass through it.

Note:

  1. At least one of the two objects must have a Rigidbody component.
  2. Both objects must have a box collider component.
  3. Only the trigger box should have Is Trigger checked.

Make the box collider static in the inspector window so that it will not interact physically with other objects.

Use the following three built-in “OnTrigger” functions:

Void OnTriggerEnter (Collider other) { // you code goes here} [Runs once when the target enters] Void OnTriggerStay (Collider other) { // you code goes here} [Runs once per frame while inside] Void OnTriggerExit( Collider other) { // you code goes here} [Runs once upon target exiting]

See the Collisions section in the Appendix for an example.

  1. Scripting
  2. Scripts play a crucial role in Unity Game Development as they enable you to implement various functionalities ranging from user interfaces to core game logic. Similar to additional components for GameObjects, scripts provide a means to extend the functionality of GameObjects beyond what is offered by the default components in the Add Component menu.

    Programming with Unity is primarily done with CSharp scripts. Many students will be familiar with C++ but there are important, and useful, differences between the two languages. C# and C++ share object-oriented programing traits such as encapsulation, data hiding, inheritance, and polymorphism. The two languages differ when it comes to multiple inheritance, data type conversion, and memory management

    Differences:

    Multiple Inheritance In C#, base un-implemented classes are called interfaces. These allow you to later define abstract classes to more granularly define what you want a specific class member to do.

    Data Type Conversion C# does not allow implicit type conversion that results in loss of precision. To do this, you must explicitly convert data types.

    Memory Management C# addresses the common woe of memory management by automatically collecting garbage and freeing up resources as needed. Memory leaks are still possible however in the form of “resource leaks” caused by classes using up system resources other than memory. In this instance, controlling the destruction of such objects can be a bit painful, so make sure your code appropriately releases resource-intensive tasks.

    When you create a new script from the Add Component menu and open it in a code editor, you'll notice that the script name is accompanied by the class MonoBehaviour. This signifies that the Script component is a subclass of MonoBehaviour. MonoBehavior is a class in Unity that provides the basic functionalities and manipulations that default components can do. In addition, in a new script, there are two empty functions called Start() and Update(). The Start function is invoked once during a scene's loading and can be utilized to initialize the script variable. Update is called once per frame. Update is where you can do real-time manipulation of the game based on things such as the time, game state, or player actions.

    Countless different functionalities are provided by C#, Unity, and the Monobehavior class, but only a few useful ones will be discussed. Often in games, you need to be able to obtain and update a GameObjects position in world space. To get a GameObjects position, you can use the keyword transform.position and assign it to a new variable of type Vector3. Similarly, assigning a new position to a GameObject is done by assigning transform.position with new Vector3 with the updated coordinates. Another method is to call transform.translate() which takes a Vector3 as input. This translates the object from its current position by a number of units in each direction specified by the input.

    Sometimes during development, you need to dynamically add new or remove GameObjects to the scene based on player interactions or time. This could be spawning or killing an enemy for example. To do so from within a script, use the Instantiate() function. It takes the name of a Prefab game object, like the one discussed in the Prefab section, as an input, and makes a copy of it. There are also additional arguments that can be used to give it a new position, rotation, or parent. To delete an object, you can call the Destroy() function with the GameObject as the argument.

    Another useful scripting functionality is getting access to other GameObjects or components. To get access to a component of the GameObject the script is attached to, you can call GetComponent(). This is useful if you want to access or change an object's color, shape, or component along those lines. To get access to another GameObject in the scene, call GameObject.Find("name of object") or GameObject.FindWithTag("name of tag"). If you are accessing multiple game objects with the same tag, use GameObject.FindGameObjectWithTag(“name of tag”), which returns a list of all objects with that tag. This is useful for things like iterating through all enemies in a game to update their positions.

    A specific case of this is obtaining a script attached from one GameObject from another script. Often in a game, you might have multiple scripts running and you need to pass variables or manipulate one script from another. First, call GameObject.Find() to get the GameObject the script is attached to. From here, you then call on the GameObject (GameObject Variable).GetComponent to get the script and assign it to a type name of the script. From here you can access a variable of the other script by calling the script.(variable name).

    To create a new script, right click in the Assets window > Create > C# Script.

    Select the appropriate GameObject from the Hierarchy window and drag your script into the Inspector window.

    For example, let's try to manipulate a textbox from a script using all of the above tools. Starting off with a fresh 3D Unity project, add a Canvas game object to your scene by right-clicking the hierarchy menu and clicking UI>Canvas.

    Then we have to add a text box. To do this right click the hierarchy menu and click UI>Legacy>Text and call the game object TextDisplay.

    Next, let's add a second GameObject that's not a child of the canvas by clicking the hierarchy menu and going to Create Empty Game Object. Rename it to TextUpdater by going to the Inspector menu. If done correctly, the hierarchy menu should look like this:

    Now, create two scripts, one called counter and one called TextBox. Drag the counter into the Inspector menu or TextUpdater and TextBox into TextDisplay.

    Open the counter in your code editor, and add these lines:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class counter : MonoBehaviour
    {
      public int count=0;
      // Start is called before the first frame update
      void Start()
      {
          count=0;
      }
    
      // Update is called once per frame
      void Update()
      {
          count++;
      }
    }
    

    This script simply counts up and will be used to fill the text box.

    Next, open up TextBox in your editor. First, we need to declare our class variables. Add these lines right above the start() function:

    public Text currentText;
    public string updateText;
    public GameObject TextUpdater;
    counter updater;
    

    currentText is a variable of type Text that holds the text of our box. updateText is a string that holds what the text box should be updated to. TextUpdater is going to be the TextUpdater game object, and updater is the same type as the name of our counter script and will hold the counter script.

    Next in start(), we need to initialize our variables using GameObject.Find() and getComponent<> to locate the correct GameObjects and components:

    void Start()
    {
        //This locates  the textDisplay gameobject and gets text component
        currentText=GameObject.Find("TextDisplay").GetComponent<Text>();
        
        //This locates the textUpdater game object with the counter script and gets the counter script component
        TextUpdater=GameObject.Find("TextUpdater");
        updater=TextUpdater.GetComponent<counter>();
    
        //This initializes the text box
        currentText.text="NULL";
    
        //This sets the text to the count variable in the counter counter script
        updateText=updater.count.ToString();
    }
    

    Finally, in Update, we need to update currentText.text with the most recent value of the count variable in counter.To make it interesting, let's try to change the position of the textbox based on the value of the counter. We are going to use transform.Translate() to update the position of the TextDisplay gameObject. We have to define a Vector3 to set how far to move the object. Add these line to Update:

    void Update()
    {
        //get most recent value of count and assign it to the text of the text box
        updateText=updater.count.ToString();
        currentText.text=updateText;
        if(updater.count>100)
        {
            transform.Translate(new Vector3(10f,10f,10f));
        }
    }
    

    If everything was done correctly, when you press play in the Unity Editor you should see this:

  3. Rendering

To create an executable file follow these steps:

  1. Select the platform you want to build from the platform list under File > Build Settings.
  2. Validate the build list.
  3. Configure any build setting requirements for your specific platform and click Build.
    1. References
    2. Unity Documentation: https://docs.unity3d.com/Manual/index.html
    3. Learn Unity Tutorials: https://learn.unity.com/tutorials
    4. Unity Scripting Documentation: https://docs.unity3d.com/ScriptReference/

      How to play audio in Unity (with examples): https://gamedevbeginner.com/how-to-play-audio-in-unity-with-examples/

    5. Splash: https://docs.unity3d.com/560/Documentation/Manual/class-PlayerSettingsSplashScreen.html
    6. C# Basic Input and Output: https://www.programiz.com/csharp-programming/basic-input-output#:~:text=In%20C%23%2C%20the% 20simplest%20method,also%20included%20in%20Console%20class
    7. Speech recognition Tutorial for Unity3D 5: https://www.youtube.com/watch?v=HwT6QyOA80E
    8. Mini Unity Tutorial - How To Use TRIGGERS To Do Things: https://www.youtube.com/watch?v=CSn0hENOIT0
    9. Colliders as Triggers - Unity Official Tutorials: https://www.youtube.com/watch?v=m0fjrQkaES4 MAKING BEAT SABER IN 10 MIN - Unity Challenge: https://www.youtube.com/watch?v=gh4k0Q1Pl7E&list=PLT7FCiOIP0K0MvP9qpW-1tz3yqkOJFx2r&in dex=6
    10. Make Object Transparent in Unity 2022! | 1 Minute Tutorial: https://www.youtube.com/watch?v=KlWPedIvwuw
    11. How to Add Voice Recognition to Your Game - Unity Tutorial: https://www.youtube.com/watch?v=29vyEOgsW8s
    12. How To Use Input.GetKey in Unity's New Input System | Unity Tutorial: https://www.youtube.com/watch?v=0z-6lxL\_sS4;i>
    13. Input System Interactions Explained | Press, Hold, Tap, SlowTap, MultiTap - Unity: https://www.youtube.com/watch?v=rMlcwtoui4I
    14. Input System Action Types Explained | Value, Passthrough, Button - Unity: https://www.youtube.com/watch?v=DMUZfVSYJfs
    1. Appendix

    Downloads

    Unity: https://unity.com/download

    Microsoft Visual Studio: https://visualstudio.microsoft.com/downloads/

    Atom: https://sourceforge.net/projects/atom.mirror/

    Libraries: https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170 Winrar: https://www.win-rar.com/download.html?&L=0

    Unity Editor UI

    Inspector

    To drag assets into the inspector window for a GameObject in the Hierarchy menu, select the GameObject and toggle the lock icon in the top right of the Inspector window. You can also click Add Component to search for a specific one.

    You can click the check box on the left of certain components to toggle them on or off. You can also click the arrow to the left of each component to see and modify all parameters related to that component (e.g. in the picture above the Transform component is opened, allowing us to easily modify the position, rotation and scale of the selected GameObject).

    Scene View

    You can change the point of view by altering the orientation in the upper-right. To interact with the scene (and objects within it), use the tools on the left side of the Scene window. These tools are used primarily to select objects and alter their position, rotation, and scale (size). All of these alterations can be achieved using the Transform tool at the bottom. Hover your cursor over one of the tools to see what type of tool it is; click on it to begin using it.

    You can access all of the scenes in your project under Project > Scenes near the Assets folder at the bottom-left of the editor.

    Pause and Play

    The game is running if the play button is highlighted in blue. Pressing it again will stop the game.

    When you press play, the Scene/Game window will automatically switch to the Game window. If you want to see what is happening from a different point of view you can switch back to the Scene view while the game is running.

    GameObjects

    Duplicate GameObjects from the Hierarchy window to create variations, or delete them after you are satisfied with your prefab (you can always drag your prefab from the assets folder into the Hierarchy window to edit it later).

    Layers

    You can group GameObjects to manipulate the behaviors of different groups of objects. GameObjects in the scene can be assigned a specific layer using the following steps:

    1. Select the object you want to assign a layer to.
    2. In the Inspector window, find the Layer drop-down menu at the top.
    3. Click on the desired layer in the drop-down menu.

    Note: This can also be done within a script like this. To add a new layer to your game within the Unity editor find Edit > Project Settings > Tags and Layers and add a custom layer in the drop-down list.

    Let’s say you want your player to be able to pass through certain objects but not others. Create a custom layer for all unique GameObjects that have hard boundaries ctrl+click. Lastly add a script to the player object and make sure that collision is only set for objects in this new layer. In Unity 3d, one way to accomplish this would be to use the UnityEngine Raycasting. Here is an example script that checks if the camera is pointed at an object in the layer.

    Tags

    Similar to layers, Tags can be assigned to GameObjects to categorize objects within a scene for various scripting applications. Here is an example of how we can use Tags to delete targets in our game. Assign the Tag “targetPrefab” to the Prefab object as shown. Select an existing Tag from the drop down menu at the top, or add a custom Tag as shown below.

    Now that we have created the tag for our GameObject we can attach the following script to a box-collider to delete targets when they have passed through the collision region. The “CompareTag” checks that the “other” object has the “targetPrefab” tag assigned to it and returns true.

    (Atom code editor shown above)

    Lighting

    There are several lighting types:

    1. Directional Light: Emits light in a specific direction, simulating a distant light source like the sun.
    2. Point Light: Emits light in all directions from a single point, which is useful for lighting a scene.
    3. Spotlight: Emits light in a cone shape from a single point.
    4. Area Light: Emits light from a rectangle, simulating a large light source like a window or a projector.
    5. Reflection Probe: These are objects which act like mirrors. This can also be useful for replicating reflective surfaces such as puddles.
    6. Light Probe Group: This is a feature that allows you to effectively produce indirect lighting by capturing other scattered light.

    Sprites

    Sprites are displayed in the game world as 2-D objects. The Sprite editor gives you the ability to cut up large sprite sheets to save space and make your rendering more efficient. To do this, do the following:
    1. Select the sprite in the asset viewer menu
    2. Change the sprite mode to “Multiple”
    3. Open the sprite editor, new options should now be available to you
    4. Here you can slice the sprite into multiple sub-sprites that can be used individually. This is particularly useful for animating 2-D characters or objects.
    5. Select the appropriate slice method or manually slice the sprite as you desire

    To use the sprites in game, do the following:

    1. Create an empty GameObject in the Hierarchy window
    2. Add the built in Sprite Renderer or a custom made Sprite Renderer onto the newly created GameObject in the Inspector window
    3. Assign the sprite to the GameObject by either dragging a sprite from the Assets folder or directly assign the sprite in the serialized field of the Sprite Renderer component

User Input

User input is read via scripts. Unity supports a built-in interface that handles user input with dedicated static properties and call methods. The most common and practical properties and methods:

Input.anyKey : checks that frame if any key or mouse button is currently pressed down. Input.GetKey(“z”) : checks that frame if the “z” key is pressed down. Input.GetMouseButtonDown : returns true during the frame in which the player pressed down on the mouse button.

These are only a few of the supported input methods Unity offers. Documentation is available on the official Unity website for other more particular methods.

Custom Key Mappings

  1. Right click in the Assets window and select Create > Input Actions
  2. Give the asset a name like “Player Controls.”
  3. Double-click on Player Controls in the Assets window and add a new Action Map in the upper-left corner of the PlayerControls window by clicking the “+” icon beside Action Maps and giving it a name like “KeyMap” or “PlayerBindings” as shown.
  4. Add an action by clicking the “+” icon beside Actions and give it a name like TapAction. An Action Map is a set of controls whereas Actions are the controls themselves. Note: An Action can have multiple key bindings.
  5. Select the appropriate Action Type from the drop-down menu shown below.
  6. Specify keybinds inside the KeyMap.

Using Mouse Clicks

To delete objects within the game.

  1. Create an empty GameObject in your scene by right-clicking in the Hierarchy panel and selecting "Create Empty".
  2. Rename the empty GameObject to something descriptive, such as "DeleteTarget".
  3. Attach a Collider component to the "DeleteTarget" GameObject. This will allow it to detect mouse clicks on it. To do this, select the "DeleteTarget" GameObject in the Hierarchy panel and go to the Inspector panel. Under "Add Component", search for "Box Collider" and add it to the object.
  4. Create a new C# script and attach it to the "DeleteTarget" GameObject. To do this, right-click in the Assets panel, select "Create" > "C# Script", name it "DeleteOnClick", and drag it onto the "DeleteTarget" GameObject in the Hierarchy panel.
  5. Open the "DeleteOnClick" script in Visual Studio or your preferred code editor and paste the code I provided in the previous answer.
  6. Save the script and return to Unity. The "DeleteTarget" GameObject should now be deletable when clicked with the mouse.
  7. If you want to delete multiple objects, you can attach the script to each one or use a loop in the script to check for mouse clicks on all objects with a certain tag.

Speech Recognition

Create a dictionary for the KeywordRecognizer as shown.

Make sure to implement your actions. Below you can see I utilized the Continue and Play phrase commands to switch between scenes.

Collisions

Example of collision-event triggering:

In the picture below you can see a target object (on the left) moving towards the trigger box in gray.

A few frames later the target turns green.

When I step forward further until the target exits the triggering region, notice that the color is set back to black.

To achieve the color change functionality I added this script to the target prefab.

Remember to always provide your scripts with all necessary assets whenever they refer to GameObjects or prefabs by dragging them from the assets folder into the corresponding field in the inspector window like so:

#Asset Store

Unity features a built-in asset store where you can download powerful tools and packages to implement features not supported by vanilla Unity. To access the Asset Store, click the “Window” tab to open a drop down menu. Select Asset Store to open up the Asset Store interface. Here you can search for different Assets, whether it be prefabs or utility interfaces. Some assets must be purchased but there are alternative free versions of most asset packages. Select the “Import” button to begin downloading the required files. Packages that contain functions and scripts usually come with installation wizards to simplify the installation process. Read the documentation for each asset package to ensure correct installation and functionality.

PDF DOWNLOAD OF THIS ARTICLE WITH FORMATTED SCREENSHOTS: Basic Game Development in Unity.pdf

Basic Game Development in Unity.md

Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 024 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 025 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 026 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 027 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 028 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 029 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 030 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 031 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 032 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 001 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 002 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 003 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 004 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 005 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 006 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 007 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 008 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 009 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 010 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 011 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 012 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 013 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 014 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 015 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 016 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 017 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 018 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 019 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 020 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 021 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 022 Aspose Words 65edb1f7-055f-4c71-9702-4b6b5f8e72fe 023

⚠️ **GitHub.com Fallback** ⚠️