{"id":85049,"date":"2019-08-20T14:36:41","date_gmt":"2019-08-20T14:36:41","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=85049"},"modified":"2021-07-29T19:44:06","modified_gmt":"2021-07-29T19:44:06","slug":"customizable-characters-in-unity","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/customizable-characters-in-unity\/","title":{"rendered":"Customizable Characters in Unity"},"content":{"rendered":"<p>The ability to change the appearance of the player-controlled character is practically a staple of video games. Some will argue that the appearance of the character is more important than the statistics or personalities of the characters themselves. A player often wants to put themselves in the game\u2019s world, and the outward appearance of the one they are controlling is often the first way to accomplish this task. Creating the art for the character is most of the work itself, but of course, programmers have to develop the tools for the user to take advantage of it. As it turns out, developing those tools is easier than you may think.<\/p>\n<p>This project will demonstrate how a character creator is made as well as how the character can retain its attributes from one scene to the next. As you may have guessed, there are several parts to the character creator itself, so this article will focus on the code to save time. That said, an overview will still be done to give you an idea of how the project will look and function once it&#8217;s complete. If you wish to follow along, you can download a version of the <a href=\"https:\/\/github.com\/prof-smash\/CustomCharacter-without-code\">project without code<\/a>. Also, there is a <a href=\"https:\/\/github.com\/prof-smash\/CustomCharacter-complete\">code completed project<\/a> you can refer to as well.<\/p>\n<h2>The Project<\/h2>\n<p>To open a pre-existing project, you will first open Unity and click <em>Open. <\/em><\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1002\" height=\"130\" class=\"wp-image-85062\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-12.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 1: Opening a project<\/p>\n<p>After this, navigate to the folder containing the project. Select the folder with the Unity project within it, then click the <em>Select Folder <\/em>button that appears in the bottom right<em>. <\/em>Once this is done, the project will begin loading. Keep in mind that you may have to navigate lower into another folder before finding the correct directory that Unity can open.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"782\" height=\"448\" class=\"wp-image-85063\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-13.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 2: Selecting the project to be opened.<\/p>\n<p>Once loaded, you&#8217;ll be greeted with a project that looks like the figure below:<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"882\" height=\"443\" class=\"wp-image-85064\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-14.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 3: The character creator project<\/p>\n<p>The screen won&#8217;t appear this way when testing the project in full-screen mode. This appearance is due to the way Unity is currently drawing the user interface (UI) in the game view. Right away, you&#8217;ll see a very menu-based project with several buttons and a scrollbar. The buttons, in particular, were created from a single button that was duplicated multiple times. Once all buttons are created in this manner, all that remains is adjusting their position, size, and image. There are an input field and a button saying \u201cto next scene\u201d on the right side of the screen. In the middle behind the UI objects is the user&#8217;s character, ready to be customized. The assets being used for the character come from the <em>Custom Character 2D Vol. 1 <\/em>asset from the Unity asset store. You can view these assets from its respective asset store page <a href=\"https:\/\/assetstore.unity.com\/packages\/2d\/characters\/custom-character-2d-vol-1-65144\">here<\/a>.<\/p>\n<p>Over in the <em>Hierarchy, <\/em>you can get a better idea of just how much is in the project. Expanding <em>UI-&gt;CharacterCreatorBackground-&gt;OptionsContainer-&gt;Content <\/em>reveals the different sections that the user will be able to change to their likings, such as the eyes and hairstyles. Expanding the different sections from there shows the individual buttons that make up each section. There&#8217;s a total of thirty-seven different buttons in the entire character creator menu!<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"332\" height=\"497\" class=\"wp-image-85065\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-15.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 4: List of objects.<\/p>\n<p>The last items of note are the two different scenes given the precise names of <em>SampleScene <\/em>and <em>New Scene<\/em>. Currently, you&#8217;re looking at <em>SampleScene<\/em>. You can double-click <em>New Scene <\/em>found in the <em>Scenes<\/em> folder in the <em>Assets<\/em> window to check out what&#8217;s inside that area if you wish, but there isn&#8217;t much. A salmon pink color with some white text that appears unfinished is all that lies within this scene. When the project is complete, this scene will have the newly created character along with some new text to demonstrate persistence between scenes.<\/p>\n<p>For now, it&#8217;s recommended to have <em>SampleScene <\/em>opened as that&#8217;s where most of the action will take place. Now that you&#8217;re familiar with all the pieces bringing the project together, it&#8217;s time to create the code that will make your character creator operate. In the <em>Scripts <\/em>folder, you&#8217;ll need to create three C# scripts. The names of these scripts are in the figure below:<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"317\" height=\"106\" class=\"wp-image-85066\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-16.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 5: All scripts<\/p>\n<h2>The CustomChar Script<\/h2>\n<p><em>CustomChar <\/em>is an excellent place to begin as its purpose is to hold all the various pieces that make up the character. <code>Update<\/code> can be deleted or commented out as it will not be needed.<\/p>\n<pre class=\"lang:c# theme:vs2012\">public SpriteRenderer hairBack;\r\npublic SpriteRenderer hairFront;\r\npublic SpriteRenderer ear;\r\npublic SpriteRenderer body;\r\npublic SpriteRenderer eyebrow;\r\npublic SpriteRenderer eye;\r\npublic SpriteRenderer mouth;\r\npublic SpriteRenderer effect;\r\npublic SpriteRenderer faceOption;\r\npublic string charName;\r\nvoid Start()\r\n{\r\n\tDontDestroyOnLoad(this);\r\n}<\/pre>\n<p>Several <code>SpriteRenderer<\/code> variables are declared with a name that relates to what part of the customized character that&#8217;s being edited. For example, the <em>ear <\/em>variable will hold the character&#8217;s ear sprite. At the end of this list of variables is a string, called <code>charName<\/code>. This variable will contain the string the user inputs into the input field from earlier. In both of your scenes, some text will change to show the user&#8217;s name along with the remainder of a message. Finally, in the <code>Start<\/code> function, you have <code>DontDestroyOnLoad<\/code> called and given a target. When loading a new scene, all objects in the current scene would ordinarily get destroyed. If you wish for an object to persist throughout scenes, such as your custom character, then <code>DontDestroyOnLoad<\/code> will preserve this object and bring it into any new scene that is loaded.<\/p>\n<p>The <em>CustomChar <\/em>script is now complete. <code>UIManager<\/code> is up next, and as you can imagine, it has a lot more going on, however, there are ways to simplify the coding process.<\/p>\n<h2>The UIManager Script<\/h2>\n<p>First, you&#8217;ll need to delete or comment out <code>Start<\/code> and <code>Update<\/code><em>.<\/em> After that, you&#8217;ll also want to add <code>using<\/code> <code>UnityEngine.UI<\/code> and <code>using UnityEngine.SceneManagement<\/code> in order to perform certain tasks. Then you move on to the variable declaration:<\/p>\n<pre class=\"lang:c# theme:vs2012\">[SerializeField]\r\nprivate CustomChar cc;\r\npublic InputField nameInput;\r\npublic Text message;<\/pre>\n<p>You might think that some <code>Sprite<\/code> variables are missing for the different parts of the character, but what you&#8217;ll see later on is that the various button functions can take care of sprite assignment for you. While you can certainly create arrays to hold the different sprites, it would be far easier to give the function a parameter that you can fill in from the Unity Editor. What&#8217;s more, there&#8217;s no need to do one function for each button. You can instead create one function for each type of character part and let the parameter take care of the rest. The function will look like this:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public void HairBackAssign(Sprite selection)\r\n{\r\n\tcc.hairBack.sprite = selection;\r\n}<\/pre>\n<p>This particular function would be given to the buttons that deal with the character&#8217;s back hair. All it does is get the <em>CustomChar <\/em>script, get the correct <code>SpriteRenderer<\/code> from it, and assign that <code>SpriteRenderer<\/code> the <code>selection<\/code> Sprite. All the other buttons follow a similar pattern with some minor differences. Table 1 shows all the functions and the corresponding code for each function.<\/p>\n<p class=\"caption\">Table 1: All functions and their code<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p><strong>Function Name<\/strong><\/p>\n<\/td>\n<td>\n<p><strong>Code<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>HairBackAssign(Sprite selection)<\/p>\n<\/td>\n<td>\n<p>cc.hairBack.sprite = selection;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>HairFrontAssign(Sprite selection)<\/p>\n<\/td>\n<td>\n<p>cc.hairFront.sprite = selection;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BodyAssign(Sprite selection)<\/p>\n<\/td>\n<td>\n<p>cc.body.sprite = selection;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EarAssign(Sprite selection)<\/p>\n<\/td>\n<td>\n<p>cc.ear.sprite = selection;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyeAssign(Sprite selection)<\/p>\n<\/td>\n<td>\n<p>cc.eye.sprite = selection;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyebrowAssign(Sprite selection)<\/p>\n<\/td>\n<td>\n<p>cc.eyebrow.sprite = selection;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthAssign(Sprite selection)<\/p>\n<\/td>\n<td>\n<p>cc.mouth.sprite = selection;<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Not all the button functions are complete though. There&#8217;s an extras section in the character creator which allows you to put glasses on the character and have them create a fireball. Where are the functions for those? They operate a little differently as neither the glasses or fireball have additional images that they could be. Instead, the buttons for those extras will enable or disable the item.<\/p>\n<pre class=\"lang:c# theme:vs2012\">public void EffectOn()\r\n{\r\n\tif (cc.effect.enabled == true)\r\n\t\tcc.effect.enabled = false;\r\n\telse\r\n\t\tcc.effect.enabled = true;\r\n}\r\npublic void FaceOptionOn()\r\n{\r\n\tif (cc.faceOption.enabled == true)\r\n\t\tcc.faceOption.enabled = false;\r\n\telse\r\n\t\tcc.faceOption.enabled = true;\r\n}<\/pre>\n<p>The functions check if the sprite renderer for the fireball and the glasses is enabled or not. Depending on the answer it will reenable or disable the extras as needed. To complete the script, some assignments will need to be given to the button saying \u201cto next scene\u201d and the input field.<\/p>\n<pre class=\"lang:c# theme:vs2012\">public void UpdateText()\r\n{\r\n\tcc.charName = nameInput.text;\r\n\tmessage.text = \"Hello! My name is... \" + cc.charName;\r\n}\r\npublic void ToNextScene()\r\n{\r\n\tSceneManager.LoadScene(\"New Scene\");\r\n}<\/pre>\n<p><code>UpdateText<\/code>, unlike all the other functions in this script, will be called every time the value of the input field changes. This is being done so you can watch the text in the same scene update in real-time. It also will assign the text in the input field to the <code>charName<\/code> variable in <code>CustomChar<\/code>. The final function, <code>ToNextScene<\/code>, calls <code>SceneManager<\/code> to load <em>New Scene. <\/em>Speaking of <em>New Scene<\/em>, there&#8217;s one final script that needs coding for the code of this project to be complete.<\/p>\n<h2>The NewLevelText Script<\/h2>\n<p>Open the <em>NewLevelText <\/em>script, remove or comment out <code>Update<\/code>, add <code>using UnityEngine.UI<\/code> to the top, then enter the following:<\/p>\n<pre class=\"lang:c# theme:vs2012\">private Text levelText;\r\nvoid Start()\r\n{\r\n\tstring character = GameObject.Find(\"Character\").GetComponent&lt;CustomChar&gt;().charName;\r\n\tlevelText = GetComponent&lt;Text&gt;();\r\n\tlevelText.text = \"Greetings! I am \" + character + \", and I hope you have a wonderful day!\";\r\n}<\/pre>\n<p>Used in <em>New Scene<\/em>, this script will find the character you create, get the <em>CustomChar <\/em>script and get <code>charName<\/code>. Then <code>NewLevelText<\/code> gets the <code>Text<\/code> component of the object to which it&#8217;s attached. Finally, it updates the level&#8217;s message to include the character&#8217;s name.<\/p>\n<p>Save the code in Visual Studio and head back to Unity.<\/p>\n<h2>Completing the Project<\/h2>\n<p>Perhaps the most important script in the entire project goes to the <em>Manager <\/em>object. With the object selected, click and drag <em>UIManager <\/em>into the <em>Inspector <\/em>window to attach the script.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"906\" height=\"663\" class=\"wp-image-85067\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-17.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 6: Attaching the <em>UIManager <\/em>component to the <em>Manager <\/em>object.<\/p>\n<p>You should also do the same for the <em>Character <\/em>object and the <em>CustomChar <\/em>script.<\/p>\n<p>Back at the <em>Manager <\/em>object, assign <em>Character <\/em>to <em>cc<\/em>, <em>NameInput<\/em> to <em>UIManager&#8217;s<\/em> <em>NameInput<\/em>, and <em>MyNameIs <\/em>to <em>Message<\/em>.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1022\" height=\"271\" class=\"wp-image-85068\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-18.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 7: Assigning component fields<\/p>\n<p>Next, you&#8217;ll need to tell Unity of all the different sprite renderers that make up the character. Expand the <em>Character <\/em>object in the <em>Hierarchy,<\/em> followed by expanding the <em>Face <\/em>child object to get all the different parts of the character. Then, with <em>Character <\/em>selected, click and drag all the different character parts into their respective fields in the <em>CustomChar <\/em>component.<\/p>\n<p class=\"caption\">Figure 8: Assigning the various character pieces to their respective fields.<\/p>\n<p>Now comes the assignment of functions to UI elements. Starting with the <em>NameInput <\/em>field, find the <em>On Value Changed <\/em>event in the <em>Input Field <\/em>component within the <em>Inspector <\/em>window. Once located, click and drag the <em>Manager <\/em>object into the <em>Object <\/em>field. From there, select the button currently saying <em>No Function<\/em>. From the drop-down menu that appears, navigate to <em>UIManager-&gt;UpdateText()<\/em>.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"603\" height=\"277\" class=\"wp-image-85070\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-20.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 9: The function assigned to the input field&#8217;s <em>On Value Changed <\/em>event.<\/p>\n<p>Similarly, you&#8217;ll need to give <em>ToNextScene <\/em>the <em>ToNextScene <\/em>function by finding the button&#8217;s <em>Button <\/em>component looking for the <em>OnClick <\/em>event. Once again, drag in Manager. This time look for the <em>ToNextScene<\/em> function.<\/p>\n<p>All that remains after this is to assign all the character creator buttons to their respective functions as well as fill in the required parameter. Given the large number of buttons to work with a table will be provided showing the different buttons, the function to use, and which sprite to use for each button. But first, a quick example of how to handle these assignments as well as where to find the images in the first place.<\/p>\n<p>First, you should navigate to the sprites to be used. In the <em>Assets <\/em>folder, navigate to <em>Custom Character_Vol 1-&gt;png-&gt;character<\/em>. From here, there are several folders corresponding to the various character pieces. Going into any of these folders will reveal the sprites you&#8217;ll need to fill parameters. Be aware that some of the files come as individual sprites while others are sprite sheets which are files with multiple images in a single file that get separated in Unity. Like with child objects in the <em>Hierarchy<\/em>, in these cases, you&#8217;ll need to expand the sheet to find the individual images.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"932\" height=\"412\" class=\"wp-image-85071\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-21.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 10: Comparison of sprites with and without sprite sheet.<\/p>\n<p>As for assigning functions to buttons, it&#8217;s the same as the <em>ToNextScene <\/em>button as before but with an additional step. Once again, you&#8217;ll set <em>Manager <\/em>as the object in the <em>On Click <\/em>event followed by selecting the correct function. After that, a field will appear below the function drop-down menu asking for a sprite. Click and drag an image from the <em>Assets <\/em>window into this field to complete the button. Look for the buttons in the <em>Hierarchy<\/em> at <em>UI \uf0e0 CharacterCreatorBackground \uf0e0 OptionsContainer \uf0e0 Content<\/em>.<\/p>\n<p>Figure 11 uses the <em>BodyOption1 <\/em>button as an example.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1057\" height=\"565\" class=\"wp-image-85072\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-22.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 11: BodyOption1 button being given a function and sprite.<\/p>\n<p>Using the table below, assign the character creator buttons to the correct functions and make sure they use the correct sprite. The codeless version of the project may fill the sprites in automatically after assigning the button function. This is due to some changes I made to the project before uploading it to GitHub. Though convenient, it is recommended you at least check the correct sprite is being used. It is also worth noting that the below table will specify if the sprite is found within a sprite sheet. Note that the button objects found in <em>Extras <\/em>will not need a sprite. This will also be specified in the table.<\/p>\n<p class=\"caption\">Table 2: All character creator buttons, their functions, and sprites.<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p><strong>Button Object<\/strong><\/p>\n<\/td>\n<td>\n<p><strong>Function<\/strong><\/p>\n<\/td>\n<td>\n<p><strong>Sprite<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BodyOption1<\/p>\n<\/td>\n<td>\n<p>BodyAssign()<\/p>\n<\/td>\n<td>\n<p>body1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BodyOption2<\/p>\n<\/td>\n<td>\n<p>BodyAssign()<\/p>\n<\/td>\n<td>\n<p>body2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BodyOption3<\/p>\n<\/td>\n<td>\n<p>BodyAssign()<\/p>\n<\/td>\n<td>\n<p>body3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BodyOption4<\/p>\n<\/td>\n<td>\n<p>BodyAssign()<\/p>\n<\/td>\n<td>\n<p>body4<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BackHairOption1<\/p>\n<\/td>\n<td>\n<p>HairBackAssign()<\/p>\n<\/td>\n<td>\n<p>h_b_a1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BackHairOption2<\/p>\n<\/td>\n<td>\n<p>HairBackAssign()<\/p>\n<\/td>\n<td>\n<p>h_b_a2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BackHairOption3<\/p>\n<\/td>\n<td>\n<p>HairBackAssign()<\/p>\n<\/td>\n<td>\n<p>h_b_a3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BackHairOption4<\/p>\n<\/td>\n<td>\n<p>HairBackAssign()<\/p>\n<\/td>\n<td>\n<p>h_b_b1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BackHairOption5<\/p>\n<\/td>\n<td>\n<p>HairBackAssign()<\/p>\n<\/td>\n<td>\n<p>h_b_b2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BackHairOption6<\/p>\n<\/td>\n<td>\n<p>HairBackAssign()<\/p>\n<\/td>\n<td>\n<p>h_b_b3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>FrontHairOption1<\/p>\n<\/td>\n<td>\n<p>HairFrontAssign()<\/p>\n<\/td>\n<td>\n<p>h_f_a1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>FrontHairOption2<\/p>\n<\/td>\n<td>\n<p>HairFrontAssign()<\/p>\n<\/td>\n<td>\n<p>h_f_a2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>FrontHairOption3<\/p>\n<\/td>\n<td>\n<p>HairFrontAssign()<\/p>\n<\/td>\n<td>\n<p>h_f_a3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>FrontHairOption4<\/p>\n<\/td>\n<td>\n<p>HairFrontAssign()<\/p>\n<\/td>\n<td>\n<p>h_f_b1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>FrontHairOption5<\/p>\n<\/td>\n<td>\n<p>HairFrontAssign()<\/p>\n<\/td>\n<td>\n<p>h_f_b2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>FrontHairOption6<\/p>\n<\/td>\n<td>\n<p>HairFrontAssign()<\/p>\n<\/td>\n<td>\n<p>h_f_b3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EarOption1<\/p>\n<\/td>\n<td>\n<p>EarAssign()<\/p>\n<\/td>\n<td>\n<p>face_ear_00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EarOption2<\/p>\n<\/td>\n<td>\n<p>EarAssign()<\/p>\n<\/td>\n<td>\n<p>face_ear_01<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyeOption1<\/p>\n<\/td>\n<td>\n<p>EyeAssign()<\/p>\n<\/td>\n<td>\n<p>eye_4 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyeOption2<\/p>\n<\/td>\n<td>\n<p>EyeAssign()<\/p>\n<\/td>\n<td>\n<p>eye_5 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyeOption3<\/p>\n<\/td>\n<td>\n<p>EyeAssign()<\/p>\n<\/td>\n<td>\n<p>eye_6 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyeOption4<\/p>\n<\/td>\n<td>\n<p>EyeAssign()<\/p>\n<\/td>\n<td>\n<p>eye_7 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyeOption5<\/p>\n<\/td>\n<td>\n<p>EyeAssign()<\/p>\n<\/td>\n<td>\n<p>eye_8 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyebrowOption1<\/p>\n<\/td>\n<td>\n<p>EyebrowAssign()<\/p>\n<\/td>\n<td>\n<p>eye_0 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyebrowOption2<\/p>\n<\/td>\n<td>\n<p>EyebrowAssign()<\/p>\n<\/td>\n<td>\n<p>eye_1 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyebrowOption3<\/p>\n<\/td>\n<td>\n<p>EyebrowAssign()<\/p>\n<\/td>\n<td>\n<p>eye_2 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>EyebrowOption4<\/p>\n<\/td>\n<td>\n<p>EyebrowAssign()<\/p>\n<\/td>\n<td>\n<p>eye_3 (found in eye sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthOption1<\/p>\n<\/td>\n<td>\n<p>MouthAssign()<\/p>\n<\/td>\n<td>\n<p>mouth_0 (found in mouth sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthOption2<\/p>\n<\/td>\n<td>\n<p>MouthAssign()<\/p>\n<\/td>\n<td>\n<p>mouth_1 (found in mouth sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthOption3<\/p>\n<\/td>\n<td>\n<p>MouthAssign()<\/p>\n<\/td>\n<td>\n<p>mouth_2 (found in mouth sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthOption4<\/p>\n<\/td>\n<td>\n<p>MouthAssign()<\/p>\n<\/td>\n<td>\n<p>mouth_3 (found in mouth sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthOption5<\/p>\n<\/td>\n<td>\n<p>MouthAssign()<\/p>\n<\/td>\n<td>\n<p>mouth_4 (found in mouth sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthOption6<\/p>\n<\/td>\n<td>\n<p>MouthAssign()<\/p>\n<\/td>\n<td>\n<p>mouth_5 (found in mouth sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthOption7<\/p>\n<\/td>\n<td>\n<p>MouthAssign()<\/p>\n<\/td>\n<td>\n<p>mouth_6 (found in mouth sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>MouthOption8<\/p>\n<\/td>\n<td>\n<p>MouthAssign()<\/p>\n<\/td>\n<td>\n<p>mouth_7 (found in mouth sprite sheet)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>ExtraOption1<\/p>\n<\/td>\n<td>\n<p>FaceOptionOn()<\/p>\n<\/td>\n<td>\n<p>N\/A<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>ExtraOption2<\/p>\n<\/td>\n<td>\n<p>EffectOn()<\/p>\n<\/td>\n<td>\n<p>N\/A<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Save your work. Go into <em>New Scene <\/em>by double-clicking the name in the<em> Scene<\/em> folder in the<em> Assets. <\/em>Find the <em>Text <\/em>object under <em>Canvas<\/em>. Once found, attach the <em>NewLevelText <\/em>component to it. After you finish that, save the scene and go back back to <em>SampleScene <\/em>and give the character creator a try.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1523\" height=\"755\" class=\"wp-image-85073\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/08\/word-image-23.jpeg\" \/> Figure 12: Character created in the previous scene persists into the new scene with <em>DontDestroyOnLoad<\/em>.<\/p>\n<h2>Conclusion<\/h2>\n<p>The two main takeaways from this project come from the button functions and <em>DontDestroyOnLoad<\/em>. Both simple items but can make game development much easier, especially when it comes to the more complex tasks like a character creator. Using parameters helped lower the number of lines in the code and kept everything tidy. <em>DontDestroyOnLoad <\/em>demonstrated the simplest way to have an object persist between scenes, thus eliminating the need to rebuild complex objects each time it&#8217;s required. All of this was shown in the context of character creators, but it could be used in other places such as stat keeping and tracking decisions the user makes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the hallmark features of video games is the ability to choose or even customize your character. In this article, Lance Talbert shows how easy it is to let the player create custom characters for your game, especially when you can take advantage of premade image assets available online. &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-85049","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\/85049","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=85049"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/85049\/revisions"}],"predecessor-version":[{"id":85076,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/85049\/revisions\/85076"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=85049"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=85049"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=85049"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=85049"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}