{"id":584,"date":"2025-02-09T10:41:33","date_gmt":"2025-02-09T15:41:33","guid":{"rendered":"https:\/\/willkolb.com\/?p=584"},"modified":"2025-02-09T10:42:24","modified_gmt":"2025-02-09T15:42:24","slug":"misc-updates","status":"publish","type":"post","link":"https:\/\/willkolb.com\/?p=584","title":{"rendered":"Leaning Updates"},"content":{"rendered":"\n<p>(Writing as I&#8217;m doing this fyi) I wanted to re-write the leaning in the game. Right now the movement is all very snap, which has some skewing to it but i wanted a more gradual lean in.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"371\" src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint-1024x371.png\" alt=\"\" class=\"wp-image-585\" srcset=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint-1024x371.png 1024w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint-300x109.png 300w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint-768x279.png 768w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint-1536x557.png 1536w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint-2048x743.png 2048w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint-500x181.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Event graph level<\/figcaption><\/figure>\n\n\n\n<p>(Normally I would use <a href=\"https:\/\/blueprintue.com\">https:\/\/blueprintue.com<\/a>, but wordpress is weird about iframes)<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"249\" src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint1-1024x249.png\" alt=\"\" class=\"wp-image-586\" srcset=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint1-1024x249.png 1024w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint1-300x73.png 300w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint1-768x187.png 768w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint1-1536x374.png 1536w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint1-2048x499.png 2048w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/blueprint1-500x122.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Now you can see here the process is, press button, move to desired input. My first thought was to throw in the delta seconds of the last frame, add a rotator and vector interpolation block and be done with it, however, Unreal&#8217;s input system is actually made for this. If you look at the top blueprint I have a few branch statements that was thresholding based upon the input value. Instead I&#8217;ll use that input value to skew between the lean position and the rest position.<\/p>\n\n\n\n<p>My lean action by default is a 1-d float which is cumulative, which should mean that as I press the lean keys (Q+E) the value of the lean action (the Axis value line from the first plot) should increase as the buttons are held down.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"958\" height=\"456\" src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-3.png\" alt=\"\" class=\"wp-image-587\" srcset=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-3.png 958w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-3-300x143.png 300w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-3-768x366.png 768w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-3-500x238.png 500w\" sizes=\"auto, (max-width: 958px) 100vw, 958px\" \/><\/figure>\n\n\n\n<p>Therefore, if I just use that value to skew between the lean position and rest position I should be good&#8230;.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">I was not good<\/h2>\n\n\n\n<p>What I described above is TOTALLY not how this works. Advanced input seems to not hold any kind of state from the previous frame unless you&#8217;re using defined curves. For example there is a &#8220;scale by delta time&#8221; modifier that works but it takes whatever the current input is and multiplies it by the frame time. This can be useful but my goal here was to avoid adding another accumulator within the player blueprint class. You can add an exponential curve but that&#8217;s just a modifier to the input values. I don&#8217;t think there will be a good way here other than adding a &#8220;currentInputValue&#8221; modifier and having it decay at a fixed rate&#8230; <\/p>\n\n\n\n<p>This is one of those situations where I shot myself in the foot for using blueprints, however I think there&#8217;s enough syntax and other bugs that I saved myself from that I don&#8217;t care <em>that<\/em> much. For example In matlab (which I use a bunch at work) this problem can be solved via:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>startPos = &#91;-10 -20 -40];\nendPos = &#91;-10 20 40];\nrestPos = &#91;-10 0 60];\ninputAxis = linspace(-1.0,1.0,3);\n&#91;iAx iAy iAz] = meshgrid(inputAxis,inputAxis,inputAxis);\n&#91;xOut yOut zOut] = interp3(&#91;startPos;restPos;endPos],CURRENT_INPUT_VALUE,iAx,iAy,iAz);\n<\/code><\/pre>\n\n\n\n<p>I think unreal can do this with curves but my head moves towards code when we get to 2+ dimensions. But honestly this is me overthinking on coffee at this point, I&#8217;ll just throw it in with another accumulator and some alpha smoothing (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Exponential_smoothing\">https:\/\/en.wikipedia.org\/wiki\/Exponential_smoothing<\/a>, which I believe is implemented in <a href=\"https:\/\/dev.epicgames.com\/documentation\/en-us\/unreal-engine\/BlueprintAPI\/Math\/Smoothing\/WeightedMovingAverageFloat\">https:\/\/dev.epicgames.com\/documentation\/en-us\/unreal-engine\/BlueprintAPI\/Math\/Smoothing\/WeightedMovingAverageFloat<\/a>) <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Attempt #1<\/h2>\n\n\n\n<p>First thing I is that I embraced curves:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"346\" src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-4-1024x346.png\" alt=\"\" class=\"wp-image-590\" srcset=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-4-1024x346.png 1024w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-4-300x101.png 300w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-4-768x259.png 768w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-4-1536x519.png 1536w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-4-500x169.png 500w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-4.png 1862w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Which was so simple I&#8217;m confused why I didn&#8217;t start with these. The only hitch I had is that it was annoying to find the &#8220;getVectorValueFromCurve&#8221; block. If you just blindly add a curve class or runtime curve class this isn&#8217;t exposed. Now the results:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"1080\" style=\"aspect-ratio: 1920 \/ 1080;\" width=\"1920\" controls src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/2025-02-09_10-13-54.mp4\"><\/video><\/figure>\n\n\n\n<p>This worked but now I&#8217;m hitting issues with state management. The rough way the Unreal input system works is: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if(currentState == buttonPressed &amp;&amp; previousState == buttonReleased)\n{\n   Trigger(inputValue);\n}\nelseif(currentState == ButtonReleased &amp;&amp; previousState == ButtonPressed)\n{\n   Ongoing(inputValue);\n}\nelseif(currentState == ButtonReleased &amp;&amp; previousState == ButtonPressed)\n{\n    Complete(inputValue);\n}else\n{\n    \/\/DoNothing\n}<\/code><\/pre>\n\n\n\n<p>Which essentially means that putting the logic attached to button presses is a fools errand. I need to move it out to the tick function, or I need to figure out how to modify the states above to keep firing the &#8220;completed&#8221; state.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Attempt #2<\/h2>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"1080\" style=\"aspect-ratio: 1920 \/ 1080;\" width=\"1920\" controls src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/2025-02-09_10-17-18.mp4\"><\/video><\/figure>\n\n\n\n<p>I tried messing with advanced input and hit the same state issue. I was hoping I could set the trigger to also be released but it never hits more than once.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"513\" src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-5-1024x513.png\" alt=\"\" class=\"wp-image-593\" srcset=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-5-1024x513.png 1024w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-5-300x150.png 300w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-5-768x385.png 768w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-5-500x250.png 500w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-5.png 1084w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>No dice&#8230;gotta push the input value smoothing and the lean function to the delta. This will require another variable to handle the previous input value of the lean buttons. This might mess up the way I visualize the math but lets see what happens.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Attempt #3<\/h2>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"1080\" style=\"aspect-ratio: 1920 \/ 1080;\" width=\"1920\" controls src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/2025-02-09_10-33-40.mp4\"><\/video><\/figure>\n\n\n\n<p>This seems to be the best lean method. Essentially I needed to add one more var to handle the current value of the input and keep the same one that defined the previous variable. Below is the blueprints.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"989\" height=\"420\" src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-6.png\" alt=\"\" class=\"wp-image-595\" srcset=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-6.png 989w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-6-300x127.png 300w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-6-768x326.png 768w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-6-500x212.png 500w\" sizes=\"auto, (max-width: 989px) 100vw, 989px\" \/><figcaption class=\"wp-element-caption\">Tick event is the input to the left<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"798\" height=\"353\" src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-7.png\" alt=\"\" class=\"wp-image-596\" srcset=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-7.png 798w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-7-300x133.png 300w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-7-768x340.png 768w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-7-500x221.png 500w\" sizes=\"auto, (max-width: 798px) 100vw, 798px\" \/><\/figure>\n\n\n\n<p>Pretty simple at the end of the day. Hard part about this stuff is never what you&#8217;re doing its always that transition from what you&#8217;re doing into the mental model that the unreal devs used.<\/p>\n\n\n\n<p>Finally my management failure&#8230;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"459\" src=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-8.png\" alt=\"\" class=\"wp-image-597\" srcset=\"https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-8.png 602w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-8-300x229.png 300w, https:\/\/willkolb.com\/wp-content\/uploads\/2025\/02\/image-8-393x300.png 393w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/figure>\n\n\n\n<p>Which doesn&#8217;t really matter too much because I&#8217;m working solo, without a server to push content to. However its just bad practice to not protect yourself from silly confusing mistakes (which will increase as you get to the end of development). <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Next goals<\/h2>\n\n\n\n<p>1.) Add a flashbang and grenade robot (look back in my notes I have a flashbang and m67 already modeled).<\/p>\n\n\n\n<p>2.) Add a new weapon<\/p>\n\n\n\n<p>3.) Add a humanoid character that rides the robots? <\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>(Writing as I&#8217;m doing this fyi) I wanted to re-write the leaning in the game. Right now the movement is all very snap, which has some skewing to it but i wanted a more gradual lean in. (Normally I would use https:\/\/blueprintue.com, but wordpress is weird about iframes) Now you can see here the process [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":596,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,9],"tags":[],"class_list":["post-584","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gamedev","category-unreal"],"_links":{"self":[{"href":"https:\/\/willkolb.com\/index.php?rest_route=\/wp\/v2\/posts\/584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/willkolb.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/willkolb.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/willkolb.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/willkolb.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=584"}],"version-history":[{"count":5,"href":"https:\/\/willkolb.com\/index.php?rest_route=\/wp\/v2\/posts\/584\/revisions"}],"predecessor-version":[{"id":600,"href":"https:\/\/willkolb.com\/index.php?rest_route=\/wp\/v2\/posts\/584\/revisions\/600"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/willkolb.com\/index.php?rest_route=\/wp\/v2\/media\/596"}],"wp:attachment":[{"href":"https:\/\/willkolb.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/willkolb.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/willkolb.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}