DevBlog 1.2: Monkey Fight - Movement, Basic Animation & Network Sync
After the last post, I went about importing the main monkey model into Unity and figuring out how to animate it. Though I thought the model was humanoid enough, the rig's bone structure was, in fact, not human enough for it to use a humanoid avatar in unity, meaning I had to use a generic type. I spent quite a while animating a basic run cycle for the monkey, but it turned out pretty good.
In terms of movement, I decided to give the player client authority. It just seemed like a first person shooter would be too clunky if the movements were handled serverside. More than likely, bullets will also be handled clientside.
I combined a basic character script for handling input with unity's builtin character controller for the movement. The player can turn a maximum of 90 degrees up or down, and the neck of the monkey model changes rotation with the player camera so other players can tell where they're looking. For gravity, I added a velocity vector to the movement script which uses a spherecast at the player's feet to check if they're grounded and, if not, increases their velocity every frame by a given gravity value. As of now, the controls work smoothly. I also used animator parameters to sync the walking animation up with the player's current speed.
The only major bug I ran into was a very bizarre one: I didn't notice until I had completed the controls, but it seemed that the player's model rose into the air, slowly, while they were walking. Granted, the player's hitbox stayed in the same place; the model itself was a child object of the main player object, and had nothing but the animator on it. So, must have been the animator, right? ...I thought so too, and I still think so, but I could never totally solve it.
Because the monkey's animator needs avatar masks to separate the torso and leg animations, and because Unity's auto-generated avatars for models must have the animator placed directly on the model's parent object for them to work, it was necessary that the animator component be placed on the monkey model itself rather than the parent player object. In my running animation, the player bobs up and down a little as they run - naturally - and the only way I could accomplish this bobbing was to move the model itself, that is, the parent object with the animator on it. I have now learned that animating the position of the object to which the animator is attached is a little volatile; it seems that, as the animator transitioned from the run animation to the idle animation, the model's position did not reset, and if it was in the air, it stayed in the air, and the next running animation built on its position.
I tried a number of solutions, but unfortunately, the only one that worked was pure brute force. In the player controller script, I made it so, when the player is not moving (i.e. in the idle animation) their model's local position is reset to (0, 0, 0). At first, this just snapped the model down out of the running animation, which worked, but looked a bit stilted, so I made it lerp (linearly interpolate) between the current position and (0, 0, 0) instead, which made the model fall smoothly.
Other than that, functionality at the moment is flawless. Animations are synced using a NetworkAnimator, controls are fluid... Next thing to tackle is weapons, weapon holding animations, weapon firing animations, etc. I'm thinking that the bullet weapons will use clientside raycasting, but I'll also try serverside physical bullets to see how those work. Stay tuned.
Comments
Post a Comment