{"id":83230,"date":"2019-02-11T14:37:09","date_gmt":"2019-02-11T14:37:09","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=83230"},"modified":"2021-07-29T19:44:09","modified_gmt":"2021-07-29T19:44:09","slug":"basic-modding-with-unity","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/basic-modding-with-unity\/","title":{"rendered":"Basic Modding with Unity"},"content":{"rendered":"<p>You might occasionally hear about a game that can be \u2018modded.\u2019 But what does that mean? For starters, a <em>mod<\/em> is simply a short version of the word \u2018modification.\u2019 In the context of video games, this means someone has taken time to modify a certain aspect of the game they are playing. This modification can occur by changing the model a character normally uses, editing text in the game, or changing out a music track. Some mods take it a step further by completely overhauling entire systems in the game such as the user interface or the character&#8217;s leveling mechanics.<\/p>\n<p>The power of a community and the ability to mod a game cannot be overstated. Mods allow players to tweak a game to their liking, add more things to do in the game, or just provide a laugh by replacing the dragon with a cartoon pony. However, it should also be noted that allowing mods is a difficult task. There&#8217;s a reason so few games allow mods. In this article, you won&#8217;t learn how to make your game moddable to the level of a game like Skyrim, but you can learn some of the basics of implementing modding capabilities. Within Unity, you&#8217;ll be shown simple methods of allowing users to change the text in your game as well as changing the current mesh an object is using.<\/p>\n<h2>Setup<\/h2>\n<p>There&#8217;s nothing you need to do ahead of project creation, so just open Unity and make a new project as shown in Figure 1.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1002\" height=\"130\" class=\"wp-image-83231\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-16.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 1: Creating a new project.<\/p>\n<p>Name your project <em>BasicMod, <\/em>specify a file path, and make sure it&#8217;s a 3D project. Once you&#8217;ve done all that, create the project. The form should resemble Figure 2.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1002\" height=\"582\" class=\"wp-image-83232\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-17.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 2: Naming the project.<\/p>\n<p>Of course, without any objects to modify there&#8217;s no game to mod at all. Start by creating some text on the screen. Go to the <em>Hierarchy <\/em>window and click the <em>Create<\/em> button. Choose <em>UI-&gt;Text <\/em>to make a text object like Figure 3.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"449\" height=\"454\" class=\"wp-image-83233\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-18.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 3: Creating some text<\/p>\n<p>Next, you&#8217;ll need to position the text in a position where it can be easily seen. The location can be wherever you choose, but Figure 4 shows how to place the text in the upper-middle of the screen. In the <em>Inspector <\/em>window set <em>Pos X <\/em>to -10 and <em>Pos Y <\/em>to 125. Then set the <em>Width <\/em>variable to 500 and <em>Height <\/em>to 150, this way there&#8217;s plenty of space for whatever text you wish to enter.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"604\" height=\"229\" class=\"wp-image-83234\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-19.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 4: Setting <em>Text <\/em>to the correct position and size<\/p>\n<p>After this, create some placeholder text in the <em>Text <\/em>field. It can be whatever you wish. Finally, change any of the text properties you wish to make it easier to read. The below example in Figure 5 places the <em>font size <\/em>variable at 30 and sets the <em>alignment <\/em>to the center.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"604\" height=\"346\" class=\"wp-image-83235\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-20.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 5: Setting up the text<\/p>\n<p>This will do for the game&#8217;s text object. Next, you&#8217;ll need a 3D object. The user may wish to change the object from a simple cube to something else. Start by clicking the <em>Create <\/em>button again in the <em>Hierarchy<\/em>. Navigate to <em>3D Object-Cube <\/em>to create a cube object in the world. Set both its <em>Position X <\/em>and <em>Position Y <\/em>fields to 0. Change its <em>Rotation Y <\/em>field to 45 and set the scale to 5 for all three axes as shown in Figure 6.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"622\" height=\"138\" class=\"wp-image-83236\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-21.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 6: The <em>Cube <\/em>object&#8217;s <em>Transform <\/em>component<\/p>\n<p>Finally, create an empty object by selecting the <em>Create <\/em>button then navigating to <em>Create Empty<\/em>. Name this new object <em>GameManager<\/em>. This is the object that will hold the script that makes this project run. There&#8217;s nothing more to do here in the Unity editor. Navigate to your <em>Assets <\/em>window and create a new <em>C# Script <\/em>as shown in Figure 7. Name this script <em>ModScript<\/em>.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"738\" height=\"577\" class=\"wp-image-83237\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-22.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 7: Making a new C# script<\/p>\n<p>Once created, double click <em>ModScript <\/em>to open Visual Studio and begin the coding process.<\/p>\n<h2>The Code<\/h2>\n<p>To get started, add <code>using UnityEngine.UI; <\/code>and <code>using System.IO;<\/code> to the top of the script as shown in Figure 8. <code>System.IO<\/code> is going to be very important for this project. You&#8217;ll use it to create a folder named <em>Resources <\/em>as well as employ <code>StreamReader<\/code> to read data from a file that the user creates. It will also be responsible for gathering file names, so the rest of the program knows which file to use. <code>UnityEngine.UI<\/code> also has an important job but just has less going on. This will allow you to edit the text on the <em>Text <\/em>object you created earlier.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"325\" height=\"111\" class=\"wp-image-83238\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-23.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 8: All require using statements.<\/p>\n<p>Only a few global variables will need to be declared for this project. Those variables are:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public Text messageText;\r\npublic MeshFilter mf;\r\nprivate string pathToMods;<\/pre>\n<p>Finally, for the sake of cleanliness, you\u2019ll have three function calls that make up the <code>Start<\/code> function. Write the following:<\/p>\n<pre class=\"lang:c# theme:vs2012\">DirectoryCreation();\r\nTextModding();\r\nMeshModding();<\/pre>\n<p>The <code>Update<\/code> function will not see any use in this project, so you may delete it or comment it out. Once finished, the variable declarations and the <code>Start<\/code> function should look like Figure 9.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"325\" height=\"239\" class=\"wp-image-83239\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-24.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 9: The code so far&#8230;<\/p>\n<p>Of course, the compiler doesn\u2019t like the fact that those three functions don&#8217;t exist. Fortunately for Visual Studio, it won&#8217;t stay that way. Start with the <code>DirectoryCreation<\/code> function.<\/p>\n<pre class=\"lang:c# theme:vs2012\">void DirectoryCreation()\r\n{\r\n\tpathToMods = Application.dataPath + \"\/Resources\";\r\n\tif (!Directory.Exists(pathToMods))\r\n\t\tDirectory.CreateDirectory(pathToMods);\r\n}<\/pre>\n<p>Time for a little breakdown of what&#8217;s happening. First, the code sets the value of <code>pathToMods<\/code>. This value is a file path, and the path in question is the <em>Resources <\/em>folder within the path of the game. Of course, none of that will matter if the folder doesn&#8217;t exist. The next two lines check to see if there is a <em>Resources <\/em>directory. If there isn&#8217;t, the folder will be created for you.<\/p>\n<p>Up next is where the fun begins. <code>TextModding<\/code> is the function that will allow a user to modify the text in the game. The function goes like this:<\/p>\n<pre class=\"lang:c# theme:vs2012\">void TextModding()\r\n{\r\n\tstring[] textMods = Directory.GetFiles(pathToMods + \"\/\", \"*.txt\");\r\n\tif (textMods.Length == 1)\r\n\t{\r\n\t\tStreamReader reader = new StreamReader(textMods[0]);\r\n\t\tmessageText.text = reader.ReadToEnd();\r\n\t}\r\n\telse if (textMods.Length &gt; 1)\r\n\t{\r\n\t\tint file = Random.Range(0, textMods.Length);\r\n\t\tStreamReader reader = new StreamReader(textMods[file]);\r\n\t\tmessageText.text = reader.ReadToEnd();\r\n\t}\r\n}<\/pre>\n<p>First, you create an array of strings called <code>textMods<\/code>. What do you fill this array with? You gather a list of all files with the txt extension and get their paths. Next, a check is performed to see if there&#8217;s more than one text file. This is done in case the user has more than one txt file. If there&#8217;s only one <em>txt<\/em> file, then you simply take that file, read the text inside it, and then apply that text to the <em>Text <\/em>object in the game. If there&#8217;s more than one <em>txt<\/em> file to choose from, Unity will choose one at random.<\/p>\n<p>So far, your two new functions, <code>DirectoryCreation<\/code> and <code>TextModding<\/code>, should look like Figure 10.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"595\" height=\"401\" class=\"wp-image-83240\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-25.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 10: DirectoryCreation and TextModding<\/p>\n<p>Next comes the ability to modify the current mesh on the <em>Cube <\/em>object using a function called <code>MeshModding<\/code>. Like before, it will find all files with the <em>fbx<\/em> extension. If there&#8217;s more than one file, the program will randomly select one to use. However, this is where the similarities between this function and <code>TextModding<\/code> end.<\/p>\n<pre class=\"lang:c# theme:vs2012\">void MeshModding()\r\n{\r\n\tstring[] meshModPaths = Directory.GetFiles(pathToMods + \"\/\", \"*.fbx\");\r\n\tstring modToUse = \"mod\";\r\n\tstring extensionToRemove = \".fbx\";\r\n\tif (meshModPaths.Length == 1)\r\n\t{\r\n\t\tmodToUse = Path.GetFileName(meshModPaths[0]);\r\n\t\tmodToUse = modToUse.Replace(extensionToRemove, \"\");\r\n\t\tmf.mesh = Resources.Load&lt;Mesh&gt;(modToUse);\r\n\t}\r\n\telse if (meshModPaths.Length &gt; 1)\r\n\t{\r\n\t\tint file = Random.Range(0, meshModPaths.Length);\r\n\t\tmodToUse = Path.GetFileName(meshModPaths[file]);\r\n\t\tmodToUse = modToUse.Replace(extensionToRemove, \"\");\r\n\t\tmf.mesh = Resources.Load&lt;Mesh&gt;(modToUse);\r\n\t}\r\n}<\/pre>\n<p>The basic idea is still intact, but the execution is somewhat different. Notice the two additional string variables declared alongside the string array. Your <code>modToUse<\/code> variable is simply the name of the mod to use, and you just give it a placeholder name. After this comes another string variable named <code>extensionToRemove<\/code>. As it turns out, a function you use later doesn&#8217;t like having extensions in the name of the file to search for. To get around this, you just specify which part of the text you wish to remove from the variable and use <em>Replace <\/em>to rid the variable of the extension.<\/p>\n<p>At the last line, you call <code>Resources<\/code><em>.<\/em><code>Load<\/code> to load the <em>fbx<\/em> file into the game. Recall the <em>Resources <\/em>folder you had the program create thanks to <code>DirectoryCreation<\/code>. This function will specifically search the <em>Resources <\/em>folder in your game for whichever file you tell it to load. In this case, it&#8217;s whatever the name of the file stored in <code>modToUse<\/code> would be minus the extension. As expected, you also specify that it will be loaded as a mesh to make Unity happy. Figure 11 shows the function.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"614\" height=\"321\" class=\"wp-image-83241\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-26.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 11: <em>MeshModding <\/em>function<\/p>\n<p>This concludes the coding section of this project. To summarize, you have granted a user the ability to modify text by reading a <em>txt<\/em> file that they create. You also allowed them to change the mesh of the object in the scene by placing an <em>fbx<\/em> file in the <em>Resources <\/em>folder. Close Visual Studio and head back to the Unity project.<\/p>\n<h2>Finishing the Project<\/h2>\n<p>Select the <em>GameManager <\/em>object in the <em>Hierarchy<\/em> and drag <em>ModScript <\/em>from the <em>Assets <\/em>window into the <em>Inspector<\/em>, attaching the script to the object as shown in Figure 12.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"859\" height=\"626\" class=\"wp-image-83242\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-27.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 12: Attaching <em>ModScript <\/em>to <em>GameManager<\/em><\/p>\n<p>Next, comes the assignment of the <em>Message Text <\/em>and <em>Mf<\/em> variables. Find your <em>Text <\/em>object that you created earlier and drag that to the <em>Message Text <\/em>field in the newly created <em>ModScript <\/em>component. Then take the <em>Cube <\/em>object and drag it to the <em>Mf <\/em>field. Once you have these in place, the Inspector should look like Figure 13.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"950\" height=\"285\" class=\"wp-image-83243\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-28.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 13: Applying <em>Text <\/em>and <em>Cube <\/em>to their corresponding variables<\/p>\n<p>There&#8217;s nothing else that needs to be done now. Does this mean the project is finished? Well, yes and no. You can and should run the project in Unity to create the <em>Resources <\/em>folder, but the project itself won&#8217;t do anything you haven&#8217;t already set up. But that&#8217;s the point. The idea is you create your base game, and then somebody else can come in later and modify certain aspects of it. In this case, go ahead and pretend to be that somebody. But first be sure to run the program so the <em>Resources <\/em>folder is created as shown in Figure 14.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"253\" height=\"112\" class=\"wp-image-83244\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-29.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 14: That folder wasn&#8217;t there before&#8230;<\/p>\n<p>Begin by adding a mesh for the game to pull from. So long as the mesh is an <em>fbx<\/em> file, the program will work just fine. This example will use a model of a barrel found <a href=\"https:\/\/3dexport.com\/free-3dmodel-barrel-open-223077.htm\">here<\/a>. Once you&#8217;ve got your model, whether it be the barrel example or something else entirely, use Windows Explorer to navigate to the <em>Resources <\/em>folder of your project. Place that <em>fbx<\/em> file in this folder.<\/p>\n<p>The text modding functionality is even simpler. Simply create a new <em>txt<\/em> file and place it somewhere in the folder. You may name the text file anything you like. Open the file and enter whatever text you wish as shown in Figure 15.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"910\" height=\"362\" class=\"wp-image-83245\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-30.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 15: Adding files to the <em>Resources <\/em>directory and writing text to a txt file<\/p>\n<p>Now enter Unity once again. Your users wouldn&#8217;t normally see this, but Unity will detect these files and update the <em>Assets <\/em>window. Now try running the game again. You should see the text change and the basic mesh of the <em>Cube <\/em>object replaced with whatever you placed as shown in Figure 16. Note: you may need to edit the scale value of the object to better see the modded mesh.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"860\" height=\"376\" class=\"wp-image-83246\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-31.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 16: The (modified) game in action!<\/p>\n<h2>Conclusion<\/h2>\n<p>As pointed out in the introduction, this is only meant to be a simple intro to the absolute basics of modding. But feel free to pat yourself on the back, for this small project you created has more modding capabilities than many games get, officially or otherwise. This example introduced you to allow other users to change some of the game text and meshes your game might use. Furthermore, it was simple too. If you&#8217;ve ever tried to mod a game yourself, you might find that it can be somewhat difficult. Here, the process has been simplified so those who wish to mod the project can do so quickly.<\/p>\n<p>Of course, how much further you would take this is up to you, and it all depends on if you even want to build your game with modding in mind. To do that you&#8217;ll need to create a system that works for you as well as other users. Perhaps you should have the game search for specific filenames? What about texturing a mesh? In this example, the mesh that you modded into your game used the texture the <em>Cube <\/em>object did. If you can change out a 3D object, it stands to reason you can also change the texture attached to that object. Experiment and see what you can discover, both for yourself and your users.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s even more fun to play a game when you can customize it, but creating such a game is more difficult for the game developer. In this article, Lance Talbert shows you how to add some simple modifications to games you create with Unity and VS. &hellip;<\/p>\n","protected":false},"author":317499,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538,53],"tags":[],"coauthors":[52549],"class_list":["post-83230","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","category-featured"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83230","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/317499"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=83230"}],"version-history":[{"count":4,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83230\/revisions"}],"predecessor-version":[{"id":83248,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83230\/revisions\/83248"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=83230"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=83230"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=83230"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=83230"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}