No Head?
đ 2023-04-28
So, since adding Daphne, I configured her textures, cleaned up her unity rig hierarchy, and made her the playable character for this greybox, so we can build snowmen with her. To do this, I had to reconfigure the HFPS âHEROPLAYERâ root animation object and mess with some of the settings, thankfully, of all the annoyances of the kit, changing the player character is fairly painless. Plug in some spine bones, reconfigure the animation, mess with some visibility issues, and youâre good to go.
One major issue with Daphne that I didnât consider when purchasing the model (because the sisterâs are NPCâs not Playables for the most part) is her head is not detached from her body. This is actually really important for a first person game, since we need to control the visibility of the head mesh separately, as the camera takes up the heads position. Many games avoid this issue entirely by having no player character be visible, and we could do this and only have Daphne be present in cut-scenes, but I hate looking down in a game and seeing emptiness, I always comment on it, because it does have an impact on my âimmersionâ, though I despise that word. We could theoretically fix this in Maya by unbinding the mesh, severing the head, rebinding the mesh, etc - but you saw what a pain it was to even bind some socks, so no, we need another solution.
I spent some time searching and found that some people alter the neck bone scale in game to have the head vanish. Basically, you set the scale on the neck bone to zero and the mesh conforms to the rig scale. The problem with this method, is that our shadow then has no head.
I came up with a solution though, instead of reducing the scale to 0, we keep the scale on the X and Y, so we have the shape for the shadow, but reduce it on the Z - that way we get out of the way of the camera. Since when we turn, we turn our whole body, weâll never see the flattened shadow in the profile. We of course would need to control this in cutscenes, but itâs the best solution I have for the moment.
Obviously, this looks extremely silly, but itâs a behind the scenes thing that hopefully wonât ever be noticed by the player. Smoke and mirrors. We created a quick SnowGlobals script to control this, added a cutscene bool and a player plug-in for the neck bone, and control it via the update. We also put a quick check to see if weâre at the scale already or not, so we donât have the scale happening every frame, just the check.
That screenshot has if cutscene false, but it should be if cutscene true, minor oversight, but itâs now working.
Next, the snowballs. Iâve done a lot of work to the snowball system since the last time we mentioned them. First we removed any instances of Medium or Large snowballs, so now only small ones appear. Second, we added a new intractable object, âSnow Pilesâ, which are just a heap of collected snow on the ground. I created this in Maya using some quick randomization and tweaking so we have two states, piled, and non piled.
Then, we jump into a new script for the object, use a simple collider to check if the player is in range or not, and if they are and they press interact, we run a small coroutine that changes the state of the pile (only if theyâre holding an object).
You can see weâre actually running a bool from our Altar Spawner, this basically checks what weâre holding, and if weâre holding a small snow object, we return true after changing the snow object scale and flag.
Because we had already tweaked the medium and large prefab snowballs to have specific attributes to work with the altar, we now need to pass these onto the object when it changes state. You can see we basically just alter itâs scale and collider size to match those previous prefabs exactly. This took a little fucking around, but the end result is quite good.
You can also see weâve altered the starting area to be a larger play area, this allows the generator to run unseen behind the gate, and also gives us an area to play with the snow mechanic before going into the labyrinth.
Ideally, Iâd like to take this one step further. It seems silly to have these preconfigured snowballs laying around, so what I want to implement next, is a fourth size (extra small) and the ability to have the piles spawn these on interact if youâre not holding a snowball. So letâs get to work. First thingâs first, Iâll add the extra small bool to our Greybox Item script, and make it half the size of the small object, then prefab the snowball. Since these snowballs never get used with the altar/snowman, we donât have to fuss too much about sizing.
With that done, we need to add some new code to our Pile scripts to make this happen, first we need to plug in the prefab, and then just instantiate it when we interact when not holding snow.
To do this, you can see Iâm grabbing the player position and then calculating a mid point between the player and the snow pile, so hopefully it feels like weâre creating a snowball. Letâs see how it looks.
Right, y position 1 may have been âŚway too high. Letâs get the actual height just messing with the snowball in engine and fix that. Oh, itâs at like -8, that makes sense. I also need to fix the scale, because when labyrinth tiles have snowballs in their generative collections, the scale is not the same as the world scale, which means our opening area snowballs are a different size to our labyrinth snowballs. We should be able to fix this easily by just creating an opening area snowball prefab that works independently to the ones in the labyrinth.
We also need to add a new state to our AddSnow function, so we can go from extra small to small. So Iâm going to make a note of the collider size and scale of our small snowballs so we can transition to them easily.
I also changed my mind on how to handle the scale issues, what Iâll do instead is just make sure the piles parents have the same scale as the labyrinth tiles, that way I donât need to fuck around with two different snowball objects.
Right, scale is still weird. We probably just need to parent the instantiated object to the pile so we can gain its size. This is pretty easy since we just add a fourth attribute to our instantiation code.
That⌠did not work. Itâs way too large and⌠why is it disappearing? Questions for the ages. I think Iâve messed up the scale logic here, I may need to just parent the snowballs to the pile parent not the piles themselves. To do this we just add â.parentâ after the transform in the instantiate code.
Well fuck me, that isnât what I expected. And I called the last one too large. Hang on⌠Oh, right, itâs the parentâs parent. Ugh, dumb. Okay, that didnât work either. What is happening? So, even when I change the prefab scale to .1,.1,.1 Iâm still getting it instantiating at .45, so it must be getting overridden in the greybox item script. AnddddâŚ.
It is, thatâs such a silly oversight, I canât remember why I changed its scale in the start function, but thatâs what the issue is, letâs just fix that and see if that makes everything work correctly.
And it works! That took way longer than it should have. Our snow system now feels way more organic, since we donât just have balls all over the place, we now create them entirely from snow.
Next, I want to change the sigil that allows the player to create snowmen. Instead of a circle sigil, I want it to be a piece of wood, driven into the snow, like a scarecrow. I found this headstone collection for free on CG trader, letâs drag it in and see what we got.
Hopefully, you can see why I chose this free asset - there is one headstone that is made from wood, so we can delete all the rest of the stuff and use that wooden base to create our snowman. So we unpack the prefab, delete all the remainders, make sure we texture our wooden beam, scale it a little, and then attach it to our ritual object.
Looks like we broke something somewhere. I must have messed with the scale of the ritual altar when I added the beam, no matter, easy fix.
Perfect. Finally, letâs add a little basket with the rocks and carrots on the bench of the cabin, so we can finish our snowman.
So, we have two issues left for the moment. One, is we need to have the door unlock when we finish our first snowman. And two, if the player messes up the progression, they run out of snow and canât finish the snowman.
Our first issue shouldnât be too hard to fix, we already have altars checking if theyâre built in the right place to open the gate at the end, so we just need to add the door functionality from elsewhere in âMirrorsâ to get the door functioning and then have the snowman check if itâs the first snowman of the level, and check the door instead of the gate when finished.
For our second issue, there are a few ways we could approach it. We could have the snow piles regenerate over time, so eventually the player would have enough snow to create the correct progression. Another option is we could have the player break apart snowballs with a button press, and join snowballs with a button press. We could also write some logic in the snow pile script to allow the player to return with a snowball, refill the pile, and generate x amount of snowballs based on what state weâre in, so the player could grab a large snowball, then refill a pile, and get 3 extra small ones. They could then refill different piles with those 3 to regen the piles and try again.
The last option seems like a medium difficulty one to implement, but we can extend our already existing systems - that being said it sounds like a bad way to play the game. Joining and dismantling snowballs seems like a good way to extend the mechanics, but itâs also cumbersome. The best option might be to have the snow piles regenerate, itâs also by far the easiest option. Time for a coffee, and then weâll fix these last two issues.
Okay, weâve added a new coroutine to our snow piles, so that instead of shutting down the object by disabling everything, we now wait 30 seconds, and turn everything back on. Nice and simple, but does it work?
We must have missed something, it does regenerate, but I canât interact with it. Letâs dive into the script to see why. Oh, another silly oversight, I set it to active true instead of active false. This is why you should name your variables sensibly, because my active bool means the opposite of what it implies, we can only interact when active is false, and active means that weâve interacted with it.
Next, letâs tackle the door. What Iâll do is bring in a door from the other levels and change out the model, then change the code. Then weâll add a global âopeningLockedâ bool, and check it when we finish a snowman to see if itâs true, if it is, we unlock the door instead of adding to our final list. Which means weâll also need an altar zone in the opening area.
So now, we have our door and a locked bool in our globals, when an altar is completed, it first checks if that bool is true, if it is, it tells the globals script to unlock the door, instead of adding the altar to our end gate.
I got that done pretty quick and then got distracted by some bugs in other sections of the code and spent an hour trying to fix those. Anyway, there we have it, the door now opens when youâve built your first snowman, granting you access to the labyrinth. It may seem trivial, but weâre on our way to polishing up this greybox loop for inclusion in the game. I want to fix the regen code so the snow piles donât suddenly pop up, and I also need some text hovers for the objects and a little more UI on the screen to help the player know what theyâre doing, so weâll tackle that in the next post, because this one got big, uwu.