{"id":2191,"date":"2020-02-11T20:16:23","date_gmt":"2020-02-12T01:16:23","guid":{"rendered":"https:\/\/lilithebowman.com\/blog\/?p=2191"},"modified":"2020-02-11T20:37:01","modified_gmt":"2020-02-12T01:37:01","slug":"gamedev-keeping-characters-upright","status":"publish","type":"post","link":"https:\/\/www.lilithebowman.com\/blog\/2020\/02\/gamedev-keeping-characters-upright\/","title":{"rendered":"Gamedev: Keeping Characters Upright"},"content":{"rendered":"\n<p>You gotta walk the walk and since we&#8217;re not trying to simulate a drunk walk here, I&#8217;ve been putting some work into making a character controller with walk\/strafe on the left stick and look on the right stick, as is custom in these here gamin&#8217; parts.<\/p>\n\n\n\n<figure class=\"wp-block-embed-twitter wp-block-embed is-type-rich is-provider-twitter\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"twitter-tweet\" data-width=\"550\" data-dnt=\"true\"><p lang=\"en\" dir=\"ltr\"><a href=\"https:\/\/twitter.com\/unity3d?ref_src=twsrc%5Etfw\">@unity3d<\/a> there has to be an easier way to do this that I&#39;m just missing, but I *finally* figured out how to make first person controls that stay upright. <a href=\"https:\/\/twitter.com\/hashtag\/gamedev?src=hash&amp;ref_src=twsrc%5Etfw\">#gamedev<\/a> <a href=\"https:\/\/twitter.com\/hashtag\/finishItFebruary?src=hash&amp;ref_src=twsrc%5Etfw\">#finishItFebruary<\/a> <a href=\"https:\/\/t.co\/ITQlnFffNQ\">pic.twitter.com\/ITQlnFffNQ<\/a><\/p>&mdash; Lilithe ??(she\/her) ? (@lilithebowman) <a href=\"https:\/\/twitter.com\/lilithebowman\/status\/1227398984748224513?ref_src=twsrc%5Etfw\">February 12, 2020<\/a><\/blockquote><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<\/div><figcaption>Success! We&#8217;re upright and working!<\/figcaption><\/figure>\n\n\n\n<p>It wasn&#8217;t a quick and easy thing. I did a lot of searching and nobody else seems to have had the answer to what I wanted. This is what it looked like before.<\/p>\n\n\n\n<figure class=\"wp-block-embed-twitter wp-block-embed is-type-rich is-provider-twitter\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"twitter-tweet\" data-width=\"550\" data-dnt=\"true\"><p lang=\"en\" dir=\"ltr\">Check out what happens without that bit of code! Slowly tumbling&#8230; tumbling towards freedom!<br><br>CW: might make you barf <a href=\"https:\/\/t.co\/0p6cEbwqPA\">pic.twitter.com\/0p6cEbwqPA<\/a><\/p>&mdash; Lilithe ??(she\/her) ? (@lilithebowman) <a href=\"https:\/\/twitter.com\/lilithebowman\/status\/1227399461535703040?ref_src=twsrc%5Etfw\">February 12, 2020<\/a><\/blockquote><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<\/div><figcaption>Well, the first reply (2nd tweet here) is what it looks like.<\/figcaption><\/figure>\n\n\n\n<p>I&#8217;m not sure why WordPress wants to embed both of them but only for the second tweet. Thanks for breaking my embed, WP!<\/p>\n\n\n\n<p>Anyhoo, I hope this helps someone as I didn&#8217;t easily find the answer when I looked.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\npublic class PlayerCharacterController : MonoBehaviour\n{\n\n\tpublic float moveSpeed = 10f;\n\tpublic float rotationRate = 10.0f;\n\tpublic float jumpForce = 20.0f;\n\tpublic CharacterController controller;\n\tpublic float gravityScale = 1.0f;\n\tpublic Vector3 moveDirection;\n\n\tprivate string moveInputAxis = \"Vertical\";\n\tprivate string strafeInputAxis = \"Horizontal\";\n\tprivate string lookHorizontalAxis = \"Mouse X\";\n\tprivate string lookVerticalAxis = \"Mouse Y\";\n\tprivate float currentJumpForce;\n\tprivate bool isJumping = false;\n\n\tvoid Start()\n\t{\n\t\tcontroller = GetComponent&lt;CharacterController>();\n\t}\n\n\tvoid Update()\n\t{\n\t\tfloat moveAxis = Input.GetAxis(moveInputAxis);\n\t\tfloat strafeAxis = Input.GetAxis(strafeInputAxis);\n\n\t\tApplyInput(moveAxis, strafeAxis);\n\t}\n\n\tprivate void ApplyInput(float moveInput, float turnInput)\n\t{\n\t\tMove(moveInput, turnInput);\n\t\tmoveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale);\n\t\tJump();\n\t\tMouseLook();\n\n\t\tcontroller.Move(moveDirection * Time.deltaTime);\n\t}\n\n\tprivate void Move(float moveInput, float strafeInput)\n\t{\n\t\t\/\/ moveDirection = new Vector3(-turnInput * rotationRate, 0.0f, -moveInput * moveSpeed);\n\t\tTransform characterTransform = controller.GetComponent&lt;Transform>();\n\t\tmoveDirection = characterTransform.forward;\n\t\tDebug.DrawRay(characterTransform.position, moveDirection, Color.red);\n\t\tmoveDirection.x = (characterTransform.forward * moveInput).x + (characterTransform.right * strafeInput).x;\n\t\tmoveDirection.y = (characterTransform.forward * moveInput).y + (characterTransform.right * strafeInput).y;\n\t\tmoveDirection.z = (characterTransform.forward * moveInput).z + (characterTransform.right * strafeInput).z;\n\t\tmoveDirection *= moveSpeed;\n\t\tDebug.DrawRay(characterTransform.position, characterTransform.right * strafeInput * moveSpeed, Color.yellow);\n\t\tDebug.DrawRay(characterTransform.position, characterTransform.forward * moveInput * moveSpeed, Color.blue);\n\t}\n\n\tprivate void Jump()\n\t{\n\t\tif(!controller.isGrounded &amp;&amp; isJumping) {\n\t\t\tVector3 force = Vector3.up * jumpForce;\n\t\t\tmoveDirection.y = --currentJumpForce;\n\t\t} else if(isJumping)\n\t\t{\n\t\t\tisJumping = false;\n\t\t}\n\t\tif (Input.GetButtonDown(\"Jump\") &amp;&amp; controller.isGrounded)\n\t\t{\n\t\t\tDebug.Log(\"Jumping!\");\n\t\t\tcurrentJumpForce = jumpForce;\n\t\t\tVector3 force = Vector3.up * jumpForce;\n\t\t\tmoveDirection.y = currentJumpForce;\n\t\t\tisJumping = true;\n\t\t}\n\t}\n\n\tprivate void MouseLook()\n\t{\n\t\tfloat mouseXInput = Input.GetAxis(lookHorizontalAxis);\n\t\tfloat mouseYInput = -Input.GetAxis(lookVerticalAxis);\n\t\tVector3 lookhere = new Vector3(mouseYInput, mouseXInput, 0);\n\t\ttransform.Rotate(lookhere);\n\n\t\t\/\/ Keep us upright\n\t\tQuaternion rot = transform.rotation;\n\t\trot = Quaternion.Euler(rot.eulerAngles.x, rot.eulerAngles.y, 0.0f); \/\/null rotation Z\n\t\ttransform.rotation = rot;\n\t}\n\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>You gotta walk the walk and since we&#8217;re not trying to simulate a drunk walk here, I&#8217;ve been putting some work into making a character controller with walk\/strafe on the left stick and look on the right stick, as is custom in these here gamin&#8217; parts. It wasn&#8217;t a quick and easy thing. I did [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":2194,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[335,239,334,337],"class_list":["post-2191","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-daily-musings","tag-finish-it-february","tag-game-development","tag-gamedev","tag-platformer-demo"],"_links":{"self":[{"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/posts\/2191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/comments?post=2191"}],"version-history":[{"count":2,"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/posts\/2191\/revisions"}],"predecessor-version":[{"id":2195,"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/posts\/2191\/revisions\/2195"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/media\/2194"}],"wp:attachment":[{"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/media?parent=2191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/categories?post=2191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lilithebowman.com\/blog\/wp-json\/wp\/v2\/tags?post=2191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}