Blog Post

Educator Developer Blog
22 MIN READ

Making games with C# and Unity – Beginner’s Tutorial

Lee_Stott's avatar
Lee_Stott
Icon for Microsoft rankMicrosoft
Mar 21, 2019
First published on MSDN on Feb 24, 2018






Guest post by Sondre Agledahl : Games programmer, CS student and Microsoft Student Partner at UCL

Microsoft Student Partners ran an introductory workshop to game development with C# and Unity at UCL. The workshop was a great success and we covered a lot of important topics, but due to time constraints we weren’t able to finish the game we were planning to make at the event. For the benefit of attendees who wanted to complete the game in full (as well as for the many who wanted to attend but weren’t able), we’ve decided to post this web tutorial covering how to make the game from start to finish.



The game we want to make is an updated 2.5D version of the 1977 game Combat for the Atari 2600 (pictured below). Similarly to that classic, our game is a two-player top-down shooter game, where your objective is to shoot and eventually destroy your opponent’s tank.


Section 1 – Setting up our game scene


We begin by creating an empty Unity project, giving it a descriptive name (“SuperTanks” seems appropriate). Once Unity has finished loading an empty scene, import our special MSP Unity StarterPack (which you can freely download from http://bit.ly/UCLMSP18 ). You can import custom asset packs by clicking on Assets -> Import Package -> Custom Package… in Unity’s menu bar at the top of the screen.

From here, open the newly imported “Prefabs” folder and drag the Tank prefab into your scene hierarchy.



Remember to save your Unity scene with an appropriate name (“Level1”) either through File -> Save Scenes or by pressing CTRL+S (it’s a good habit to get into pressing these at frequent intervals to make sure you don’t lose any progress).

From here, we want to create the primary floor of our level mesh. Insert a plane into your scene by clicking on GameObject -> 3D Object -> Plane . Ensure your newly created plane is centred at position (0, 0, 0), which should be directly below the tank, as pictured below.



Navigate to the Materials folder and find the “GroundMat” material. Drag and drop it onto your newly created Plane object to apply a simple brown dirt texture to it.

Next, we want to resize our plane to create a play space of a similar size to that of Atari Combat. Select your Plane object in the Hierarchy and change its scale values to (12, 1, 7). For organisational purposes, let’s also rename our plane object to “Ground”.

With our new Ground object set up, we’ll position our camera so that it captures this entire play space.

Select your Main Camera object in the Hierarchy and move it so that it is above the Ground and Tank objects, facing downwards. If you’re adjusting values manually, you can set the Main Camera’s position to (0, 63, -25), and its rotation to (70, 0, 0). Your scene should look similar to that pictured below:


Next, let’s start to think about how we want our Tank to behave. Since our Tank is going to be a solid, physical object in our game, we are going to want to add both a Rigidbody and a Box Collider to it. Simply select your Tank object and click on the Add Component button at the bottom right of the screen in the Inspector view, find the Rigidbody and Box Collider components and add them.



As a simple introduction to movement and input, we’ve included a PlayerMovement script as a part of the MSP Unity starter package. Navigate to the Scripts folder and drag the PlayerMovement file onto your Tank object. Provided you’ve set up the Tank’s other components correctly, you should now find that by building and running your game (pressing the Play icon at the top middle of Unity), you can move your tank around the play space with the W-A-S-D keys.



Once you’ve had a play with moving your Tank around your scene, remember to apply your changes to the Tank prefab, so that every other Tank copy we make in the future will have the same components that we just added applied to it. (With your Tank object selected, find the Prefab options in the top of the Inspector view on the right side of the screen, and click on Apply.






















With your changes applied to the Tank prefab, you can now experiment around with inserting another tank and setting the value of Player Number (on the PlayerMovement component) to 2. The script will now respond to input from the UP-DOWN-LEFT-RIGHT arrow keys on your keyboard instead, allowing for two-player movement. (We will have a more detailed look at multiplayer integration later, so you can delete your second Tank object once you’re done testing out this basic movement.)

Section 2 – Firing missiles


One core piece of functionality we want in our game is for our Tank to be able to fire missiles – so let’s write a script that does just that. With your Tank object selected, click on Add Component in the lower right of the Inspector view, and select New Script . Name your new script appropriately (I will call mine MissileGun ) and press Create and Add . Double-click on your newly created script and it should open up in Visual Studio (or your IDE of choice).

The empty script will contain two empty functions – Start (which is called once when our object first enters the scene), and Update (which is called every single frame of the game). Since we want to fire our missiles in response to user input (which can happen at any point), we want to add our functionality into the Update function.

Before we implement our missile firing, however, let’s declare a few important variables that we’re going to need. At the top of your script, declare a public int variable called “playerNumber” (with a default value of 1), and a public GameObject variable called missilePrefab.



If you now switch back into Unity, you should find that these two variables now have become editable fields inside our MissileGun component that we can access our change from inside our Unity editor.



Now that we have a way to influence our scripts from inside Unity, go back inside the Prefabs folder and drag the Missile prefab into the empty Missile Prefab field on our Tank’s MissileGun component.

We now have access to our Missile object inside of our script, so let’s begin thinking about the conditions for shooting them. We want to spawn our missiles in response to input from the player, so let’s take a look at which buttons we have available to read from inside Unity.

Inside your Unity window, click on Edit -> Project Settings -> Input to open up Unity’s Input Manager (it should appear on the right-hand side of the screen). Here you can see a list of all the buttons that are defined in Unity by default. Notice the “Fire1” and “Fire2” buttons; we will configure these to be the button for firing missiles for our Player 1 and Player 2 respectively.



The Positive Button field for each input button denotes which keyboard key Unity checks for to determine whether the button in question was pressed. In order to make the game easiest to play for two players on a single keyboard, let’s change Positive Button for the “Fire2” button to “right ctrl”.

With this simple change applied, go back into Visual Studio (or your IDE of choice). We want to spawn our missile in response to the player pressing either the “Fire1” or “Fire2” buttons, so we will make the following changes to our Update function:



Here we’re making use of Unity’s handy Instantiate function, which takes in a GameObject reference, a position and a rotation value as parameters, and inserts that GameObject into our scene. Since we want to spawn our missile prefab, we pass in our missilePrefab variable as the first argument. The transform.position and transform.rotation variables refer to the current position and rotation of our Tank object, so we pass those in as well.

The Input.GetButtonDown function takes in the name of a Unity button and returns true if the user pressed that button during the current frame. By concatenating the string “Fire” with our playerNumber variable, we make Unity check for either “Fire1” (the left CTRL key) or “Fire2” (the right CTRL key) depending on what whether we’ve set playerNumber to 1 or 2.

Go back into Unity and press the Play button to play around with the current state of our game.



You should find that you can now spawn a trail of missiles in your Tank’s path with repeated presses of the CTRL key. Not exactly the behaviour we were going for, but we’re getting closer.

Let’s start moving closer to what we want by editing our Missile prefab. Drag the prefab from inside the Prefabs folder into your scene to create a new Missile instance. Just like our Tank, we want our missiles to be affected by Unity’s physics engine, so let’s add a Rigidbody component to our Missile instance.

We also want our missiles to collide with other objects in our scene, so let’s add a Capsule Collider component to it as well. You may find that Unity’s default size and position for this Capsule Collider don’t exactly match the shape of the missile, so edit the properties of this component until they do. (My settings are Center: (0, 0, 0), Radius: 0.3, Height: 2.5 and Direction: Z-axis).



Remember to Apply your changes to the Missile prefab when you’re done editing its components!

With these changes applied, you can do some more playtesting. You may notice that after making our missiles into physical, collidable objects, they cause our Tank to twirl around and bounce up and down around the scene. We’ll want to make a few adjustments to make sure this doesn’t happen.

Select your Tank object and find its Rigidbody component. Under the Constraints option, tick the boxes for Freeze Rotation in X and Z. This will ensure that our Tank only rotates around the Y-axis (which is what we want it do in response to user input).

Next, let’s make a few adjustments so that our missiles spawn from a position just in front of the tank’s cannon instead of in the middle of it.

Right click on your Tank object in the Hierarchy view and select Create Empty . This will insert an empty GameObject into your scene that is “childed” to the Tank – which means that its position and rotation will always be relative to that of the Tank (so that when the Tank moves around the scene, this child object will move alongside it).

Rename this empty GameObject with an appropriate name (such as “Fire Transform”), and move it to a location in front of the Tank where you want missiles to spawn from (I’ve set mine to position (0, 2, 5)).

From here, let’s get hold of a reference to our new Fire Transform object from inside our MissileGun script. Open your script again and declare a new public variable of type Transform called “fireTransform”.


Just as before, if you now go back into Unity, you will find that a new empty field ( Fire Transform ) should appear in your Tank’s MissileGun component. Take our newly created Fire Transform object and drag it into this empty field.



Back inside our MissileGun script, let’s change our call to Instantiate so that our missiles are spawned at the position of our Fire Transform object rather than our tank’s position:



Again, remember to apply your changes to the Tank prefab! If you now have a play with the game, you will see that our missiles behave much closer to how we want them to.

The astute reader will still notice that our missiles aren’t flying off into the air the way we would expect them to. Let’s change that by applying a force to them right after they’ve been spawned.

Let’s start by declaring another public float variable that defines the magnitude of the force we’ll be applying at the top of our script (I’ve set mine to a default value of 2000):



Now we can apply this force to our missiles in the following way:



Here we’re temporarily storing a reference to our newly spawned missile object inside the missile variable, then using the GetComponent function to retrieve its Rigidbody component. Finally, we call Unity’s AddForce function on the missile’s Rigidbody.

Because a force has both magnitude and direction, we have to pass in a vector object into this function. The handy transform.forward variable always contains a unit vector that points in our Tank’s “forward” direction, which is the direction we want our missiles to move in. We scale this vector with our fireForce variable in order to fire them off with the appropriate magnitude.

Test your game to confirm that your missiles are now finally blasting off into the air in a semi-realistic fashion.



As a final touch to our missile-firing functionality, let’s add a sound effect to play when our missiles spawn. Find your Missile prefab again and add an Audio Source component to it. Navigate to the Sounds folder, and drag the Fire.mp3 file into the empty AudioClip field on the Audio Source component.


Section 3 – Explosion Physics


We now have some satisfying missile-firing mechanics going, but our missiles are still just colliding against the floor and grinding to a halt like any other object when they fall. We would much prefer to have them explode instead.

If you’ve had a peek in the Prefabs folder, you will see that you’ve already been provided with an Explosion prefab. This prefab contains a collection of flashy-looking particle effects that we’ll want to spawn when our missiles collide with something.

On your Missile prefab, create and add a new script with an appropriate name for what we’re about to do (such as “MissileExplosion”), and open it up in your IDE. Just as we’ve done before, let’s declare a public GameObject variable at the top of our script to hold a reference to our Explosion prefab.



Drag the Explosion prefab into the field that corresponds to this new variable.



Now let’s Instantiate a copy of this Explosion prefab every time our Missile collides with something. We’re going to accomplish this using the Unity function OnCollisionEnter , which will be automatically called on any object with a Collider component the moment it collides against another object.

Inside your MissileExplosion script, simply start typing OnCollisionEnter , and Visual Studio should automatically give you the appropriate auto-complete option for the function we’re looking for (just hit TAB or RETURN on your keyboard to confirm your choice). If for whatever reason your IDE doesn’t provide you with this auto-complete help, just copy the function definition below into your MissileExplosion script:



Now, inside the OnCollisionEnter function, we want to spawn our Explosion prefab, and then remove our missile from our scene. We’ll accomplish this by adding the following lines to the function:



Like earlier, we’re Instantiating our explosionPrefab at our current position. The variable Quaternion.identity , though cryptic-looking, simply means that our explosion will spawn with no rotation applied to it. (We prefer not to pass in our Missile’s rotation here, as that would spawn our explosion effect rotated at weird angles depending on the orientation of our Missile.)

Once our explosion has spawned, we remove our missile from the scene by calling the aptly named Destroy function, passing in the gameObject variable, which holds a reference to the object this script is attached to (our Missile, in this case).

You can give your game another test-run now to confirm that our explosion effects are spawning as expected.



From here let’s back up our newly added explosion effects with some actual physics. After we’ve spawned our explosion prefab, we want to apply an appropriate explosion force to all objects that happen to be close by.

We can accomplish this with another convenient built-in function called Physics.OverlapSphere . This function will create a virtual sphere around any point in space and return a list of all the Collider components that fall inside its radius.

To implement this, let’s start by declaring one float variable to define the radius of our explosion (I’ve set mine to a default value of 5), and another to define the magnitude of the explosion force we want to apply to all surrounding objects (which I’ve set to a default value of 1000).



Next, we’ll insert a call to Physics.OverlapSphere right after we’ve spawned our explosion effects, passing in the current position of our missile and the radius we want our explosion to have:



From here, let’s go through each of the Collider components that were inside the virtual sphere (using a foreach loop) and apply an explosion force to them using the Unity function AddExplosionForce . Recall that in order to add a force to an object, we need to first get its Rigidbody component, so let’s do the following:



Here we temporarily store each object’s Rigidbody component inside the targetBody variable. We also have to make sure the object we’re trying to push actually has a Rigidbody component attached – this is why we insert the check for targetBody == null and continue to the next iteration of the loop if no Rigidbody was found.

The AddExplosionForce function takes in a value for the magnitude of our explosion force, as well as the position and desired radius of our explosion. From there, Unity will automatically calculate the appropriate force to apply to the object depending on how far away from the centre of the explosion it is.

If you’ve made it this far, congratulate yourself by giving your game another test-run. You can now insert another Tank prefab into your scene (remember to set the value of Player Number on the PlayerMovement and the MissileGun components to 2 for this second Tank!) and test that the explosion physics are working as they should. In its current state, you already have a rather enjoyable game of king-of-the-hill, as you can push your fellow Player off of the play space with a well-placed missile.



As a final touch to our explosion mechanics, let’s add another sound effect to play when our missiles explode. Find your Explosion prefab and add an Audio Source component to it. Inside the Sounds folder, find the Explosion.mp3 file and drag it into the empty AudioClip field.

Section 4 – Setting up a win condition


Our current physics simulation is good fun, but doesn’t exactly resemble Atari Combat in its mechanics. Let’s set up a health system for keeping track of how many times each Tank has been hit, and for ending the game when one Tank has taken too many hits in a row.

Select either your Tank prefab or one of your Tank objects in the scene (if you’re editing a Tank instance, remember to apply your changes to the prefab when you’re done!), and create a new script. (I’ll call mine simply “Health”). Open your new script in your IDE.

To start with, declare a public int variable to determine how much health a Tank has at the beginning of the game (I’ve set mine to a default value of 5). From here, we’ll declare another private int to keep track of how much health our tank currently has at any given point in the game.



Inside the Start function (which you’ll recall is called by Unity on every script when that object first enters the scene), we’ll set currentHealth to the value of startHealth , so that our Tanks start out with a maximum health value when the game begins.



From there we’ll want to set up a way for other components to interact with our Health script to make our tanks lose health. We can accomplish this by creating a new public function that decrements the value of currentHealth every time it’s called:



We can now call this new TakeDamage function from anywhere in order to decrease the health of one of our Tanks.

Of course, we’ll want to have a mechanism in place to end the game once one of our Tanks’ health drops to zero. Let’s create another simple Die function that we call whenever this happens. Inside Die , we can simply destroy our Tank’s GameObject for the time being to indicate that the game is over.



We now have features in place to make our Tanks take damage, but we’re not actually using them anywhere. We want our Tanks to take damage whenever they are hit by a Missile’s explosion, so let’s return to our MissileExplosion script and add this extra functionality.

Inside of MissileExplosion ’s OnCollisionEnter function, we’re already going through every object that is within range of our explosion, so let’s insert another few lines here to apply damage to any object in range that also has a Health component:



Notice that we can use Unity’s GetComponent function to access even our own user-defined components, such as Health. Just as we did before applying forces to nearby Rigidbodies, we also have to make sure to check whether or not the object we’re looking at actually has a Health component before we call the TakeDamage function.

We now have a suitable win condition in place! You may find it a bit difficult to kill your fellow player without knocking them off the playing field first, however. Let’s sort that out by adding some walls around our play space.

You can add walls by simply inserting a few cubes into your scene ( GameObject -> 3D Object -> Cube from the menu at the top of Unity), resizing, rotating and moving them to the edge of the play space accordingly. If you navigate to the Materials folder, you can find the WallMat , which you can drag and drop onto your Cubes to give them a rusty metal look.

I set up my level’s walls in the following way: After inserting a Cube and applying the WallMat to it, I scaled it to (5, 5, 75) and moved it to the left edge of the play space. I then duplicated the cube (right click on it in the Hierarchy and select Duplicate ) and moved the copy to the right edge. I then made another duplicate, set its scale to (5, 5, 125) rotated it 90 degrees in Y and moved it to the top edge. Finally, I duplicated this wall one last time and moved it to the bottom edge.



Now that we have all of the components we want on our Tanks in place, let’s also apply a different Material to our second Tank so they are clearly differentiated. With your second tank selected in the Hierarchy, find its Mesh Renderer component and expand the Materials array option. Inside the Materials folder, find Player2Mat and drag it into the first element of the second Tank’s Materials array.




Section 5 – User Interface


The only thing that remains for us to do to recreate Atari Combat in modern form is to display each player’s current score on some sort of on-screen HUD. We’ll accomplish this using a UI Text element.

Insert a UI Text object by clicking on GameObject -> UI -> Text . You’ll notice that doing this inserted not only a new object called Text into your scene, but also a Canvas and an EventSystem . If you double-click on the Canvas object in the Hierarchy to zoom in on it, you may be startled to find that it is actually a giant rectangle that sits somewhere far removed from the rest of our level. As it turns out, there is a natural explanation for this.



The Canvas object, which is the parent object of all UI objects in Unity, actually exists in a different “space” from all of our other objects. Our Tanks, walls, Ground and Missiles exist in what’s known as “World Space” – the virtual 3D coordinate system of our game. The Canvas and all the objects childed to it, meanwhile, exist in 2D “Screen Space”. Screen Space coordinates are determined by the size of the player’s screen, and objects that use it will by default always render on top of all other objects.

To start with, select your newly created Text object and edit its Text component. Select the Color property and set it to white.



You can now confirm that the Text object does in fact appear on top of everything else by switching to Game View (or by pressing the Play button and running the game).



Let’s make some more changes to our Text object. Select Unity’s UI Editing tool in the top left-hand side of Unity (or by pressing the T key on your keyboard).



Using this tool, move the Text object to the top left of the Canvas. Rename this object to “Player 1 Score”. From here, find its Text component again and set its Font Style to Bold , and its Font Size to 26. Fill in the Text field with placeholder numbers to represent Player 1’s score (I’ll just use “999999999”).

Duplicate this Player 1 Score object and rename it “Player 2 Score”. Move Player 2 Score to the top right corner of the Canvas, and edit its Alignment property to be right-aligned . You should end up with a Canvas that looks like the following:



With that, we have an on-screen HUD in place for displaying our players’ scores. Of course, our text elements are still completely static and will not change during play. Let’s do something about that.

Select your Canvas object in the Hierarchy and add a new script to it with a descriptive name (I’ll call mine “ScoreManager”). Open it up in your IDE.

As we saw when editing our Text objects, the component responsible for what text to display on the screen was the aptly named Text component, so these are the components we want to be editing inside our script. Unfortunately, Unity doesn’t grant us access to these components by default, so we’ll have to include the following line at the very top of our ScoreManager script:



This using line will import all of the components associated with UI. Having addressed that, let’s start our script by declaring two public variables of type Text (I will call mine “player1ScoreText” and “player2ScoreText”).



Similar to what we’ve done before, populate these new public variables by dragging the Player 1 Score and Player 2 Score objects into the corresponding empty fields on the Canvas in Unity.



We can now edit what text to display inside our Text objects anywhere we want inside our script. Let’s start by setting both of them to display “0” when inside our ScoreManager ’s Start function:



Notice that in order to change the text that displays on each Text component, we have to assign a different string to its text property. (The term “text” has been heavily overloaded here, so if you’re confused, just take care to copy the above two lines carefully until you get the desired effect.)

If we now Play our game, we’ll see that our Text objects indeed start off by displaying “0” when the game runs.



All that remains now is for us to change what these elements display in response to a Tank getting hit by a missile. In order to accomplish that, we’ll have to declare another two private int variables to keep track of each player’s score. We’ll set both of these to a default value of 0 to represent each of our players’ score at the start of the game.



From here, let’s think about how we would want outside components to interact with our ScoreManager to increase a player’s score. A player’s score should go up if they managed to hit their fellow player with a well-placed missile. The easiest way for us to detect when this has happened would be inside our Health script whenever the TakeDamage function is called.

With this in mind, let’s create a public function inside our ScoreManager script that takes in the number of the player that just took damage and increments the value of the other player’s score. (I’m going to call this function “OnPlayerDamaged”.)



Finally, we want to make sure we’re updating our Text elements to display each player’s new score as soon as it changes:



Note that the text property expects to be assigned a string value, which is why we have to apply the ToString function to the player1Score and player2Score variables before we assign them to the Text elements.

All we have to do now is insert a call to this new function inside our Health script. Before we do that, however, we need to declare another public int variable inside of Health so we can keep track of which player took damage.



We’re also going to need a way to access our ScoreManager script from inside of Health. We can do this in the same way that we did before, by declaring a public ScoreManager variable and simply dragging it into the empty field.

This time, however, because we know that there will only be one ScoreManager in our scene at any time, we can make use of another handy Unity function instead – FindObjectOfType :



The FindObjectOfType function will search through our current scene and return the first object it finds of a certain type, which is why it’s enough for us to declare a private ScoreManager variable to hold the reference we need.

Finally, let’s insert the appropriate call to OnPlayerDamaged inside of our Health script’s TakeDamage function:



And with that – congratulations! You now have a fully working version of Atari Combat, updated for the modern era. Make sure to playtest your game to make sure everything is working as it should. (Remember to set the correct Player Number value for each Tank’s PlayerMovement, MissileGun and Health component respectively.)

It’s now up to you how you want to design your level. Personally, I will do my best to recreate the classic design of the Combat level pictured at the beginning of this tutorial by moving and shaping a set of cubes:


Conclusion


Thank you for sticking through with this tutorial until the end and for persevering through with making a complete game! Whether or not you made it out to our workshop in person or not, I hope you’ve picked up on a number of key concepts about making games in Unity and C#.

Feel free to take a look at the source code for the completed game at https://github.com/colonelsalt/SuperTanks if you want to compare your implementation to mine.

If you’re looking to improve or expand upon the game from here, there are certainly many directions you could take it. Let me offer a few suggestions off the top of my head:

· You’ll notice we have a couple of unused sound effects inside our Sounds folder. Can you think of a suitable place to insert these in the game? What actions should trigger them to start or stop playing?

· Is it really fair that a player can damage him- or herself with their own missile and give their opponent points? What changes could you implement to make sure that only an opponent’s missile can damage a given Tank?

· Typically games will have some functionality in place to prevent a player from taking damage too quickly in a row by making them invincible for a second or two after they take damage – how could you go about implementing this?

· What if we want to play another round immediately without closing down our game and re-opening it? What mechanisms would have to be in place, and which variables would have to be reset in order for a “Play Again” button to work as expected?

Project asset credits:

· Low-Poly Tank Assets by PixelMannen: https://opengameart.org/content/low-poly-tank-assets

· Small Explosives Pack by mrpoly: https://opengameart.org/content/small-explosives-pack

· Short Explosion 1 by ProjectsU012: https://freesound.org/people/ProjectsU012/sounds/334266/

· Gun, pistol, single shot silenced, Walther pp7 by John J: https://www.zapsplat.com/music/gun-pistol-single-shot-silenced-walther-pp7/

· Tada Fanfare A by plasterbrain: https://freesound.org/people/plasterbrain/sounds/397355/

· Combat Plan by PlayOnLoop.com: https://www.playonloop.com/2018-music-loops/combat-plan/

· Seamless Ground Textures by TutorialsForBlender: http://www.tutorialsforblender3d.com/Ground/Page2

· Metal Rusty and Patterned by maxTextures: http://www.mb3d.co.uk/mb3d/Metal_Rusty_and_Patterned_Seamless_and_Tileable_High_Res_Textures.html
Updated Mar 21, 2019
Version 2.0
No CommentsBe the first to comment
"}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCoverImage\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCoverImage-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeTitle\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTimeToRead\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeDescription\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/Pager/PagerLoadMore\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505309992"}],"cachedText({\"lastModified\":\"1745505309992\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505309992"}]},"CachedAsset:pages-1745160780925":{"__typename":"CachedAsset","id":"pages-1745160780925","value":[{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745160780925,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":"en","possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","entityType":"CATEGORY","displayId":"EducationSector","nodeType":"category","depth":3,"title":"Education Sector","shortTitle":"Education Sector","parent":{"__ref":"Category:category:solutions"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top","entityType":"CATEGORY","shortTitle":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities","entityType":"CATEGORY","shortTitle":"Communities"},"Category:category:solutions":{"__typename":"Category","id":"category:solutions","displayId":"solutions","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Topics","entityType":"CATEGORY","shortTitle":"Topics"},"Blog:board:EducatorDeveloperBlog":{"__typename":"Blog","id":"board:EducatorDeveloperBlog","entityType":"BLOG","displayId":"EducatorDeveloperBlog","nodeType":"board","depth":4,"conversationStyle":"BLOG","title":"Educator Developer Blog","description":"","avatar":null,"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:EducationSector"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:solutions"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:EducationSector"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}},"shortTitle":"Educator Developer Blog","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"REVERSE_PUBLISH_TIME","repliesFormat":"threaded"},"tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":false,"tagType":"FREEFORM_ONLY"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc","height":512,"width":512,"mimeType":"image/png"},"Rank:rank:4":{"__typename":"Rank","id":"rank:4","position":6,"name":"Microsoft","color":"333333","icon":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}"},"rankStyle":"OUTLINE"},"User:user:210546":{"__typename":"User","id":"user:210546","uid":210546,"login":"Lee_Stott","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0yMTA1NDYtODM5MjVpMDI2ODNGQTMwMzAwNDFGQQ"},"rank":{"__ref":"Rank:rank:4"},"email":"","messagesCount":380,"biography":null,"topicsCount":349,"kudosReceivedCount":433,"kudosGivenCount":13,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2018-09-25T06:34:59.520-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":0},"BlogTopicMessage:message:380346":{"__typename":"BlogTopicMessage","uid":380346,"subject":"Making games with C# and Unity – Beginner’s Tutorial","id":"message:380346","revisionNum":2,"repliesCount":0,"author":{"__ref":"User:user:210546"},"depth":0,"hasGivenKudo":false,"board":{"__ref":"Blog:board:EducatorDeveloperBlog"},"conversation":{"__ref":"Conversation:conversation:380346"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:380346"},"teaser":"First published on MSDN on Feb 24, 2018  Guest post by Sondre Agledahl: Games programmer, CS student and Microsoft Student Partner at UCLMicrosoft Student Partners ran an introductory workshop to game development with C# and Unity at UCL.","body":"\n \n \n First published on MSDN on Feb 24, 2018\n \n
\n
\n
\n \n
\n
\n \n
\n
\n Guest post by\n \n Sondre Agledahl\n \n : Games programmer, CS student and Microsoft Student Partner at UCL\n
\n
\n Microsoft Student Partners ran an introductory workshop to game development with C# and Unity at UCL. The workshop was a great success and we covered a lot of important topics, but due to time constraints we weren’t able to finish the game we were planning to make at the event. For the benefit of attendees who wanted to complete the game in full (as well as for the many who wanted to attend but weren’t able), we’ve decided to post this web tutorial covering how to make the game from start to finish.\n
\n
\n \n
\n
\n The game we want to make is an updated 2.5D version of the 1977 game Combat for the Atari 2600 (pictured below). Similarly to that classic, our game is a two-player top-down shooter game, where your objective is to shoot and eventually destroy your opponent’s tank.\n
\n
\n \n
\n

\n Section 1 – Setting up our game scene\n

\n
\n We begin by creating an empty Unity project, giving it a descriptive name (“SuperTanks” seems appropriate). Once Unity has finished loading an empty scene, import our special MSP Unity StarterPack (which you can freely download from\n \n http://bit.ly/UCLMSP18\n \n ). You can import custom asset packs by clicking on\n \n Assets -> Import Package -> Custom Package…\n \n in Unity’s menu bar at the top of the screen.\n
\n
\n From here, open the newly imported “Prefabs” folder and drag the\n \n Tank\n \n prefab into your scene hierarchy.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n
\n \n \n
\n \n \n
\n
\n
\n
\n Remember to save your Unity scene with an appropriate name (“Level1”) either through\n \n File -> Save Scenes\n \n or by pressing CTRL+S (it’s a good habit to get into pressing these at frequent intervals to make sure you don’t lose any progress).\n
\n
\n From here, we want to create the primary floor of our level mesh. Insert a plane into your scene by clicking on\n \n GameObject -> 3D Object -> Plane\n \n . Ensure your newly created plane is centred at position (0, 0, 0), which should be directly below the tank, as pictured below.\n
\n
\n \n
\n
\n Navigate to the\n \n Materials\n \n folder and find the “GroundMat” material. Drag and drop it onto your newly created Plane object to apply a simple brown dirt texture to it.\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n
\n \n \n \n \n
\n \n \n \n
\n
\n
\n Next, we want to resize our plane to create a play space of a similar size to that of Atari Combat. Select your Plane object in the Hierarchy and change its scale values to (12, 1, 7). For organisational purposes, let’s also rename our plane object to “Ground”.\n
\n
\n With our new Ground object set up, we’ll position our camera so that it captures this entire play space.\n
\n
\n Select your\n \n Main Camera\n \n object in the Hierarchy and move it so that it is above the Ground and Tank objects, facing downwards. If you’re adjusting values manually, you can set the Main Camera’s position to (0, 63, -25), and its rotation to (70, 0, 0). Your scene should look similar to that pictured below:\n
\n
\n \n
\n Next, let’s start to think about how we want our Tank to behave. Since our Tank is going to be a solid, physical object in our game, we are going to want to add both a\n \n Rigidbody\n \n and a\n \n Box Collider\n \n to it. Simply select your Tank object and click on the\n \n Add Component\n \n button at the bottom right of the screen in the Inspector view, find the\n \n Rigidbody\n \n and\n \n Box Collider\n \n components and add them.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n
\n \n \n \n
\n
\n
\n As a simple introduction to movement and input, we’ve included a\n \n PlayerMovement\n \n script as a part of the MSP Unity starter package. Navigate to the\n \n Scripts\n \n folder and drag the\n \n PlayerMovement\n \n file onto your Tank object. Provided you’ve set up the Tank’s other components correctly, you should now find that by building and running your game (pressing the\n \n Play\n \n icon at the top middle of Unity), you can move your tank around the play space with the W-A-S-D keys.\n
\n
\n \n
\n
\n Once you’ve had a play with moving your Tank around your scene, remember to apply your changes to the\n \n Tank\n \n prefab, so that every other Tank copy we make in the future will have the same components that we just added applied to it. (With your Tank object selected, find the Prefab options in the top of the Inspector view on the right side of the screen, and click on Apply.\n
\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n With your changes applied to the Tank prefab, you can now experiment around with inserting another tank and setting the value of\n \n Player Number\n \n (on the\n \n PlayerMovement\n \n component) to 2. The script will now respond to input from the UP-DOWN-LEFT-RIGHT arrow keys on your keyboard instead, allowing for two-player movement. (We will have a more detailed look at multiplayer integration later, so you can delete your second Tank object once you’re done testing out this basic movement.)\n
\n

\n Section 2 – Firing missiles\n

\n
\n One core piece of functionality we want in our game is for our Tank to be able to fire missiles – so let’s write a script that does just that. With your Tank object selected, click on\n \n Add Component\n \n in the lower right of the Inspector view, and select\n \n New Script\n \n . Name your new script appropriately (I will call mine\n \n MissileGun\n \n ) and press\n \n Create and Add\n \n . Double-click on your newly created script and it should open up in Visual Studio (or your IDE of choice).\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n
\n \n \n \n \n \n
\n
\n
\n The empty script will contain two empty functions –\n \n Start\n \n (which is called once when our object first enters the scene), and\n \n Update\n \n (which is called every single frame of the game). Since we want to fire our missiles in response to user input (which can happen at any point), we want to add our functionality into the\n \n Update\n \n function.\n
\n
\n Before we implement our missile firing, however, let’s declare a few important variables that we’re going to need. At the top of your script, declare a public\n \n int\n \n variable called “playerNumber” (with a default value of 1), and a public\n \n GameObject\n \n variable called\n \n missilePrefab.\n \n
\n
\n \n
\n
\n If you now switch back into Unity, you should find that these two variables now have become editable fields inside our\n \n MissileGun\n \n component that we can access our change from inside our Unity editor.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n \n
\n \n \n \n
\n
\n
\n
\n Now that we have a way to influence our scripts from inside Unity, go back inside the\n \n Prefabs\n \n folder and drag the\n \n Missile\n \n prefab into the empty\n \n Missile Prefab\n \n field on our Tank’s MissileGun component.\n
\n
\n We now have access to our\n \n Missile\n \n object inside of our script, so let’s begin thinking about the conditions for shooting them. We want to spawn our missiles in response to input from the player, so let’s take a look at which buttons we have available to read from inside Unity.\n
\n
\n Inside your Unity window, click on\n \n Edit -> Project Settings -> Input\n \n to open up Unity’s Input Manager (it should appear on the right-hand side of the screen). Here you can see a list of all the buttons that are defined in Unity by default. Notice the “Fire1” and “Fire2” buttons; we will configure these to be the button for firing missiles for our Player 1 and Player 2 respectively.\n
\n
\n \n
\n
\n The\n \n Positive Button\n \n field for each input button denotes which keyboard key Unity checks for to determine whether the button in question was pressed. In order to make the game easiest to play for two players on a single keyboard, let’s change\n \n Positive Button\n \n for the “Fire2” button to “right ctrl”.\n
\n
\n With this simple change applied, go back into Visual Studio (or your IDE of choice). We want to spawn our missile in response to the player pressing either the “Fire1” or “Fire2” buttons, so we will make the following changes to our\n \n Update\n \n function:\n
\n
\n \n
\n
\n Here we’re making use of Unity’s handy\n \n Instantiate\n \n function, which takes in a\n \n GameObject\n \n reference, a position and a rotation value as parameters, and inserts that GameObject into our scene. Since we want to spawn our missile prefab, we pass in our\n \n missilePrefab\n \n variable as the first argument. The\n \n transform.position\n \n and\n \n transform.rotation\n \n variables refer to the current position and rotation of our Tank object, so we pass those in as well.\n
\n
\n The\n \n Input.GetButtonDown\n \n function takes in the name of a Unity button and returns true if the user pressed that button during the current frame. By concatenating the string “Fire” with our\n \n playerNumber\n \n variable, we make Unity check for either “Fire1” (the left CTRL key) or “Fire2” (the right CTRL key) depending on what whether we’ve set\n \n playerNumber\n \n to 1 or 2.\n
\n
\n Go back into Unity and press the Play button to play around with the current state of our game.\n
\n
\n \n
\n
\n You should find that you can now spawn a trail of missiles in your Tank’s path with repeated presses of the CTRL key. Not exactly the behaviour we were going for, but we’re getting closer.\n
\n
\n Let’s start moving closer to what we want by editing our\n \n Missile\n \n prefab. Drag the prefab from inside the Prefabs folder into your scene to create a new\n \n Missile\n \n instance. Just like our Tank, we want our missiles to be affected by Unity’s physics engine, so let’s add a\n \n Rigidbody\n \n component to our Missile instance.\n
\n
\n We also want our missiles to collide with other objects in our scene, so let’s add a\n \n Capsule Collider\n \n component to it as well. You may find that Unity’s default size and position for this Capsule Collider don’t exactly match the shape of the missile, so edit the properties of this component until they do. (My settings are Center: (0, 0, 0), Radius: 0.3, Height: 2.5 and Direction: Z-axis).\n
\n
\n \n
\n
\n Remember to\n \n Apply\n \n your changes to the Missile prefab when you’re done editing its components!\n
\n
\n With these changes applied, you can do some more playtesting. You may notice that after making our missiles into physical, collidable objects, they cause our Tank to twirl around and bounce up and down around the scene. We’ll want to make a few adjustments to make sure this doesn’t happen.\n
\n \n \n \n \n \n \n \n \n
\n
\n \n \n
\n
\n Select your Tank object and find its\n \n Rigidbody\n \n component. Under the\n \n Constraints\n \n option, tick the boxes for\n \n Freeze Rotation\n \n in X and Z. This will ensure that our Tank only rotates around the Y-axis (which is what we want it do in response to user input).\n
\n
\n Next, let’s make a few adjustments so that our missiles spawn from a position just in front of the tank’s cannon instead of in the middle of it.\n
\n
\n Right click on your Tank object in the Hierarchy view and select\n \n Create Empty\n \n . This will insert an empty\n \n GameObject\n \n into your scene that is “childed” to the Tank – which means that its position and rotation will always be relative to that of the Tank (so that when the Tank moves around the scene, this child object will move alongside it).\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n \n
\n \n \n \n
\n \n \n
\n
\n
\n
\n Rename this empty GameObject with an appropriate name (such as “Fire Transform”), and move it to a location in front of the Tank where you want missiles to spawn from (I’ve set mine to position (0, 2, 5)).\n
\n
\n From here, let’s get hold of a reference to our new\n \n Fire Transform\n \n object from inside our\n \n MissileGun\n \n script. Open your script again and declare a new public variable of type\n \n Transform\n \n called “fireTransform”.\n
\n
\n \n
\n Just as before, if you now go back into Unity, you will find that a new empty field (\n \n Fire Transform\n \n ) should appear in your Tank’s\n \n MissileGun\n \n component. Take our newly created Fire Transform object and drag it into this empty field.\n
\n
\n \n
\n
\n Back inside our\n \n MissileGun\n \n script, let’s change our call to\n \n Instantiate\n \n so that our missiles are spawned at the position of our\n \n Fire Transform\n \n object rather than our tank’s position:\n
\n
\n \n
\n
\n Again, remember to apply your changes to the Tank prefab! If you now have a play with the game, you will see that our missiles behave much closer to how we want them to.\n
\n
\n The astute reader will still notice that our missiles aren’t flying off into the air the way we would expect them to. Let’s change that by applying a force to them right after they’ve been spawned.\n
\n
\n Let’s start by declaring another public\n \n float\n \n variable that defines the magnitude of the force we’ll be applying at the top of our script (I’ve set mine to a default value of 2000):\n
\n
\n \n
\n
\n Now we can apply this force to our missiles in the following way:\n
\n
\n \n
\n
\n Here we’re temporarily storing a reference to our newly spawned missile object inside the\n \n missile\n \n variable, then using the\n \n GetComponent\n \n function to retrieve its Rigidbody component. Finally, we call Unity’s\n \n AddForce\n \n function on the missile’s Rigidbody.\n
\n
\n Because a force has both magnitude and direction, we have to pass in a vector object into this function. The handy\n \n transform.forward\n \n variable always contains a unit vector that points in our Tank’s “forward” direction, which is the direction we want our missiles to move in. We scale this vector with our\n \n fireForce\n \n variable in order to fire them off with the appropriate magnitude.\n
\n
\n Test your game to confirm that your missiles are now finally blasting off into the air in a semi-realistic fashion.\n
\n
\n \n
\n
\n As a final touch to our missile-firing functionality, let’s add a sound effect to play when our missiles spawn. Find your\n \n Missile\n \n prefab again and add an\n \n Audio Source\n \n component to it. Navigate to the\n \n Sounds\n \n folder, and drag the\n \n Fire.mp3\n \n file into the empty\n \n AudioClip\n \n field on the\n \n Audio Source\n \n component.\n
\n
\n \n
\n

\n Section 3 – Explosion Physics\n

\n
\n We now have some satisfying missile-firing mechanics going, but our missiles are still just colliding against the floor and grinding to a halt like any other object when they fall. We would much prefer to have them explode instead.\n
\n
\n If you’ve had a peek in the Prefabs folder, you will see that you’ve already been provided with an\n \n Explosion\n \n prefab. This prefab contains a collection of flashy-looking particle effects that we’ll want to spawn when our missiles collide with something.\n
\n
\n On your\n \n Missile\n \n prefab, create and add a new script with an appropriate name for what we’re about to do (such as “MissileExplosion”), and open it up in your IDE. Just as we’ve done before, let’s declare a public\n \n GameObject\n \n variable at the top of our script to hold a reference to our Explosion prefab.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n \n
\n \n \n
\n
\n
\n
\n Drag the\n \n Explosion\n \n prefab into the field that corresponds to this new variable.\n
\n
\n \n
\n
\n Now let’s Instantiate a copy of this Explosion prefab every time our Missile collides with something. We’re going to accomplish this using the Unity function\n \n OnCollisionEnter\n \n , which will be automatically called on any object with a Collider component the moment it collides against another object.\n
\n
\n Inside your\n \n MissileExplosion\n \n script, simply start typing\n \n OnCollisionEnter\n \n , and Visual Studio should automatically give you the appropriate auto-complete option for the function we’re looking for (just hit TAB or RETURN on your keyboard to confirm your choice). If for whatever reason your IDE doesn’t provide you with this auto-complete help, just copy the function definition below into your\n \n MissileExplosion\n \n script:\n
\n
\n \n
\n
\n Now, inside the\n \n OnCollisionEnter\n \n function, we want to spawn our Explosion prefab, and then remove our missile from our scene. We’ll accomplish this by adding the following lines to the function:\n
\n
\n \n
\n
\n Like earlier, we’re Instantiating our\n \n explosionPrefab\n \n at our current position. The variable\n \n Quaternion.identity\n \n , though cryptic-looking, simply means that our explosion will spawn with no rotation applied to it. (We prefer not to pass in our Missile’s rotation here, as that would spawn our explosion effect rotated at weird angles depending on the orientation of our Missile.)\n
\n
\n Once our explosion has spawned, we remove our missile from the scene by calling the aptly named\n \n Destroy\n \n function, passing in the\n \n gameObject\n \n variable, which holds a reference to the object this script is attached to (our Missile, in this case).\n
\n
\n You can give your game another test-run now to confirm that our explosion effects are spawning as expected.\n
\n
\n \n
\n
\n From here let’s back up our newly added explosion effects with some actual physics. After we’ve spawned our explosion prefab, we want to apply an appropriate explosion force to all objects that happen to be close by.\n
\n
\n We can accomplish this with another convenient built-in function called\n \n Physics.OverlapSphere\n \n . This function will create a virtual sphere around any point in space and return a list of all the Collider components that fall inside its radius.\n
\n
\n To implement this, let’s start by declaring one\n \n float\n \n variable to define the radius of our explosion (I’ve set mine to a default value of 5), and another to define the magnitude of the explosion force we want to apply to all surrounding objects (which I’ve set to a default value of 1000).\n
\n
\n \n
\n
\n Next, we’ll insert a call to\n \n Physics.OverlapSphere\n \n right after we’ve spawned our explosion effects, passing in the current position of our missile and the radius we want our explosion to have:\n
\n
\n \n
\n
\n From here, let’s go through each of the Collider components that were inside the virtual sphere (using a\n \n foreach\n \n loop) and apply an explosion force to them using the Unity function\n \n AddExplosionForce\n \n . Recall that in order to add a force to an object, we need to first get its Rigidbody component, so let’s do the following:\n
\n
\n \n
\n
\n Here we temporarily store each object’s Rigidbody component inside the\n \n targetBody\n \n variable. We also have to make sure the object we’re trying to push actually has a Rigidbody component attached – this is why we insert the check for\n \n targetBody == null\n \n and\n \n continue\n \n to the next iteration of the loop if no Rigidbody was found.\n
\n
\n The\n \n AddExplosionForce\n \n function takes in a value for the magnitude of our explosion force, as well as the position and desired radius of our explosion. From there, Unity will automatically calculate the appropriate force to apply to the object depending on how far away from the centre of the explosion it is.\n
\n
\n If you’ve made it this far, congratulate yourself by giving your game another test-run. You can now insert another Tank prefab into your scene (remember to set the value of\n \n Player Number\n \n on the PlayerMovement and the MissileGun components to 2 for this second Tank!) and test that the explosion physics are working as they should. In its current state, you already have a rather enjoyable game of king-of-the-hill, as you can push your fellow Player off of the play space with a well-placed missile.\n
\n
\n \n
\n
\n As a final touch to our explosion mechanics, let’s add another sound effect to play when our missiles explode. Find your Explosion prefab and add an\n \n Audio Source\n \n component\n \n \n to it. Inside the Sounds folder, find the\n \n Explosion.mp3\n \n file and drag it into the empty\n \n AudioClip\n \n field.\n
\n

\n Section 4 – Setting up a win condition\n

\n
\n Our current physics simulation is good fun, but doesn’t exactly resemble Atari Combat in its mechanics. Let’s set up a health system for keeping track of how many times each Tank has been hit, and for ending the game when one Tank has taken too many hits in a row.\n
\n
\n Select either your Tank prefab or one of your Tank objects in the scene (if you’re editing a Tank instance, remember to apply your changes to the prefab when you’re done!), and create a new script. (I’ll call mine simply “Health”). Open your new script in your IDE.\n
\n
\n To start with, declare a public\n \n int\n \n variable to determine how much health a Tank has at the beginning of the game (I’ve set mine to a default value of 5). From here, we’ll declare another private\n \n int\n \n to keep track of how much health our tank currently has at any given point in the game.\n
\n
\n \n
\n
\n Inside the\n \n Start\n \n function (which you’ll recall is called by Unity on every script when that object first enters the scene), we’ll set\n \n currentHealth\n \n to the value of\n \n startHealth\n \n , so that our Tanks start out with a maximum health value when the game begins.\n
\n
\n \n
\n
\n From there we’ll want to set up a way for other components to interact with our\n \n Health\n \n script to make our tanks lose health. We can accomplish this by creating a new public function that decrements the value of\n \n currentHealth\n \n every time it’s called:\n
\n
\n \n
\n
\n We can now call this new\n \n TakeDamage\n \n function from anywhere in order to decrease the health of one of our Tanks.\n
\n
\n Of course, we’ll want to have a mechanism in place to end the game once one of our Tanks’ health drops to zero. Let’s create another simple\n \n Die\n \n function that we call whenever this happens. Inside\n \n Die\n \n , we can simply destroy our Tank’s GameObject for the time being to indicate that the game is over.\n
\n
\n \n
\n
\n We now have features in place to make our Tanks take damage, but we’re not actually using them anywhere. We want our Tanks to take damage whenever they are hit by a Missile’s explosion, so let’s return to our\n \n MissileExplosion\n \n script and add this extra functionality.\n
\n
\n Inside of\n \n MissileExplosion\n \n ’s\n \n OnCollisionEnter\n \n function, we’re already going through every object that is within range of our explosion, so let’s insert another few lines here to apply damage to any object in range that also has a Health component:\n
\n
\n \n
\n
\n Notice that we can use Unity’s\n \n GetComponent\n \n function to access even our own user-defined components, such as Health. Just as we did before applying forces to nearby Rigidbodies, we also have to make sure to check whether or not the object we’re looking at actually has a\n \n Health\n \n component before we call the\n \n TakeDamage\n \n function.\n
\n
\n We now have a suitable win condition in place! You may find it a bit difficult to kill your fellow player without knocking them off the playing field first, however. Let’s sort that out by adding some walls around our play space.\n
\n
\n You can add walls by simply inserting a few cubes into your scene (\n \n GameObject -> 3D Object -> Cube\n \n from the menu at the top of Unity), resizing, rotating and moving them to the edge of the play space accordingly. If you navigate to the\n \n Materials\n \n folder, you can find the\n \n WallMat\n \n , which you can drag and drop onto your Cubes to give them a rusty metal look.\n
\n
\n I set up my level’s walls in the following way: After inserting a Cube and applying the\n \n WallMat\n \n to it, I scaled it to (5, 5, 75) and moved it to the left edge of the play space. I then duplicated the cube (right click on it in the Hierarchy and select\n \n Duplicate\n \n ) and moved the copy to the right edge. I then made another duplicate, set its scale to (5, 5, 125) rotated it 90 degrees in Y and moved it to the top edge. Finally, I duplicated this wall one last time and moved it to the bottom edge.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n \n \n
\n \n
\n
\n
\n Now that we have all of the components we want on our Tanks in place, let’s also apply a different Material to our second Tank so they are clearly differentiated. With your second tank selected in the Hierarchy, find its\n \n Mesh Renderer\n \n component and expand the\n \n Materials\n \n array option. Inside the\n \n Materials\n \n folder, find\n \n Player2Mat\n \n and drag it into the first element of the second Tank’s\n \n Materials\n \n array.\n
\n
\n \n
\n
\n \n
\n

\n Section 5 – User Interface\n

\n
\n The only thing that remains for us to do to recreate Atari Combat in modern form is to display each player’s current score on some sort of on-screen HUD. We’ll accomplish this using a UI Text element.\n
\n
\n Insert a UI Text object by clicking on\n \n GameObject -> UI -> Text\n \n . You’ll notice that doing this inserted not only a new object called\n \n Text\n \n into your scene, but also a\n \n Canvas\n \n and an\n \n EventSystem\n \n . If you double-click on the\n \n Canvas\n \n object in the Hierarchy to zoom in on it, you may be startled to find that it is actually a giant rectangle that sits somewhere far removed from the rest of our level. As it turns out, there is a natural explanation for this.\n
\n
\n \n
\n
\n The\n \n Canvas\n \n object, which is the parent object of all UI objects in Unity, actually exists in a different “space” from all of our other objects. Our Tanks, walls, Ground and Missiles exist in what’s known as “World Space” – the virtual 3D coordinate system of our game. The\n \n Canvas\n \n and all the objects childed to it, meanwhile, exist in 2D “Screen Space”. Screen Space coordinates are determined by the size of the player’s screen, and objects that use it will by default always render on top of all other objects.\n
\n
\n To start with, select your newly created\n \n Text\n \n object and edit its\n \n Text\n \n component. Select the\n \n Color\n \n property and set it to white.\n
\n
\n \n
\n
\n You can now confirm that the\n \n Text\n \n object does in fact appear on top of everything else by switching to\n \n Game View\n \n (or by pressing the\n \n Play\n \n button and running the game).\n
\n
\n \n
\n
\n Let’s make some more changes to our\n \n Text\n \n object. Select Unity’s\n \n UI Editing\n \n tool in the top left-hand side of Unity (or by pressing the T key on your keyboard).\n
\n
\n \n
\n \n \n \n \n \n \n \n \n
\n
\n \n
\n
\n Using this tool, move the Text object to the top left of the Canvas. Rename this object to “Player 1 Score”. From here, find its\n \n Text\n \n component again and set its\n \n Font Style\n \n to\n \n Bold\n \n , and its\n \n Font Size\n \n to 26. Fill in the\n \n Text\n \n field with placeholder numbers to represent Player 1’s score (I’ll just use “999999999”).\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n
\n \n \n \n
\n
\n Duplicate this\n \n Player 1 Score\n \n object and rename it “Player 2 Score”. Move\n \n Player 2 Score\n \n to the top right corner of the Canvas, and edit its\n \n Alignment\n \n property to be\n \n right-aligned\n \n . You should end up with a Canvas that looks like the following:\n
\n
\n \n
\n
\n With that, we have an on-screen HUD in place for displaying our players’ scores. Of course, our text elements are still completely static and will not change during play. Let’s do something about that.\n
\n
\n Select your\n \n Canvas\n \n object in the Hierarchy and add a new script to it with a descriptive name (I’ll call mine “ScoreManager”). Open it up in your IDE.\n
\n
\n As we saw when editing our Text objects, the component responsible for what text to display on the screen was the aptly named\n \n Text\n \n component, so these are the components we want to be editing inside our script. Unfortunately, Unity doesn’t grant us access to these components by default, so we’ll have to include the following line at the very top of our\n \n ScoreManager\n \n script:\n
\n
\n \n
\n
\n This\n \n using\n \n line will import all of the components associated with UI. Having addressed that, let’s start our script by declaring two public variables of type\n \n Text\n \n (I will call mine “player1ScoreText” and “player2ScoreText”).\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n \n \n
\n \n
\n
\n
\n Similar to what we’ve done before, populate these new public variables by dragging the\n \n Player 1 Score\n \n and\n \n Player 2 Score\n \n objects into the corresponding empty fields on the Canvas in Unity.\n
\n
\n \n
\n
\n We can now edit what text to display inside our\n \n Text\n \n objects anywhere we want inside our script. Let’s start by setting both of them to display “0” when inside our\n \n ScoreManager\n \n ’s\n \n Start\n \n function:\n
\n
\n \n
\n
\n Notice that in order to change the text that displays on each\n \n Text\n \n component, we have to assign a different string to its\n \n text\n \n property. (The term “text” has been heavily overloaded here, so if you’re confused, just take care to copy the above two lines carefully until you get the desired effect.)\n
\n
\n If we now Play our game, we’ll see that our\n \n Text\n \n objects indeed start off by displaying “0” when the game runs.\n
\n
\n \n
\n
\n All that remains now is for us to change what these elements display in response to a Tank getting hit by a missile. In order to accomplish that, we’ll have to declare another two private\n \n int\n \n variables to keep track of each player’s score. We’ll set both of these to a default value of 0 to represent each of our players’ score at the start of the game.\n
\n
\n \n
\n
\n From here, let’s think about how we would want outside components to interact with our\n \n ScoreManager\n \n to increase a player’s score. A player’s score should go up if they managed to hit their fellow player with a well-placed missile. The easiest way for us to detect when this has happened would be inside our\n \n Health\n \n script whenever the\n \n TakeDamage\n \n function is called.\n
\n
\n With this in mind, let’s create a public function inside our\n \n ScoreManager\n \n script that takes in the number of the player that just took damage and increments the value of the other player’s score. (I’m going to call this function “OnPlayerDamaged”.)\n
\n
\n \n
\n
\n Finally, we want to make sure we’re updating our\n \n Text\n \n elements to display each player’s new score as soon as it changes:\n
\n
\n \n
\n
\n Note that the\n \n text\n \n property expects to be assigned a\n \n string\n \n value, which is why we have to apply the\n \n ToString\n \n function to the\n \n player1Score\n \n and\n \n player2Score\n \n variables before we assign them to the Text elements.\n
\n
\n All we have to do now is insert a call to this new function inside our\n \n Health\n \n script. Before we do that, however, we need to declare another public\n \n int\n \n variable inside of\n \n Health\n \n so we can keep track of which player took damage.\n
\n
\n \n
\n
\n We’re also going to need a way to access our\n \n ScoreManager\n \n script from inside of\n \n Health.\n \n We can do this in the same way that we did before, by declaring a public\n \n ScoreManager\n \n variable and simply dragging it into the empty field.\n
\n
\n This time, however, because we know that there will only be one\n \n ScoreManager\n \n in our scene at any time, we can make use of another handy Unity function instead –\n \n FindObjectOfType\n \n :\n
\n
\n \n
\n
\n The\n \n FindObjectOfType\n \n function will search through our current scene and return the first object it finds of a certain type, which is why it’s enough for us to declare a private\n \n ScoreManager\n \n variable to hold the reference we need.\n
\n
\n Finally, let’s insert the appropriate call to\n \n OnPlayerDamaged\n \n inside of our\n \n Health\n \n script’s\n \n TakeDamage\n \n function:\n
\n
\n \n
\n
\n And with that – congratulations! You now have a fully working version of Atari Combat, updated for the modern era. Make sure to playtest your game to make sure everything is working as it should. (Remember to set the correct\n \n Player Number\n \n value for each Tank’s\n \n PlayerMovement, MissileGun\n \n and\n \n Health\n \n component respectively.)\n
\n
\n It’s now up to you how you want to design your level. Personally, I will do my best to recreate the classic design of the Combat level pictured at the beginning of this tutorial by moving and shaping a set of cubes:\n
\n
\n \n
\n

\n Conclusion\n

\n
\n Thank you for sticking through with this tutorial until the end and for persevering through with making a complete game! Whether or not you made it out to our workshop in person or not, I hope you’ve picked up on a number of key concepts about making games in Unity and C#.\n
\n
\n Feel free to take a look at the source code for the completed game at\n \n https://github.com/colonelsalt/SuperTanks\n \n if you want to compare your implementation to mine.\n
\n
\n If you’re looking to improve or expand upon the game from here, there are certainly many directions you could take it. Let me offer a few suggestions off the top of my head:\n
\n
\n · You’ll notice we have a couple of unused sound effects inside our\n \n Sounds\n \n folder. Can you think of a suitable place to insert these in the game? What actions should trigger them to start or stop playing?\n
\n
\n · Is it really fair that a player can damage him- or herself with their own missile and give their opponent points? What changes could you implement to make sure that only an opponent’s missile can damage a given Tank?\n
\n
\n · Typically games will have some functionality in place to prevent a player from taking damage too quickly in a row by making them invincible for a second or two after they take damage – how could you go about implementing this?\n
\n
\n · What if we want to play another round immediately without closing down our game and re-opening it? What mechanisms would have to be in place, and which variables would have to be reset in order for a “Play Again” button to work as expected?\n
\n
\n \n Project asset credits:\n \n
\n
\n ·\n \n Low-Poly Tank Assets\n \n by PixelMannen:\n \n https://opengameart.org/content/low-poly-tank-assets\n \n
\n
\n ·\n \n Small Explosives Pack\n \n by mrpoly:\n \n https://opengameart.org/content/small-explosives-pack\n \n
\n
\n ·\n \n Short Explosion 1\n \n by ProjectsU012:\n \n https://freesound.org/people/ProjectsU012/sounds/334266/\n \n
\n
\n ·\n \n Gun, pistol, single shot silenced, Walther pp7\n \n by John J:\n \n https://www.zapsplat.com/music/gun-pistol-single-shot-silenced-walther-pp7/\n \n \n \n
\n
\n ·\n \n Tada Fanfare A\n \n by plasterbrain:\n \n https://freesound.org/people/plasterbrain/sounds/397355/\n \n \n \n
\n
\n ·\n \n Combat Plan\n \n by PlayOnLoop.com:\n \n https://www.playonloop.com/2018-music-loops/combat-plan/\n \n \n \n
\n
\n ·\n \n Seamless Ground Textures\n \n by TutorialsForBlender:\n \n http://www.tutorialsforblender3d.com/Ground/Page2\n \n \n \n
\n
\n ·\n \n Metal Rusty and Patterned\n \n by maxTextures:\n \n http://www.mb3d.co.uk/mb3d/Metal_Rusty_and_Patterned_Seamless_and_Tileable_High_Res_Textures.html\n \n \n","body@stringLength":"50888","rawBody":"\n \n \n First published on MSDN on Feb 24, 2018\n \n
\n
\n
\n \n
\n
\n \n
\n
\n Guest post by\n \n Sondre Agledahl\n \n : Games programmer, CS student and Microsoft Student Partner at UCL\n
\n
\n Microsoft Student Partners ran an introductory workshop to game development with C# and Unity at UCL. The workshop was a great success and we covered a lot of important topics, but due to time constraints we weren’t able to finish the game we were planning to make at the event. For the benefit of attendees who wanted to complete the game in full (as well as for the many who wanted to attend but weren’t able), we’ve decided to post this web tutorial covering how to make the game from start to finish.\n
\n
\n \n
\n
\n The game we want to make is an updated 2.5D version of the 1977 game Combat for the Atari 2600 (pictured below). Similarly to that classic, our game is a two-player top-down shooter game, where your objective is to shoot and eventually destroy your opponent’s tank.\n
\n
\n \n
\n

\n Section 1 – Setting up our game scene\n

\n
\n We begin by creating an empty Unity project, giving it a descriptive name (“SuperTanks” seems appropriate). Once Unity has finished loading an empty scene, import our special MSP Unity StarterPack (which you can freely download from\n \n http://bit.ly/UCLMSP18\n \n ). You can import custom asset packs by clicking on\n \n Assets -> Import Package -> Custom Package…\n \n in Unity’s menu bar at the top of the screen.\n
\n
\n From here, open the newly imported “Prefabs” folder and drag the\n \n Tank\n \n prefab into your scene hierarchy.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n
\n \n \n
\n \n \n
\n
\n
\n
\n Remember to save your Unity scene with an appropriate name (“Level1”) either through\n \n File -> Save Scenes\n \n or by pressing CTRL+S (it’s a good habit to get into pressing these at frequent intervals to make sure you don’t lose any progress).\n
\n
\n From here, we want to create the primary floor of our level mesh. Insert a plane into your scene by clicking on\n \n GameObject -> 3D Object -> Plane\n \n . Ensure your newly created plane is centred at position (0, 0, 0), which should be directly below the tank, as pictured below.\n
\n
\n \n
\n
\n Navigate to the\n \n Materials\n \n folder and find the “GroundMat” material. Drag and drop it onto your newly created Plane object to apply a simple brown dirt texture to it.\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n
\n \n \n \n \n
\n \n \n \n
\n
\n
\n Next, we want to resize our plane to create a play space of a similar size to that of Atari Combat. Select your Plane object in the Hierarchy and change its scale values to (12, 1, 7). For organisational purposes, let’s also rename our plane object to “Ground”.\n
\n
\n With our new Ground object set up, we’ll position our camera so that it captures this entire play space.\n
\n
\n Select your\n \n Main Camera\n \n object in the Hierarchy and move it so that it is above the Ground and Tank objects, facing downwards. If you’re adjusting values manually, you can set the Main Camera’s position to (0, 63, -25), and its rotation to (70, 0, 0). Your scene should look similar to that pictured below:\n
\n
\n \n
\n Next, let’s start to think about how we want our Tank to behave. Since our Tank is going to be a solid, physical object in our game, we are going to want to add both a\n \n Rigidbody\n \n and a\n \n Box Collider\n \n to it. Simply select your Tank object and click on the\n \n Add Component\n \n button at the bottom right of the screen in the Inspector view, find the\n \n Rigidbody\n \n and\n \n Box Collider\n \n components and add them.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n
\n \n \n \n
\n
\n
\n As a simple introduction to movement and input, we’ve included a\n \n PlayerMovement\n \n script as a part of the MSP Unity starter package. Navigate to the\n \n Scripts\n \n folder and drag the\n \n PlayerMovement\n \n file onto your Tank object. Provided you’ve set up the Tank’s other components correctly, you should now find that by building and running your game (pressing the\n \n Play\n \n icon at the top middle of Unity), you can move your tank around the play space with the W-A-S-D keys.\n
\n
\n \n
\n
\n Once you’ve had a play with moving your Tank around your scene, remember to apply your changes to the\n \n Tank\n \n prefab, so that every other Tank copy we make in the future will have the same components that we just added applied to it. (With your Tank object selected, find the Prefab options in the top of the Inspector view on the right side of the screen, and click on Apply.\n
\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n With your changes applied to the Tank prefab, you can now experiment around with inserting another tank and setting the value of\n \n Player Number\n \n (on the\n \n PlayerMovement\n \n component) to 2. The script will now respond to input from the UP-DOWN-LEFT-RIGHT arrow keys on your keyboard instead, allowing for two-player movement. (We will have a more detailed look at multiplayer integration later, so you can delete your second Tank object once you’re done testing out this basic movement.)\n
\n

\n Section 2 – Firing missiles\n

\n
\n One core piece of functionality we want in our game is for our Tank to be able to fire missiles – so let’s write a script that does just that. With your Tank object selected, click on\n \n Add Component\n \n in the lower right of the Inspector view, and select\n \n New Script\n \n . Name your new script appropriately (I will call mine\n \n MissileGun\n \n ) and press\n \n Create and Add\n \n . Double-click on your newly created script and it should open up in Visual Studio (or your IDE of choice).\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n
\n \n \n \n \n \n
\n
\n
\n The empty script will contain two empty functions –\n \n Start\n \n (which is called once when our object first enters the scene), and\n \n Update\n \n (which is called every single frame of the game). Since we want to fire our missiles in response to user input (which can happen at any point), we want to add our functionality into the\n \n Update\n \n function.\n
\n
\n Before we implement our missile firing, however, let’s declare a few important variables that we’re going to need. At the top of your script, declare a public\n \n int\n \n variable called “playerNumber” (with a default value of 1), and a public\n \n GameObject\n \n variable called\n \n missilePrefab.\n \n
\n
\n \n
\n
\n If you now switch back into Unity, you should find that these two variables now have become editable fields inside our\n \n MissileGun\n \n component that we can access our change from inside our Unity editor.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n \n
\n \n \n \n
\n
\n
\n
\n Now that we have a way to influence our scripts from inside Unity, go back inside the\n \n Prefabs\n \n folder and drag the\n \n Missile\n \n prefab into the empty\n \n Missile Prefab\n \n field on our Tank’s MissileGun component.\n
\n
\n We now have access to our\n \n Missile\n \n object inside of our script, so let’s begin thinking about the conditions for shooting them. We want to spawn our missiles in response to input from the player, so let’s take a look at which buttons we have available to read from inside Unity.\n
\n
\n Inside your Unity window, click on\n \n Edit -> Project Settings -> Input\n \n to open up Unity’s Input Manager (it should appear on the right-hand side of the screen). Here you can see a list of all the buttons that are defined in Unity by default. Notice the “Fire1” and “Fire2” buttons; we will configure these to be the button for firing missiles for our Player 1 and Player 2 respectively.\n
\n
\n \n
\n
\n The\n \n Positive Button\n \n field for each input button denotes which keyboard key Unity checks for to determine whether the button in question was pressed. In order to make the game easiest to play for two players on a single keyboard, let’s change\n \n Positive Button\n \n for the “Fire2” button to “right ctrl”.\n
\n
\n With this simple change applied, go back into Visual Studio (or your IDE of choice). We want to spawn our missile in response to the player pressing either the “Fire1” or “Fire2” buttons, so we will make the following changes to our\n \n Update\n \n function:\n
\n
\n \n
\n
\n Here we’re making use of Unity’s handy\n \n Instantiate\n \n function, which takes in a\n \n GameObject\n \n reference, a position and a rotation value as parameters, and inserts that GameObject into our scene. Since we want to spawn our missile prefab, we pass in our\n \n missilePrefab\n \n variable as the first argument. The\n \n transform.position\n \n and\n \n transform.rotation\n \n variables refer to the current position and rotation of our Tank object, so we pass those in as well.\n
\n
\n The\n \n Input.GetButtonDown\n \n function takes in the name of a Unity button and returns true if the user pressed that button during the current frame. By concatenating the string “Fire” with our\n \n playerNumber\n \n variable, we make Unity check for either “Fire1” (the left CTRL key) or “Fire2” (the right CTRL key) depending on what whether we’ve set\n \n playerNumber\n \n to 1 or 2.\n
\n
\n Go back into Unity and press the Play button to play around with the current state of our game.\n
\n
\n \n
\n
\n You should find that you can now spawn a trail of missiles in your Tank’s path with repeated presses of the CTRL key. Not exactly the behaviour we were going for, but we’re getting closer.\n
\n
\n Let’s start moving closer to what we want by editing our\n \n Missile\n \n prefab. Drag the prefab from inside the Prefabs folder into your scene to create a new\n \n Missile\n \n instance. Just like our Tank, we want our missiles to be affected by Unity’s physics engine, so let’s add a\n \n Rigidbody\n \n component to our Missile instance.\n
\n
\n We also want our missiles to collide with other objects in our scene, so let’s add a\n \n Capsule Collider\n \n component to it as well. You may find that Unity’s default size and position for this Capsule Collider don’t exactly match the shape of the missile, so edit the properties of this component until they do. (My settings are Center: (0, 0, 0), Radius: 0.3, Height: 2.5 and Direction: Z-axis).\n
\n
\n \n
\n
\n Remember to\n \n Apply\n \n your changes to the Missile prefab when you’re done editing its components!\n
\n
\n With these changes applied, you can do some more playtesting. You may notice that after making our missiles into physical, collidable objects, they cause our Tank to twirl around and bounce up and down around the scene. We’ll want to make a few adjustments to make sure this doesn’t happen.\n
\n \n \n \n \n \n \n \n \n
\n
\n \n \n
\n
\n Select your Tank object and find its\n \n Rigidbody\n \n component. Under the\n \n Constraints\n \n option, tick the boxes for\n \n Freeze Rotation\n \n in X and Z. This will ensure that our Tank only rotates around the Y-axis (which is what we want it do in response to user input).\n
\n
\n Next, let’s make a few adjustments so that our missiles spawn from a position just in front of the tank’s cannon instead of in the middle of it.\n
\n
\n Right click on your Tank object in the Hierarchy view and select\n \n Create Empty\n \n . This will insert an empty\n \n GameObject\n \n into your scene that is “childed” to the Tank – which means that its position and rotation will always be relative to that of the Tank (so that when the Tank moves around the scene, this child object will move alongside it).\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n \n
\n \n \n \n
\n \n \n
\n
\n
\n
\n Rename this empty GameObject with an appropriate name (such as “Fire Transform”), and move it to a location in front of the Tank where you want missiles to spawn from (I’ve set mine to position (0, 2, 5)).\n
\n
\n From here, let’s get hold of a reference to our new\n \n Fire Transform\n \n object from inside our\n \n MissileGun\n \n script. Open your script again and declare a new public variable of type\n \n Transform\n \n called “fireTransform”.\n
\n
\n \n
\n Just as before, if you now go back into Unity, you will find that a new empty field (\n \n Fire Transform\n \n ) should appear in your Tank’s\n \n MissileGun\n \n component. Take our newly created Fire Transform object and drag it into this empty field.\n
\n
\n \n
\n
\n Back inside our\n \n MissileGun\n \n script, let’s change our call to\n \n Instantiate\n \n so that our missiles are spawned at the position of our\n \n Fire Transform\n \n object rather than our tank’s position:\n
\n
\n \n
\n
\n Again, remember to apply your changes to the Tank prefab! If you now have a play with the game, you will see that our missiles behave much closer to how we want them to.\n
\n
\n The astute reader will still notice that our missiles aren’t flying off into the air the way we would expect them to. Let’s change that by applying a force to them right after they’ve been spawned.\n
\n
\n Let’s start by declaring another public\n \n float\n \n variable that defines the magnitude of the force we’ll be applying at the top of our script (I’ve set mine to a default value of 2000):\n
\n
\n \n
\n
\n Now we can apply this force to our missiles in the following way:\n
\n
\n \n
\n
\n Here we’re temporarily storing a reference to our newly spawned missile object inside the\n \n missile\n \n variable, then using the\n \n GetComponent\n \n function to retrieve its Rigidbody component. Finally, we call Unity’s\n \n AddForce\n \n function on the missile’s Rigidbody.\n
\n
\n Because a force has both magnitude and direction, we have to pass in a vector object into this function. The handy\n \n transform.forward\n \n variable always contains a unit vector that points in our Tank’s “forward” direction, which is the direction we want our missiles to move in. We scale this vector with our\n \n fireForce\n \n variable in order to fire them off with the appropriate magnitude.\n
\n
\n Test your game to confirm that your missiles are now finally blasting off into the air in a semi-realistic fashion.\n
\n
\n \n
\n
\n As a final touch to our missile-firing functionality, let’s add a sound effect to play when our missiles spawn. Find your\n \n Missile\n \n prefab again and add an\n \n Audio Source\n \n component to it. Navigate to the\n \n Sounds\n \n folder, and drag the\n \n Fire.mp3\n \n file into the empty\n \n AudioClip\n \n field on the\n \n Audio Source\n \n component.\n
\n
\n \n
\n

\n Section 3 – Explosion Physics\n

\n
\n We now have some satisfying missile-firing mechanics going, but our missiles are still just colliding against the floor and grinding to a halt like any other object when they fall. We would much prefer to have them explode instead.\n
\n
\n If you’ve had a peek in the Prefabs folder, you will see that you’ve already been provided with an\n \n Explosion\n \n prefab. This prefab contains a collection of flashy-looking particle effects that we’ll want to spawn when our missiles collide with something.\n
\n
\n On your\n \n Missile\n \n prefab, create and add a new script with an appropriate name for what we’re about to do (such as “MissileExplosion”), and open it up in your IDE. Just as we’ve done before, let’s declare a public\n \n GameObject\n \n variable at the top of our script to hold a reference to our Explosion prefab.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n \n
\n \n \n
\n
\n
\n
\n Drag the\n \n Explosion\n \n prefab into the field that corresponds to this new variable.\n
\n
\n \n
\n
\n Now let’s Instantiate a copy of this Explosion prefab every time our Missile collides with something. We’re going to accomplish this using the Unity function\n \n OnCollisionEnter\n \n , which will be automatically called on any object with a Collider component the moment it collides against another object.\n
\n
\n Inside your\n \n MissileExplosion\n \n script, simply start typing\n \n OnCollisionEnter\n \n , and Visual Studio should automatically give you the appropriate auto-complete option for the function we’re looking for (just hit TAB or RETURN on your keyboard to confirm your choice). If for whatever reason your IDE doesn’t provide you with this auto-complete help, just copy the function definition below into your\n \n MissileExplosion\n \n script:\n
\n
\n \n
\n
\n Now, inside the\n \n OnCollisionEnter\n \n function, we want to spawn our Explosion prefab, and then remove our missile from our scene. We’ll accomplish this by adding the following lines to the function:\n
\n
\n \n
\n
\n Like earlier, we’re Instantiating our\n \n explosionPrefab\n \n at our current position. The variable\n \n Quaternion.identity\n \n , though cryptic-looking, simply means that our explosion will spawn with no rotation applied to it. (We prefer not to pass in our Missile’s rotation here, as that would spawn our explosion effect rotated at weird angles depending on the orientation of our Missile.)\n
\n
\n Once our explosion has spawned, we remove our missile from the scene by calling the aptly named\n \n Destroy\n \n function, passing in the\n \n gameObject\n \n variable, which holds a reference to the object this script is attached to (our Missile, in this case).\n
\n
\n You can give your game another test-run now to confirm that our explosion effects are spawning as expected.\n
\n
\n \n
\n
\n From here let’s back up our newly added explosion effects with some actual physics. After we’ve spawned our explosion prefab, we want to apply an appropriate explosion force to all objects that happen to be close by.\n
\n
\n We can accomplish this with another convenient built-in function called\n \n Physics.OverlapSphere\n \n . This function will create a virtual sphere around any point in space and return a list of all the Collider components that fall inside its radius.\n
\n
\n To implement this, let’s start by declaring one\n \n float\n \n variable to define the radius of our explosion (I’ve set mine to a default value of 5), and another to define the magnitude of the explosion force we want to apply to all surrounding objects (which I’ve set to a default value of 1000).\n
\n
\n \n
\n
\n Next, we’ll insert a call to\n \n Physics.OverlapSphere\n \n right after we’ve spawned our explosion effects, passing in the current position of our missile and the radius we want our explosion to have:\n
\n
\n \n
\n
\n From here, let’s go through each of the Collider components that were inside the virtual sphere (using a\n \n foreach\n \n loop) and apply an explosion force to them using the Unity function\n \n AddExplosionForce\n \n . Recall that in order to add a force to an object, we need to first get its Rigidbody component, so let’s do the following:\n
\n
\n \n
\n
\n Here we temporarily store each object’s Rigidbody component inside the\n \n targetBody\n \n variable. We also have to make sure the object we’re trying to push actually has a Rigidbody component attached – this is why we insert the check for\n \n targetBody == null\n \n and\n \n continue\n \n to the next iteration of the loop if no Rigidbody was found.\n
\n
\n The\n \n AddExplosionForce\n \n function takes in a value for the magnitude of our explosion force, as well as the position and desired radius of our explosion. From there, Unity will automatically calculate the appropriate force to apply to the object depending on how far away from the centre of the explosion it is.\n
\n
\n If you’ve made it this far, congratulate yourself by giving your game another test-run. You can now insert another Tank prefab into your scene (remember to set the value of\n \n Player Number\n \n on the PlayerMovement and the MissileGun components to 2 for this second Tank!) and test that the explosion physics are working as they should. In its current state, you already have a rather enjoyable game of king-of-the-hill, as you can push your fellow Player off of the play space with a well-placed missile.\n
\n
\n \n
\n
\n As a final touch to our explosion mechanics, let’s add another sound effect to play when our missiles explode. Find your Explosion prefab and add an\n \n Audio Source\n \n component\n \n \n to it. Inside the Sounds folder, find the\n \n Explosion.mp3\n \n file and drag it into the empty\n \n AudioClip\n \n field.\n
\n

\n Section 4 – Setting up a win condition\n

\n
\n Our current physics simulation is good fun, but doesn’t exactly resemble Atari Combat in its mechanics. Let’s set up a health system for keeping track of how many times each Tank has been hit, and for ending the game when one Tank has taken too many hits in a row.\n
\n
\n Select either your Tank prefab or one of your Tank objects in the scene (if you’re editing a Tank instance, remember to apply your changes to the prefab when you’re done!), and create a new script. (I’ll call mine simply “Health”). Open your new script in your IDE.\n
\n
\n To start with, declare a public\n \n int\n \n variable to determine how much health a Tank has at the beginning of the game (I’ve set mine to a default value of 5). From here, we’ll declare another private\n \n int\n \n to keep track of how much health our tank currently has at any given point in the game.\n
\n
\n \n
\n
\n Inside the\n \n Start\n \n function (which you’ll recall is called by Unity on every script when that object first enters the scene), we’ll set\n \n currentHealth\n \n to the value of\n \n startHealth\n \n , so that our Tanks start out with a maximum health value when the game begins.\n
\n
\n \n
\n
\n From there we’ll want to set up a way for other components to interact with our\n \n Health\n \n script to make our tanks lose health. We can accomplish this by creating a new public function that decrements the value of\n \n currentHealth\n \n every time it’s called:\n
\n
\n \n
\n
\n We can now call this new\n \n TakeDamage\n \n function from anywhere in order to decrease the health of one of our Tanks.\n
\n
\n Of course, we’ll want to have a mechanism in place to end the game once one of our Tanks’ health drops to zero. Let’s create another simple\n \n Die\n \n function that we call whenever this happens. Inside\n \n Die\n \n , we can simply destroy our Tank’s GameObject for the time being to indicate that the game is over.\n
\n
\n \n
\n
\n We now have features in place to make our Tanks take damage, but we’re not actually using them anywhere. We want our Tanks to take damage whenever they are hit by a Missile’s explosion, so let’s return to our\n \n MissileExplosion\n \n script and add this extra functionality.\n
\n
\n Inside of\n \n MissileExplosion\n \n ’s\n \n OnCollisionEnter\n \n function, we’re already going through every object that is within range of our explosion, so let’s insert another few lines here to apply damage to any object in range that also has a Health component:\n
\n
\n \n
\n
\n Notice that we can use Unity’s\n \n GetComponent\n \n function to access even our own user-defined components, such as Health. Just as we did before applying forces to nearby Rigidbodies, we also have to make sure to check whether or not the object we’re looking at actually has a\n \n Health\n \n component before we call the\n \n TakeDamage\n \n function.\n
\n
\n We now have a suitable win condition in place! You may find it a bit difficult to kill your fellow player without knocking them off the playing field first, however. Let’s sort that out by adding some walls around our play space.\n
\n
\n You can add walls by simply inserting a few cubes into your scene (\n \n GameObject -> 3D Object -> Cube\n \n from the menu at the top of Unity), resizing, rotating and moving them to the edge of the play space accordingly. If you navigate to the\n \n Materials\n \n folder, you can find the\n \n WallMat\n \n , which you can drag and drop onto your Cubes to give them a rusty metal look.\n
\n
\n I set up my level’s walls in the following way: After inserting a Cube and applying the\n \n WallMat\n \n to it, I scaled it to (5, 5, 75) and moved it to the left edge of the play space. I then duplicated the cube (right click on it in the Hierarchy and select\n \n Duplicate\n \n ) and moved the copy to the right edge. I then made another duplicate, set its scale to (5, 5, 125) rotated it 90 degrees in Y and moved it to the top edge. Finally, I duplicated this wall one last time and moved it to the bottom edge.\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n \n \n
\n \n
\n
\n
\n Now that we have all of the components we want on our Tanks in place, let’s also apply a different Material to our second Tank so they are clearly differentiated. With your second tank selected in the Hierarchy, find its\n \n Mesh Renderer\n \n component and expand the\n \n Materials\n \n array option. Inside the\n \n Materials\n \n folder, find\n \n Player2Mat\n \n and drag it into the first element of the second Tank’s\n \n Materials\n \n array.\n
\n
\n \n
\n
\n \n
\n

\n Section 5 – User Interface\n

\n
\n The only thing that remains for us to do to recreate Atari Combat in modern form is to display each player’s current score on some sort of on-screen HUD. We’ll accomplish this using a UI Text element.\n
\n
\n Insert a UI Text object by clicking on\n \n GameObject -> UI -> Text\n \n . You’ll notice that doing this inserted not only a new object called\n \n Text\n \n into your scene, but also a\n \n Canvas\n \n and an\n \n EventSystem\n \n . If you double-click on the\n \n Canvas\n \n object in the Hierarchy to zoom in on it, you may be startled to find that it is actually a giant rectangle that sits somewhere far removed from the rest of our level. As it turns out, there is a natural explanation for this.\n
\n
\n \n
\n
\n The\n \n Canvas\n \n object, which is the parent object of all UI objects in Unity, actually exists in a different “space” from all of our other objects. Our Tanks, walls, Ground and Missiles exist in what’s known as “World Space” – the virtual 3D coordinate system of our game. The\n \n Canvas\n \n and all the objects childed to it, meanwhile, exist in 2D “Screen Space”. Screen Space coordinates are determined by the size of the player’s screen, and objects that use it will by default always render on top of all other objects.\n
\n
\n To start with, select your newly created\n \n Text\n \n object and edit its\n \n Text\n \n component. Select the\n \n Color\n \n property and set it to white.\n
\n
\n \n
\n
\n You can now confirm that the\n \n Text\n \n object does in fact appear on top of everything else by switching to\n \n Game View\n \n (or by pressing the\n \n Play\n \n button and running the game).\n
\n
\n \n
\n
\n Let’s make some more changes to our\n \n Text\n \n object. Select Unity’s\n \n UI Editing\n \n tool in the top left-hand side of Unity (or by pressing the T key on your keyboard).\n
\n
\n \n
\n \n \n \n \n \n \n \n \n
\n
\n \n
\n
\n Using this tool, move the Text object to the top left of the Canvas. Rename this object to “Player 1 Score”. From here, find its\n \n Text\n \n component again and set its\n \n Font Style\n \n to\n \n Bold\n \n , and its\n \n Font Size\n \n to 26. Fill in the\n \n Text\n \n field with placeholder numbers to represent Player 1’s score (I’ll just use “999999999”).\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n
\n \n \n \n
\n
\n Duplicate this\n \n Player 1 Score\n \n object and rename it “Player 2 Score”. Move\n \n Player 2 Score\n \n to the top right corner of the Canvas, and edit its\n \n Alignment\n \n property to be\n \n right-aligned\n \n . You should end up with a Canvas that looks like the following:\n
\n
\n \n
\n
\n With that, we have an on-screen HUD in place for displaying our players’ scores. Of course, our text elements are still completely static and will not change during play. Let’s do something about that.\n
\n
\n Select your\n \n Canvas\n \n object in the Hierarchy and add a new script to it with a descriptive name (I’ll call mine “ScoreManager”). Open it up in your IDE.\n
\n
\n As we saw when editing our Text objects, the component responsible for what text to display on the screen was the aptly named\n \n Text\n \n component, so these are the components we want to be editing inside our script. Unfortunately, Unity doesn’t grant us access to these components by default, so we’ll have to include the following line at the very top of our\n \n ScoreManager\n \n script:\n
\n
\n \n
\n
\n This\n \n using\n \n line will import all of the components associated with UI. Having addressed that, let’s start our script by declaring two public variables of type\n \n Text\n \n (I will call mine “player1ScoreText” and “player2ScoreText”).\n
\n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n \n \n
\n \n
\n
\n
\n Similar to what we’ve done before, populate these new public variables by dragging the\n \n Player 1 Score\n \n and\n \n Player 2 Score\n \n objects into the corresponding empty fields on the Canvas in Unity.\n
\n
\n \n
\n
\n We can now edit what text to display inside our\n \n Text\n \n objects anywhere we want inside our script. Let’s start by setting both of them to display “0” when inside our\n \n ScoreManager\n \n ’s\n \n Start\n \n function:\n
\n
\n \n
\n
\n Notice that in order to change the text that displays on each\n \n Text\n \n component, we have to assign a different string to its\n \n text\n \n property. (The term “text” has been heavily overloaded here, so if you’re confused, just take care to copy the above two lines carefully until you get the desired effect.)\n
\n
\n If we now Play our game, we’ll see that our\n \n Text\n \n objects indeed start off by displaying “0” when the game runs.\n
\n
\n \n
\n
\n All that remains now is for us to change what these elements display in response to a Tank getting hit by a missile. In order to accomplish that, we’ll have to declare another two private\n \n int\n \n variables to keep track of each player’s score. We’ll set both of these to a default value of 0 to represent each of our players’ score at the start of the game.\n
\n
\n \n
\n
\n From here, let’s think about how we would want outside components to interact with our\n \n ScoreManager\n \n to increase a player’s score. A player’s score should go up if they managed to hit their fellow player with a well-placed missile. The easiest way for us to detect when this has happened would be inside our\n \n Health\n \n script whenever the\n \n TakeDamage\n \n function is called.\n
\n
\n With this in mind, let’s create a public function inside our\n \n ScoreManager\n \n script that takes in the number of the player that just took damage and increments the value of the other player’s score. (I’m going to call this function “OnPlayerDamaged”.)\n
\n
\n \n
\n
\n Finally, we want to make sure we’re updating our\n \n Text\n \n elements to display each player’s new score as soon as it changes:\n
\n
\n \n
\n
\n Note that the\n \n text\n \n property expects to be assigned a\n \n string\n \n value, which is why we have to apply the\n \n ToString\n \n function to the\n \n player1Score\n \n and\n \n player2Score\n \n variables before we assign them to the Text elements.\n
\n
\n All we have to do now is insert a call to this new function inside our\n \n Health\n \n script. Before we do that, however, we need to declare another public\n \n int\n \n variable inside of\n \n Health\n \n so we can keep track of which player took damage.\n
\n
\n \n
\n
\n We’re also going to need a way to access our\n \n ScoreManager\n \n script from inside of\n \n Health.\n \n We can do this in the same way that we did before, by declaring a public\n \n ScoreManager\n \n variable and simply dragging it into the empty field.\n
\n
\n This time, however, because we know that there will only be one\n \n ScoreManager\n \n in our scene at any time, we can make use of another handy Unity function instead –\n \n FindObjectOfType\n \n :\n
\n
\n \n
\n
\n The\n \n FindObjectOfType\n \n function will search through our current scene and return the first object it finds of a certain type, which is why it’s enough for us to declare a private\n \n ScoreManager\n \n variable to hold the reference we need.\n
\n
\n Finally, let’s insert the appropriate call to\n \n OnPlayerDamaged\n \n inside of our\n \n Health\n \n script’s\n \n TakeDamage\n \n function:\n
\n
\n \n
\n
\n And with that – congratulations! You now have a fully working version of Atari Combat, updated for the modern era. Make sure to playtest your game to make sure everything is working as it should. (Remember to set the correct\n \n Player Number\n \n value for each Tank’s\n \n PlayerMovement, MissileGun\n \n and\n \n Health\n \n component respectively.)\n
\n
\n It’s now up to you how you want to design your level. Personally, I will do my best to recreate the classic design of the Combat level pictured at the beginning of this tutorial by moving and shaping a set of cubes:\n
\n
\n \n
\n

\n Conclusion\n

\n
\n Thank you for sticking through with this tutorial until the end and for persevering through with making a complete game! Whether or not you made it out to our workshop in person or not, I hope you’ve picked up on a number of key concepts about making games in Unity and C#.\n
\n
\n Feel free to take a look at the source code for the completed game at\n \n https://github.com/colonelsalt/SuperTanks\n \n if you want to compare your implementation to mine.\n
\n
\n If you’re looking to improve or expand upon the game from here, there are certainly many directions you could take it. Let me offer a few suggestions off the top of my head:\n
\n
\n · You’ll notice we have a couple of unused sound effects inside our\n \n Sounds\n \n folder. Can you think of a suitable place to insert these in the game? What actions should trigger them to start or stop playing?\n
\n
\n · Is it really fair that a player can damage him- or herself with their own missile and give their opponent points? What changes could you implement to make sure that only an opponent’s missile can damage a given Tank?\n
\n
\n · Typically games will have some functionality in place to prevent a player from taking damage too quickly in a row by making them invincible for a second or two after they take damage – how could you go about implementing this?\n
\n
\n · What if we want to play another round immediately without closing down our game and re-opening it? What mechanisms would have to be in place, and which variables would have to be reset in order for a “Play Again” button to work as expected?\n
\n
\n \n Project asset credits:\n \n
\n
\n ·\n \n Low-Poly Tank Assets\n \n by PixelMannen:\n \n https://opengameart.org/content/low-poly-tank-assets\n \n
\n
\n ·\n \n Small Explosives Pack\n \n by mrpoly:\n \n https://opengameart.org/content/small-explosives-pack\n \n
\n
\n ·\n \n Short Explosion 1\n \n by ProjectsU012:\n \n https://freesound.org/people/ProjectsU012/sounds/334266/\n \n
\n
\n ·\n \n Gun, pistol, single shot silenced, Walther pp7\n \n by John J:\n \n https://www.zapsplat.com/music/gun-pistol-single-shot-silenced-walther-pp7/\n \n \n \n
\n
\n ·\n \n Tada Fanfare A\n \n by plasterbrain:\n \n https://freesound.org/people/plasterbrain/sounds/397355/\n \n \n \n
\n
\n ·\n \n Combat Plan\n \n by PlayOnLoop.com:\n \n https://www.playonloop.com/2018-music-loops/combat-plan/\n \n \n \n
\n
\n ·\n \n Seamless Ground Textures\n \n by TutorialsForBlender:\n \n http://www.tutorialsforblender3d.com/Ground/Page2\n \n \n \n
\n
\n ·\n \n Metal Rusty and Patterned\n \n by maxTextures:\n \n http://www.mb3d.co.uk/mb3d/Metal_Rusty_and_Patterned_Seamless_and_Tileable_High_Res_Textures.html\n \n \n","kudosSumWeight":0,"postTime":"2019-03-21T10:37:15.345-07:00","images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU2OThpQzk4RjBFRTdFMTI0NzIwMg?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU2OTlpNEZBMTIyRTM0OEJDNjEzMw?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDBpNjM3OEQ1REQ3MjE3NkEyMQ?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDFpOUQ1OUU0MTI3MTNGQURCRQ?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDJpNDQxRkY5OEVDQzk4QkU5NA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDY","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDNpMTNDQzUxM0UxRTkzNENCNg?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDc","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDRpNEFCNUVDQjE5MkFBNTMwQg?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDg","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDVpQ0QzNjgyMzM4RUJGOEIyRA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDk","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDZpRUFBMkEzRDQ4Q0M3M0M4Mw?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEw","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDdpMjZBOUVCMzU1MTMxNzU2MQ?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEx","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDhpMEMxOThGMEQ5Q0Q2MTgyRA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEy","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDlpMEE4ODgxN0QzMzREQzcyRA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEz","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTBpQ0IwRkU4RkYyMTQ0QUE0MA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE0","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTFpQTFGOTAzMjVDQTBBOEZEQw?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE1","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTJpNjBFNDk3NDExMDgyMDUyNg?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE2","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTNpRTI5Qzc4Qjc3RTNBNTkxNA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE3","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTRpQjkwMTYxRUEyRjZCMzg5MQ?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE4","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTVpNEFCNjdFMkQxRUFFOUZGQQ?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE5","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTZpMUM1NzNGMzI3QUUwNTZERA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDIw","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTdpQTYwMzYxRTdBNDlFMDY5NA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDIx","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MThpQzRFNzJCRjdFRjYxOUZDQQ?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDIy","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTlpRjVBNUMzMDcwRDE4RDgxOA?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDIz","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjBpMTc0RjBCMTNFNjEyNjAyRg?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDI0","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjFpNzk0QTFDQzlBMTg3OTNEQQ?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDI1","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjJpM0JENzFCMEQwRUI4RkM1NA?revision=2\"}"}}],"totalCount":64,"pageInfo":{"__typename":"PageInfo","hasNextPage":true,"endCursor":"MjUuMXwyLjF8b3wyNXxfTlZffDI1","hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":true,"endCursor":"MjUuMXwyLjF8b3wxMHxfTlZffDEw","hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:Academic","text":"Academic","time":"2019-03-21T04:12:34.461-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDI","node":{"__typename":"Tag","id":"tag:faculty","text":"faculty","time":"2019-03-21T04:12:34.461-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDM","node":{"__typename":"Tag","id":"tag:game development","text":"game development","time":"2019-03-21T04:13:41.884-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDQ","node":{"__typename":"Tag","id":"tag:Gaming","text":"Gaming","time":"2018-06-15T14:57:36.633-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDU","node":{"__typename":"Tag","id":"tag:learning","text":"learning","time":"2019-03-21T04:21:17.532-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDY","node":{"__typename":"Tag","id":"tag:microsoft student partner","text":"microsoft student partner","time":"2019-01-08T18:24:08.166-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDc","node":{"__typename":"Tag","id":"tag:student","text":"student","time":"2019-03-21T04:12:34.461-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDg","node":{"__typename":"Tag","id":"tag:students","text":"students","time":"2019-03-21T04:16:37.592-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDk","node":{"__typename":"Tag","id":"tag:UCL","text":"UCL","time":"2019-03-21T05:13:58.572-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDEw","node":{"__typename":"Tag","id":"tag:Unity","text":"Unity","time":"2019-01-08T18:36:44.826-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":22,"rawTeaser":"First published on MSDN on Feb 24, 2018  Guest post by Sondre Agledahl: Games programmer, CS student and Microsoft Student Partner at UCLMicrosoft Student Partners ran an introductory workshop to game development with C# and Unity at UCL.","introduction":"","coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""},"currentRevision":{"__ref":"Revision:revision:380346_2"},"latestVersion":{"__typename":"FriendlyVersion","major":"2","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":3644},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"blogMessagePolicies":{"__typename":"BlogMessagePolicies","canDoAuthoringActionsOnBlog":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","key":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":2}},"Conversation:conversation:380346":{"__typename":"Conversation","id":"conversation:380346","solved":false,"topic":{"__ref":"BlogTopicMessage:message:380346"},"lastPostingActivityTime":"2019-03-21T10:37:17.938-07:00","lastPostTime":"2019-03-21T10:37:15.345-07:00","unreadReplyCount":0,"isSubscribed":false},"ModerationData:moderation_data:380346":{"__typename":"ModerationData","id":"moderation_data:380346","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU2OThpQzk4RjBFRTdFMTI0NzIwMg?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU2OThpQzk4RjBFRTdFMTI0NzIwMg?revision=2","title":"","associationType":"BODY","width":855,"height":394,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU2OTlpNEZBMTIyRTM0OEJDNjEzMw?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU2OTlpNEZBMTIyRTM0OEJDNjEzMw?revision=2","title":"","associationType":"BODY","width":194,"height":231,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDBpNjM3OEQ1REQ3MjE3NkEyMQ?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDBpNjM3OEQ1REQ3MjE3NkEyMQ?revision=2","title":"","associationType":"BODY","width":855,"height":530,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDFpOUQ1OUU0MTI3MTNGQURCRQ?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDFpOUQ1OUU0MTI3MTNGQURCRQ?revision=2","title":"","associationType":"BODY","width":855,"height":617,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDJpNDQxRkY5OEVDQzk4QkU5NA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDJpNDQxRkY5OEVDQzk4QkU5NA?revision=2","title":"","associationType":"BODY","width":851,"height":215,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDNpMTNDQzUxM0UxRTkzNENCNg?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDNpMTNDQzUxM0UxRTkzNENCNg?revision=2","title":"","associationType":"BODY","width":851,"height":417,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDRpNEFCNUVDQjE5MkFBNTMwQg?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDRpNEFCNUVDQjE5MkFBNTMwQg?revision=2","title":"","associationType":"BODY","width":852,"height":385,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDVpQ0QzNjgyMzM4RUJGOEIyRA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDVpQ0QzNjgyMzM4RUJGOEIyRA?revision=2","title":"","associationType":"BODY","width":854,"height":314,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDZpRUFBMkEzRDQ4Q0M3M0M4Mw?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDZpRUFBMkEzRDQ4Q0M3M0M4Mw?revision=2","title":"","associationType":"BODY","width":855,"height":440,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDdpMjZBOUVCMzU1MTMxNzU2MQ?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDdpMjZBOUVCMzU1MTMxNzU2MQ?revision=2","title":"","associationType":"BODY","width":855,"height":469,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDhpMEMxOThGMEQ5Q0Q2MTgyRA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDhpMEMxOThGMEQ5Q0Q2MTgyRA?revision=2","title":"","associationType":"BODY","width":851,"height":280,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDlpMEE4ODgxN0QzMzREQzcyRA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MDlpMEE4ODgxN0QzMzREQzcyRA?revision=2","title":"","associationType":"BODY","width":842,"height":371,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTBpQ0IwRkU4RkYyMTQ0QUE0MA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTBpQ0IwRkU4RkYyMTQ0QUE0MA?revision=2","title":"","associationType":"BODY","width":381,"height":370,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTFpQTFGOTAzMjVDQTBBOEZEQw?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTFpQTFGOTAzMjVDQTBBOEZEQw?revision=2","title":"","associationType":"BODY","width":389,"height":373,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTJpNjBFNDk3NDExMDgyMDUyNg?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTJpNjBFNDk3NDExMDgyMDUyNg?revision=2","title":"","associationType":"BODY","width":853,"height":235,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTNpRTI5Qzc4Qjc3RTNBNTkxNA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTNpRTI5Qzc4Qjc3RTNBNTkxNA?revision=2","title":"","associationType":"BODY","width":851,"height":187,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTRpQjkwMTYxRUEyRjZCMzg5MQ?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTRpQjkwMTYxRUEyRjZCMzg5MQ?revision=2","title":"","associationType":"BODY","width":843,"height":498,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTVpNEFCNjdFMkQxRUFFOUZGQQ?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTVpNEFCNjdFMkQxRUFFOUZGQQ?revision=2","title":"","associationType":"BODY","width":831,"height":182,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTZpMUM1NzNGMzI3QUUwNTZERA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTZpMUM1NzNGMzI3QUUwNTZERA?revision=2","title":"","associationType":"BODY","width":848,"height":459,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTdpQTYwMzYxRTdBNDlFMDY5NA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTdpQTYwMzYxRTdBNDlFMDY5NA?revision=2","title":"","associationType":"BODY","width":851,"height":535,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MThpQzRFNzJCRjdFRjYxOUZDQQ?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MThpQzRFNzJCRjdFRjYxOUZDQQ?revision=2","title":"","associationType":"BODY","width":838,"height":265,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTlpRjVBNUMzMDcwRDE4RDgxOA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MTlpRjVBNUMzMDcwRDE4RDgxOA?revision=2","title":"","associationType":"BODY","width":847,"height":287,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjBpMTc0RjBCMTNFNjEyNjAyRg?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjBpMTc0RjBCMTNFNjEyNjAyRg?revision=2","title":"","associationType":"BODY","width":505,"height":213,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjFpNzk0QTFDQzlBMTg3OTNEQQ?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjFpNzk0QTFDQzlBMTg3OTNEQQ?revision=2","title":"","associationType":"BODY","width":825,"height":172,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjJpM0JENzFCMEQwRUI4RkM1NA?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODAzNDYtOTU3MjJpM0JENzFCMEQwRUI4RkM1NA?revision=2","title":"","associationType":"BODY","width":703,"height":158,"altText":null},"Revision:revision:380346_2":{"__typename":"Revision","id":"revision:380346_2","lastEditTime":"2019-03-21T10:37:17.938-07:00"},"CachedAsset:theme:customTheme1-1745160780424":{"__typename":"CachedAsset","id":"theme:customTheme1-1745160780424","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#1E1E1E","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1745505309992","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1745505309992","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/blogs/BlogMessagePage:board:EducatorDeveloperBlog-1745502712767":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/blogs/BlogMessagePage:board:EducatorDeveloperBlog-1745502712767","value":{"id":"BlogMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"blog-article","layout":"ONE_COLUMN","bgColor":null,"showTitle":null,"showDescription":null,"textPosition":null,"textColor":null,"sectionEditLevel":"LOCKED","bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"OneColumnQuiltSection","columnMap":{"main":[{"id":"blogs.widget.blogArticleWidget","className":"lia-blog-container","props":null,"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"}},{"id":"section-1729184836777","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":false,"showDescription":false,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[],"side":[],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-pages/blogs/BlogMessagePage-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-pages/blogs/BlogMessagePage-1745505309992","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This blog post cannot be found","name":"Blog Message Page","section.blog-article.title":"Blog Post","archivedMessageTitle":"This Content Has Been Archived","section.section-1729184836777.title":"","section.section-1729184836777.description":"","section.CncIde.title":"Blog Post","section.tifEmD.description":"","section.tifEmD.title":""},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1745505311086":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1745505311086","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-microsoft365-copilot-link","params":{"categoryId":"Microsoft365Copilot"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-content_management-link","params":{"categoryId":"Content_Management"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoftintune"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"MicrosoftforNonprofits"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.community_banner","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"usePageWidth":false,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1745505309992","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.community_banner-en-1745160816752":{"__typename":"CachedAsset","id":"component:custom.widget.community_banner-en-1745160816752","value":{"component":{"id":"custom.widget.community_banner","template":{"id":"community_banner","markupLanguage":"HANDLEBARS","style":".community-banner {\n a.top-bar.btn {\n top: 0px;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0px;\n background: #0068b8;\n color: white;\n padding: 10px 0px;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0px !important;\n font-size: 14px;\n }\n}\n","texts":null,"defaults":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.community_banner","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_community_banner_community-banner_1x9u2_1 {\n a.custom_widget_community_banner_top-bar_1x9u2_2.custom_widget_community_banner_btn_1x9u2_2 {\n top: 0;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0;\n background: #0068b8;\n color: white;\n padding: 0.625rem 0;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0 !important;\n font-size: 0.875rem;\n }\n}\n","tokens":{"community-banner":"custom_widget_community_banner_community-banner_1x9u2_1","top-bar":"custom_widget_community_banner_top-bar_1x9u2_2","btn":"custom_widget_community_banner_btn_1x9u2_2"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-1745160816752":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-1745160816752","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search.","blogs.sidebar.pagetitle":"Latest Blogs | Microsoft Tech Community","followThisNode":"Follow this node","unfollowThisNode":"Unfollow this node"},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-1745160816752":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-1745160816752","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n\n.social-share {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n\n.sharing-options {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 43px;\n border-radius: 0px 7px 7px 0px;\n}\n.linkedin-icon {\n border-top-right-radius: 7px;\n}\n.linkedin-icon:hover {\n border-radius: 0;\n}\n.social-share-rss-image {\n border-bottom-right-radius: 7px;\n}\n.social-share-rss-image:hover {\n border-radius: 0;\n}\n\n.social-link-footer {\n position: relative;\n display: block;\n margin: -2px 0;\n transition: all 0.2s ease;\n}\n.social-link-footer:hover .linkedin-icon {\n border-radius: 0;\n}\n.social-link-footer:hover .social-share-rss-image {\n border-radius: 0;\n}\n\n.social-link-footer img {\n width: 40px;\n height: auto;\n transition: filter 0.3s ease;\n}\n\n.social-share-list {\n width: 40px;\n}\n.social-share-rss-image {\n width: 40px;\n}\n\n.share-icon {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n\n.share-icon:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n\n.share-icon:hover .label {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n\n.label {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 10px;\n top: 50%;\n transform: translateY(-50%);\n height: 40px;\n border-radius: 0 6px 6px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 5px 20px 8px;\n margin-left: -1px;\n}\n.linkedin {\n background-color: #0474b4;\n}\n.facebook {\n background-color: #3c5c9c;\n}\n.twitter {\n background-color: white;\n color: black;\n}\n.reddit {\n background-color: #fc4404;\n}\n.mail {\n background-color: #848484;\n}\n.bluesky {\n background-color: white;\n color: black;\n}\n.rss {\n background-color: #ec7b1c;\n}\n#RSS {\n width: 40px;\n height: 40px;\n}\n\n@media (max-width: 991px) {\n .social-share {\n display: none;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_105bp_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_105bp_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_105bp_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_105bp_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_105bp_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n.custom_widget_MicrosoftFooter_social-share_105bp_138 {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n.custom_widget_MicrosoftFooter_sharing-options_105bp_146 {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 2.6875rem;\n border-radius: 0 0.4375rem 0.4375rem 0;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-top-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-bottom-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 {\n position: relative;\n display: block;\n margin: -0.125rem 0;\n transition: all 0.2s ease;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 img {\n width: 2.5rem;\n height: auto;\n transition: filter 0.3s ease;\n}\n.custom_widget_MicrosoftFooter_social-share-list_105bp_188 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195 {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover .custom_widget_MicrosoftFooter_label_105bp_207 {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n.custom_widget_MicrosoftFooter_label_105bp_207 {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 0.625rem;\n top: 50%;\n transform: translateY(-50%);\n height: 2.5rem;\n border-radius: 0 0.375rem 0.375rem 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.25rem 0.3125rem 1.25rem 0.5rem;\n margin-left: -0.0625rem;\n}\n.custom_widget_MicrosoftFooter_linkedin_105bp_156 {\n background-color: #0474b4;\n}\n.custom_widget_MicrosoftFooter_facebook_105bp_237 {\n background-color: #3c5c9c;\n}\n.custom_widget_MicrosoftFooter_twitter_105bp_240 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_reddit_105bp_244 {\n background-color: #fc4404;\n}\n.custom_widget_MicrosoftFooter_mail_105bp_247 {\n background-color: #848484;\n}\n.custom_widget_MicrosoftFooter_bluesky_105bp_250 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_rss_105bp_254 {\n background-color: #ec7b1c;\n}\n#custom_widget_MicrosoftFooter_RSS_105bp_1 {\n width: 2.5rem;\n height: 2.5rem;\n}\n@media (max-width: 991px) {\n .custom_widget_MicrosoftFooter_social-share_105bp_138 {\n display: none;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_105bp_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_105bp_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_105bp_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_105bp_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58","c-list":"custom_widget_MicrosoftFooter_c-list_105bp_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_105bp_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_105bp_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107","social-share":"custom_widget_MicrosoftFooter_social-share_105bp_138","sharing-options":"custom_widget_MicrosoftFooter_sharing-options_105bp_146","linkedin-icon":"custom_widget_MicrosoftFooter_linkedin-icon_105bp_156","social-share-rss-image":"custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162","social-link-footer":"custom_widget_MicrosoftFooter_social-link-footer_105bp_169","social-share-list":"custom_widget_MicrosoftFooter_social-share-list_105bp_188","share-icon":"custom_widget_MicrosoftFooter_share-icon_105bp_195","label":"custom_widget_MicrosoftFooter_label_105bp_207","linkedin":"custom_widget_MicrosoftFooter_linkedin_105bp_156","facebook":"custom_widget_MicrosoftFooter_facebook_105bp_237","twitter":"custom_widget_MicrosoftFooter_twitter_105bp_240","reddit":"custom_widget_MicrosoftFooter_reddit_105bp_244","mail":"custom_widget_MicrosoftFooter_mail_105bp_247","bluesky":"custom_widget_MicrosoftFooter_bluesky_105bp_250","rss":"custom_widget_MicrosoftFooter_rss_105bp_254","RSS":"custom_widget_MicrosoftFooter_RSS_105bp_1"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1745505309992","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1745505309992","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftforNonprofits":{"__typename":"Category","id":"category:MicrosoftforNonprofits","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Microsoft365Copilot":{"__typename":"Category","id":"category:Microsoft365Copilot","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Content_Management":{"__typename":"Category","id":"category:Content_Management","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoftintune":{"__typename":"Category","id":"category:microsoftintune","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"QueryVariables:TopicReplyList:message:380346:2":{"__typename":"QueryVariables","id":"TopicReplyList:message:380346:2","value":{"id":"message:380346","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-components/community/Navbar-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1745505309992","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Nonprofit Community","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","Common-content_management-link":"Content Management","microsoft-learn":"Microsoft Learn","s-q-l-server":"Content Management","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Outlook","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","Common-microsoft365-copilot-link":"Microsoft 365 Copilot","outlook":"Microsoft 365 Copilot","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1745505309992","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1745505309992","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1745505309992","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1745505309992","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1745505309992","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1745505309992","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solved","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1745505309992","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1745505309992","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1745505309992","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1745505309992","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCoverImage-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCoverImage-1745505309992","value":{"coverImageTitle":"Cover Image"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeTitle-1745505309992","value":{"nodeTitle":"{nodeTitle, select, community {Community} other {{nodeTitle}}} "},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTimeToRead-1745505309992","value":{"minReadText":"{min} MIN READ"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1745505309992","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1745505309992","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1745505309992","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1745505309992","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1745505309992","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1745505309992","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1745505309992","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1745505309992","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1745505309992","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1745505309992","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1745505309992","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1745505309992","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeAvatar-1745505309992","value":{"altTitle":"Node avatar for {nodeTitle}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeDescription-1745505309992","value":{"description":"{description}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1745505309992","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505309992","value":{"loadMore":"Show More"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505309992":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1745505309992","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false}}}},"page":"/blogs/BlogMessagePage/BlogMessagePage","query":{"boardId":"educatordeveloperblog","messageSubject":"making-games-with-c-and-unity-8211-beginner8217s-tutorial","messageId":"380346"},"buildId":"HEhyUrv5OXNBIbfCLaOrw","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.1.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/blogs/BlogArticleWidget/BlogArticleWidget.tsx","./components/external/components/ExternalComponent.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx","../shared/client/components/common/Pager/PagerLoadMore/PagerLoadMore.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=BlogMessagePage&entity.id=board%3Aeducatordeveloperblog&entity.id=message%3A380346","strategy":"afterInteractive"}]}