{"id":564,"date":"2025-04-07T13:44:44","date_gmt":"2025-04-07T13:44:44","guid":{"rendered":"https:\/\/sites.wsagames.com\/sc18g23\/?p=564"},"modified":"2025-04-07T13:44:44","modified_gmt":"2025-04-07T13:44:44","slug":"ability-multiplier-text-ui-playtesting-sessions-checkpoints-main-menu-settings-removing-ability-multiplier","status":"publish","type":"post","link":"https:\/\/sites.wsagames.com\/sc18g23\/2025\/04\/07\/ability-multiplier-text-ui-playtesting-sessions-checkpoints-main-menu-settings-removing-ability-multiplier\/","title":{"rendered":"Ability Multiplier Text UI, Playtesting sessions, Checkpoints, Main Menu, Settings, Removing Ability Multiplier"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Ability Multiplier Text UI<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One of the first things I did this week was add a UI element to the HUD to indicate to the player the Ability Multiplier strength. This was surprisingly difficult to pull off, as I had to modify the UI of the ability selection scene a couple of times to get all the alignment elements to work, but eventually I was able to get it hooked up to the AbilitySelectionHUD.cs script.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bouncing Issues<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"615\" src=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.13.33-1024x615.png\" alt=\"\" class=\"wp-image-593\" srcset=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.13.33-1024x615.png 1024w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.13.33-300x180.png 300w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.13.33-768x461.png 768w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.13.33-1536x922.png 1536w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.13.33-850x510.png 850w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.13.33.png 1666w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Playtest 1 (Thursday)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There was a play testing session for all of the groups projects on Thursday, where people could come in and test the groups games out. The event was fairly busy, and I wasn&#8217;t able to write any notes, but my teammates did and Guy shared what I needed to do on Discord.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"386\" src=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.04.41-1024x386.png\" alt=\"\" class=\"wp-image-591\" srcset=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.04.41-1024x386.png 1024w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.04.41-300x113.png 300w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.04.41-768x290.png 768w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.04.41-850x320.png 850w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.04.41.png 1406w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">I immediately began to work on fixing these issues. I asked Guy for clarification on the last point as I wasn&#8217;t sure what he meant and he didn&#8217;t respond.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checkpoints<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One of the suggestions I got from Guy while we here play testing the game on Thursday was to add checkpoints to the game. This would involve some rewriting of the code, particularly in the GameManager script, where the game scene reloaded when the player died. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One of the first things I did for this was create a GameObject called Checkpoints and a script of the same name. The functionality of this script is fairly simple, when the player passes through the GameObject&#8217;s trigger, it checks to see if the bool for (insert name) is active, if it is, the function returns. If it isn&#8217;t, then the Object will tell the GameManager&#8217;s variable what position it is, the bool will then become true. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class Checkpoint : MonoBehaviour\n{\n    private bool _hasPassedCheckpoint;\n    private GameManager _gameManager;\n    public TextMeshProUGUI checkpointReachedTxt;\n    &#091;SerializeField] private Vector3 checkpointPositionOpen;\n    &#091;FormerlySerializedAs(\"_xPosition\")] public float xPosition = 420f;\n\n    private void Start()\n    {\n        _gameManager = FindObjectOfType&lt;GameManager&gt;();\n    }\n\n    private void OnTriggerEnter(Collider other)\n    {\n        if (!other.gameObject.CompareTag(\"Player\") || _hasPassedCheckpoint) return;\n        \/\/ set _hasPassedCheckpoint;\n        _hasPassedCheckpoint = true;\n        \/\/ Set checkpoint in GameManager.\n        _gameManager.lastCheckpoint = transform.position;\n        \/\/ Indicate in UI that player has passed checkpoint.\n        checkpointReachedTxt.gameObject.SetActive(true);\n        \/\/ Set a coroutine to disable UI after 3 seconds. \n        StartCoroutine(ResetCheckpointReachedTxt());\n    }\n\n    IEnumerator ResetCheckpointReachedTxt()\n    {\n        yield return new WaitForSeconds(3f);\n        checkpointReachedTxt.gameObject.SetActive(false);\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When the player dies, the GameManager will first disable the player character, then after a few seconds it will set the player&#8217;s location to that of its last checkpoint and then reenable the player object.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    public IEnumerator ResetGame()\n    {\n        _player.gameObject.SetActive(false);\n        yield return new WaitForSeconds(_reloadTime);\n        ResetPlayerAtCheckpoint();\n        ResetInteractables();\n    }<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>    void ResetPlayerAtCheckpoint()\n    {\n        _player.transform.position = lastCheckpoint;\n        _player.gameObject.SetActive(true);\n        var rb = _player.GetComponent&lt;Rigidbody&gt;();\n        rb.velocity = Vector3.zero;\n    }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Ability Multiplier Removal<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One of the pieces of feedback I got from this play testing session was to remove the ability multiplier and replace it with a fixed number that&#8217;d be used for the gravity ability. This was fairly easy to do. All I really had to do was yank out the scrolling functions that the PlayerInput, which severed the ability entirely. There was already a variable that managed the amount of force an object would get, so I simply doubled it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Main Menu\/Settings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To prepare for the play test the following day I also worked to make a Main Menu and a Settings screen for the game, that way, it wouldn&#8217;t immediately jump into the action. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first thing I did for the Main Menu and the Settings was to make a new scene called menu by duplicating a previous scene and deleting most of the game-related objects in the scene, including the player. I kept the world though for a backdrop and the EventSystem to ensure the UI worked. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"590\" height=\"354\" src=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.38.53.png\" alt=\"\" class=\"wp-image-600\" srcset=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.38.53.png 590w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.38.53-300x180.png 300w\" sizes=\"(max-width: 590px) 100vw, 590px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see, there are 2 GameObjects called MainMenu and Settings, which are both Canvas. They also have their own scripts, mainly disable one and enable the other. The MainMenu script also has a play button, which opens the game, while the settings script has a few more functions relating to adjusting the in-game settings. At the moment it doesn&#8217;t do much but I expanded upon the script in the following week.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class MainMenu : MonoBehaviour\n{\n    &#091;SerializeField] GameObject settingsMenu;\n    public void StartGame()\n    {\n        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);\n    }\n\n    public void OpenSettingsMenu()\n    {\n        settingsMenu.SetActive(true);\n        gameObject.SetActive(false);\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;d also obtained a logo by contacting Parker, who instructed me to go to the game&#8217;s GDD page.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"724\" src=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.39.21-1024x724.png\" alt=\"\" class=\"wp-image-601\" srcset=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.39.21-1024x724.png 1024w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.39.21-300x212.png 300w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.39.21-768x543.png 768w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.39.21-850x601.png 850w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-07-at-14.39.21.png 1154w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Cool Down<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One suggestion I got from Guy was to create a cooldown for the player&#8217;s abilities. This was easy to do and I was able to get it down the same day.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"529\" src=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.03.42-1024x529.png\" alt=\"\" class=\"wp-image-590\" srcset=\"https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.03.42-1024x529.png 1024w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.03.42-300x155.png 300w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.03.42-768x397.png 768w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.03.42-850x439.png 850w, https:\/\/sites.wsagames.com\/sc18g23\/wp-content\/uploads\/sites\/9\/2025\/04\/Screenshot-2025-04-04-at-11.03.42.png 1216w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">What I did was this: I made a new bool variable called _abilityIsCoolingDown. If the player attempts to get up the ability menu, and _abilityIsCoolingDown is true, then the function will return and the player won&#8217;t able to cast an ability. Then, in the Casting function, I will start a Coroutine called CoolDownAbility which will make _abilityIsCoolingDown to true, wait for the cooldownTime variable, currently 5 seconds, and then turn it to false.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public void <strong>OnAbilityInteract<\/strong>(InputAction.CallbackContext context)\n{\n    if (_abilityIsCoolingDown) return;\n}\n\nprivate void Casting()\n    {\n        \/\/ enable cinemachine\n        cinemachineCamera.gameObject.SetActive(true);\n        abilitySelectionHUD.gameObject.SetActive(false);\n        selectionArea.gameObject.SetActive(true);\n        PerformAbility(currentAbility, selectionArea.GetObjects(), selectionArea.GetRadius());\n        abilityCharge--;\n        Debug.Log($\"Ability Charge: {abilityCharge}\");\n        selectionArea.gameObject.SetActive(false);\n        _abilityStageIndex = 0;\n        StartCoroutine(CoolDownAbility());\n}\n\n\n\nIEnumerator CoolDownAbility()\n    {\n        _abilityIsCoolingDown = true;\n        yield return new WaitForSeconds(cooldownTime);\n        _abilityIsCoolingDown = false;\n    }<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Playtest 2 (Friday)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The second playtest took place on a Friday at 10:30 AM. One mistake I&#8217;d made was not realizing that the playtest would take place on the same day and time as my business studies lesson. However, it turned out alright in the end since there wasn&#8217;t much teaching going on for that day and in fact, she encouraged the class to go to the computer rooms to try out the game. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first person to try out the game was my business studies teacher. I could see that she was struggling with knowing what to do in the game and, a common theme throughout the playtests, didn&#8217;t know where to go. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In total, I had about 7 people play the game, about about a quarter of those providing feedback, so overall, a decent turnout, even if it didn&#8217;t match that of Thursdays play testing, it was a more calm environment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the next week, I implemented changes based on the feedback I had gotten from the previous playtest session.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ability Multiplier Text UI One of the first things I did this week was add a UI element to the HUD to indicate to the player the Ability Multiplier strength. This was surprisingly difficult to pull off, as I had to modify the UI of the ability selection scene a couple of times to get&#8230;<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-564","post","type-post","status-publish","format-standard","hentry","category-semester-2-kinetic-panic"],"_links":{"self":[{"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/posts\/564","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/comments?post=564"}],"version-history":[{"count":11,"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/posts\/564\/revisions"}],"predecessor-version":[{"id":602,"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/posts\/564\/revisions\/602"}],"wp:attachment":[{"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/media?parent=564"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/categories?post=564"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sites.wsagames.com\/sc18g23\/wp-json\/wp\/v2\/tags?post=564"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}