Monday 20.6 | Starting Work on Stealth & New Environment

Platformer Prototype

Today I started with creating an environment for testing the stealth mechanics which I will be adding this week. The better part of the day went implementing audible events and fixing combat.


Inaudible Audible Steps

Using UnityEvents to make enemies hear the player run. I don't know if invoking every enemy's OnAudibleEvent method is the best way of handling this, but for the prototype it works. At the moment the mechanic feels weird because I don't have the foot step sounds or enemy animations to go along with it yet.


Wave Function Collapse Environment

WFCEnvironment

I created a simple environment with a Wave Function Collapse unity implementation I had fiddled with a couple weeks back (marian42/wavefunctioncollapse). I had created the building blocks back then so I literally just had to press generate and move a couple blocks around to make it little more functional.

CoupleBuildingBlocksAndConnections

Day's Work

  • Wave function collapse environment
  • StealthEventSystem
    • UnityEvent OnAudibleEvent
    • On enemy
      • PlayerDetection listens to audibleevent and checks distance
      • Behaviour tree gets target from PlayerDetection
  • Fixing Executing
    • Also renamed to critical strike
  • Still trying to figure out the combat
    • Testing with many enemies

Friday 17.6 | Back Critical Strike

Platformer Prototype

Adding a critical strike marker for enemies when they're facing away from the player. Needs some fixing still because of a small detour during the day.

Shader Execute/Critical Strike Mark

First I simply created a world canvas with a radial fill for the timer and a simple cross graphic. The idea was to first run the timer and then activate the graphic and notify the character scripts that this enemy can be critically striked. Everything looked pretty good but I just got a tingle that it could look amazing actually on the back of the enemy.

NotUsedShaderExecuteMark

Well I "somehow" got it working and looking great, but when actually playing the mark was way too small in my opinion (could be a sick shirt graphic though). Since there's no good way of making it noticeably larger, I scrapped the material for now. It really wouldn't even make a big difference, because of the viewing angle always being favourable for the canvas.

ExecuteMark

Day's Work

"Execute" probably going to get renamed to critical strike

  • Imported running attack
  • Enemy
    • Execute timer
    • Sound when able to execute
    • Sound when the strike hits
    • Fading in and out
  • Character
    • Execute
      • Disable player movement when executing
      • Weapon effects

Wednesday 15.6 & Thursday 16.6 | Combat

Platformer Prototype

I got a little excited when I got the combat actually playable and worked on it for 13 hours on Wednesday. So yeah, today I'm just gonna write this and take it easy. On Wednesday though, the combat started to look and feel pretty good already. I'll still have to mess around with the camera, figure out how to visualize the enemy's health and add a lot of things, but that's gonna be after getting the stealth mechanic working and seeing how it all plays out.

Kicking to Keep Player at Attacking Range

I had trouble keeping the player at a hittable range. The problem wasn't only that the enemy wouldn't hit but more that the enemy got "pushed" when trying to move back to the hittable range. It probably could've worked with some precise movement, but that means a lot of time for polishing. I thought a more interesting way to keep the player at a distance would be a kick.

Kick

This seemed like a great idea but still required some coding for the push. In the end I decided that this wouldn't be an obstacle for adding it because the pushing code would probably get used a lot in the future. Currently the actual push is just roughly timed and the strength over time is controlled with an animation curve and I don't think that that's going to be changing because it really might not even matter.

The kick ended up being a great and time efficient way of preventing the player from drilling the enemy's shins to dust.


Weapon Swinging and Impact Sounds

I also got some great sounds in, thanks to Eponn on FreeSound.org. The WeaponInfo ScriptableObject has a list for swinging sounds and impact sounds (per weapon of course). Then when swinging I just get a random one different from the previous and play it with the help of an AudioSource pool.


Download Audiosource pool Script

I thought AudioSource pooling can be useful in any project, so if you wanna save a couple minutes on writing one, download this. AudioSourcePool (Isn't optimized or anything)


About the weird attacking behaviour code

I decided to disable behaviour tree evaluating totally while the enemy is dead or disabled. After this I got almost all of the functionality out of the EnemyBehaviour and into the behaviour tree nodes.


GlobalCombatManager

Work Done

  • Player now takes damage and reacts too
    • Player's movement and angular speed controllable when attacking
    • "Character" script for holding the player's state and everything associated (IDamageable, Stats, Reacting to hits)
  • Refactoring and better segmenting a lot of Character Controller code => More readable, easier to debug, easier to add more functionality
  • Global Combat Manager for easy testing/balancing of combat
    • Holds parameters for combat such as
      • Threshold of damage after which an enemy or player reacts (the animation)
      • Movement and angular speed when attacking
  • Enemy
    • Modified primary attack animation to always hit when straight ahead (swung to the side before)
    • Kicking
      • When player gets too close the enemy kicks him
      • Meant adding a pushing mechanic to the character controller
        • Did with Vector3 PushVelocity
        • When PushVelocity is not zero, override the normal movement loop
  • Very simple Player hp and enemy hp UI
  • Weapon
    • OnSwing animation event to play swing sounds
    • Hit & Swing sounds (Thanks to Eponn on FreeSound.org)
    • Hit and getting hit haptics
  • AudioSource pool with main method: PlaySoundAtPosition()
    • This method finds an available audiosource from the pool, if on eis not found it gets instantiated

Tuesday 14.6 | Enemy Combat

Platformer Prototype

Adding basic functionality for enemy combat. I will probably be refining and adding effects to this for the rest of the week.

Behaviour Tree & Enemy Script Relationship

I implemented the combat state management system pretty weird. I have some functionality in the behaviour tree nodes and some in the EnemyBehaviour script (driven by the behaviour tree though). I have some concerns but first, here's roughly how chasing and attacking works at the moment.

Behaviour Tree Chasing/Attacking Node

Pseudocode:

	if (PlayerInAttackRange && IsFacingPlayer)
		enemy.state = EnemyBehaviour.EnemyState.Attacking;
		
	else
	{
		enemy.state = EnemyBehaviour.EnemyState.Chasing;

		// If target in range but not facing it turn it
		if (PlayerInAttackRange)
			RotateTowardsPlayer();

		navMeshAgent.SetDestination(playerPosition);
	}

EnemyBehaviour (Main enemy script)

Pseudocode:

	Update()
	{
		switch (state)
		{
			case EnemyState.Patrolling:
				Patrolling();
			case EnemyState.Chasing:
				Chasing();
			case EnemyState.Inspecting:
				Inspecting();
			case EnemyState.Attacking:
				Attacking();
			case EnemyState.Dead:
				break;
		}
	}

I did this partly because I found it easy to implement the attacking loop fully in the EnemyBehaviour. I'm worried that this might cause issues when implementing the stealth and such, but I'll have to look into it tomorrow and decide how I'm going to approach this.

SecondaryAttack CoolGuyStats

Day's Work

  • Enemy combat
    • "Guard" Behaviour Tree
      • Attacking/Chasing sets the EnemyBehaviour state to Chasing and Attacking
    • EnemyBehaviour
      • Enum EnemyState
      • Frequency of secondary attacks determined by ScriptableObject EnemyStats
      • Attack speed corresponds to animation length
        • Animation length has to be 2s
        • Animation speed is 2 and changed with "Attack Speed" parameter
    • Secondary attack animation
    • Small fixes

Monday 13.6 | Animated Enemy

Platformer Prototype

Adding an animated enemy around which I will be building the enemy functionality hopefully within this week. As much as possible is yoinked from the player systems. Today I got the enemy's basic patroling movement and hit reaction working.

Enemy Animator System

I'll implemented enemy animations with a single Animator Controller and just change the animations within it using Animator Override Controllers.

EnemyCoolGuy

Reacting to hits

I use a blend tree for changing the reaction direction. In the code I have an Enum that has the type of reactions and I use this when setting reactions, making the code a lot more readable.

EnemyCoolGuy

Day's Work

  • Enemy
    • Import "Cool Guy" as enemy
      • Old model I got from sketchfab some time ago (Heavily optimized)
      • Animations from mixamo
      • Model Machete
    • Reacting to damage (Only gut atm other animations I got were from left and right and I'm going to be implementing those tomorrow)
    • Set up everything ready for attacking
      • Use the Weapon Manager that the player also uses (Just less detection points)
      • EnemyBehaviour (The script every enemytype script will inherit from)
      • CoolGuy (The enemytype specific script, atm empty)
      • Animator
        • Stolen from player
        • Using Animator Override Controller as a animator controller prefab
      • Patrolling is the same as what the old enemies' had
  • Fixed bug with player's attack cooldown

Friday 10.6 | Combo Attack

Platformer Prototype

Today's task was to add combo attacks and do minor fixes all around the combat system. Now I will probably be switching focus to enemy combat. I think If I were to continue adding to the combat system, I would find a lot to be useless after adding the enemy combat system. After getting the enemy combat system up and running I will probably see the bigger picture clearer.

Combo Attack

On the code side I'm just checking for the attack input when 60% of the attack's cooldown has passed. If input is given a "Combo" boolean parameter on the animator is set to true which I use to disable the "Any State" transitions.

ComboAttacksAnimator
  • Sword Trail fixed
  • Attacking while rolling removed
  • Combo attacks
    • Animator based implementation (Script is only used to control a combo boolean)
    • Needs testing (Minimal, No polishing)
    • Reworked code for attacking to fit comboing
  • New attack animation for primary attack combo

Thursday 9.6 | Platformer Camera

Platformer Prototype

Today was almost all about implementing an actual platformer camera into the project. Other than that I just added a trail to the sword.

Platformer Camera

I started to notice that I had to fully control the camera which isn't what platformers are about and thought I could fix this before going deeper into combat. I played a couple of old platformers and realized that I was essentially using a 3rd person shooter camera. I knew all along it wasn't the right kind of camera but didn't realise the right one would make such a big difference.

CinemachineFreeLookCamera

Before this I started with fiddling around with the Cinemachine Virtual Camera but didn't seem to find the right one for the job. So I looked into it a bit more and found out that Cinemachine has the right camera but just not within the virtual camera (has like a thousand settings itself), which I quess is made for 3rd and 1st person shooters. The right camera was the "free look" camera with the orbit mode "simple follow with world up", which wants to stay in place(world space) while looking at the player at a specified distance.

Sword Trail

I added a sword trail with the help of a useful tutorial I found on Youtube. For turning it off and on again I use the emission module's RateOverTimeMultiplier, setting it to 0 and back to original when attacking. In need of some polishing effort though.

SwordTrail

Day's Work

  • Implementing the Cinemachine Free Look Camera
    • Input from new input system
    • Cinemachine collider using the smoothed "pull to player" method
    • Smoothing camera height with platform snapping (When grounded or climbing snap player follow transforms target height to players height, Not used in video because in my opinion maybe not needed for this kind of platformer, but time will tell)
  • Sword trail
    • Particle system trail
    • Controlled by weapon manager StartDealingDamage and StopDealingDamage functions

Tuesday 7.6 & Wednesday 8.6 | Melee Combat

Platformer Prototype

Tuesday stretched a little longer than I would've wanted to. A lot got done on the detection and damage system though. Wednesday I spent on making minor fixes all around and getting the attacks to feel more responsive.

Damage & Detection System

Detection

Detection system got a lot of new stuff including:

  • 2 ways for detecting hits
    • SphereOverlap
    • Raycasts back and forward

Sphere Overlap is used to find clean hits and raycasts are used find hits where the blade has gone through the player in one frame (collision detection therefore missing it).

Damage

I had a couple of ideas for the damage system, one being calculating the damage for every detection point and the other being velocity based attacks. The first one felt nice but is a total pain to implement thanks to the complexity. The velocity on the other hand made the hits feel random.

Finally I ended up with a per point calculations with position of the points scaling the damage linearly (Closer to the tip deals more damage). The point closest to the handle dealing 1/10 (amount of points) the damage and the very tip dealing full damage.

This damage also scales the effects which are up next.

Effects

For every detection point that has hit there is a ParticleSystem instantiated or placed from pool. I created an empty object and a "MonoBehaviour" to hold and manage these, called "ParticleSystemPool", which does the following:

  • Instantiates new ParticleSystems when needed
  • Places them
  • Scales bursts based on damage
  • Plays the effects

Using "Any State" Transitions for Responsive Attacking

AnimatorAttackAnyState

Rolling Fixed

Switched from using root motion to just locking the direction and adding some speed. Can't see a difference and feels a 100 times better. Before even the smoothed camera got weird because the root motion was so jittery.

Pictures

WeaponManagerEditor

WeaponManager Editor


SwordEditor

SwordEditor


WeaponTypeScriptableObject

WeaponType ScirptableObject


AttackAnimationEvents

Attack Animation Events


Work Done

  • Hit detection system
    • Now has 2 ways for detecting
      • SphereOverlap (After which a raycast is used to determine the point where effects are played from)
      • Raycasts back and forward
    • A lot of polishing and debugging
  • Damage System (Calculated per detection point)
    • Blade position based damage (Closer to the tip deals more damage)
    • (Wednesday) Offset the impact of position based damage to get true max damage of weapon (Still has small bug)
    • Animation events start and stop the damage dealing and hit detection
  • Hit effects (ParticleSystems only, per detection point)
    • "ParticleSystemPool" which holds the particle systems
      • Instantiates when needed
      • Places the effects
      • Scales bursts depending on damage
      • Plays the effects
  • Weapon system
    • "Weapon Manager" on player which holds "WeaponBehaviour equippedWeapon"
    • "Sword" is on the weapon and derives from "WeaponBehaviour"
    • "WeaponBehaviour" holds the parent of the blade line parent and a ScriptableObject "WeaponType"
    • "WeaponType" Holds the weapon's max damage and attack speed (only max damage is implemented as of now)
  • Fixed rolling (Wednesday)
    • No more root motion because it made the character go through walls
  • Fixed attack timings (Wednesday)
    • Transitions come from "Any State" state so it doesn't matter if asomething else is playing but cooldown is off

Monday 6.6 | Combat, Melee Hit Detection

Platformer Prototype

Starting on this week's focus combat with melee hit detection. Creating a sword with a line acting as the damage dealing section. Raycast based hit detection script for it.

Detection Points Distribution

I created a script that distributes given amount of points on a line constructed of empties. In the video the "detection points" are drawn as spheres on the sword.

SwordLinePointsVisualized

Spheres in the picture visualize the line's points.

Raycasting

The position of the "detection points" are saved for the next frame. Then a raycast is shot towards the last frames position, detecting a possible hit. In the video the red rays mean no hit and green ones mean hit.

Day's Work

  • Blender
    • Second attack animation modified to make sword movement look "realistic"
    • Importing only actions in the NLA strips to accelerate iterating
    • Sword modeled
  • Weapon script
    • Distributing points on a line
    • Ray shooting from those points to their old positions
    • Gizmo spheres
  • "Enemy" physics layer

Friday 3.6 | More Climbing Animations

Platformer Prototype

Continuing yesterday's animating and animator work. Adding a ledge grab animation, trying new things with the animator layers and minor fixing overall.

Root Bone Problems

Trying different things with the animator, but still having the problem of the character floating on the wall because of the root bone being a deform one. I will be looking into this over the weekend, the solution hopefully not being to manually animate a new non-deform root bone to every animation.

WallGap

Animator Layers

Sharing states among more animator layers for clarity. Minor flaw being the lack of blending between jumping and grabbing the wall.

ClimbingLayer MovementLayer
  • Climbing
    • Ledge grabbing animation
    • Snapping to ledge
    • Slipping gets faster with time
    • Climbing added to a new layer in animator
    • Fixed bug when climbing indoors and hitting roof
    • Other minor fixes

Thursday 2.6 | Climbing Animations

Platformer Prototype

After yesterday's coding I took this day a little more chill and did some animating and unity animator work.

Animations in Unity

Looking pretty janky at the moment, but almost everything is going to get polished.

Blender IK Exporting Problems

I didn't find good animations from mixamo so I had to make them. So I added inverse kinematics to my rig to do them in a timely manner and it's also beneficial for any probable animating in the future. IK turned out to be a problem when exporting the animations. I thought Blender would add keyframes to the constrained bones automatically when exporting, but this wasn't the case, I only got the old Unity rig to animate the root bone.

FastIK

After a "little bit" of googling I found out about "baking actions" which saved the day. This feature creates a new action and basically creates keyframes for the constrained bones every "Frame Step".

ActionBaking ActionBakingMenu

Today's Work

  • Blender
    • IK added to rig
    • Leap animation
    • Slipping animation
  • Unity
    • Climbing Animations imported
    • States added to a messy animator
    • Animator parameter handling added to climbing code

Wednesday 1.6 | Ledge Grabbing

Platformer Prototype

Ledge grabbing method that doesn't require any additional colliders. (But requires every ledge to be a mesh collider)

Ledge Detection Code

I could've just made it with colliders but felt kinda special today.

  1. Shoot a rays down at differing angles (Amount and angle change controllable)
  2. If hit and surface normal points to the sky get the triangle that was hit
  3. Calculates boundaries for the triangle
  4. Calculate closest point to "hand" position within these boundaries
  5. Snap player in ledge grab pose to this point (Animations not in yet)

(Doesn't work for ledges that are not perfectly going along the x or z axis & doesn't take height into consideration yet)

Debugging

GizmosImage

White rectangle are the boundaries of the triangle, red ray is a no hit, blue hit, green hit and the normal is pointing up. White sphere is the calculated grab point. (The one attached to player is a wall check sphere)

Cleaning up

I also got rid of booleans for controlling the climbing and used an enum to control flow through the climbing process. Before I had a mess of booleans like onLedge, climbing and detectingLedge. Which was a nightmare to manage and debug.

	public enum Mode
	{
		DetectWall,
		Climbing,
		DetectLedge,
		GrabbingLedge,
		Falling
	}

Today's Work

On top of the above explained ledge grabbing and detection.

  • Climbing
    • Can only climb up and sideways
    • Can drop from wall when joystick back enough (Threshold controllable)
    • Can't jump to the when right next to it
    • Minor fixes

Next up are the animations which I fear are going to be a hassle.


Tuesday 31.5 | Climbing

Platformer Prototype

A bit of polishing on the roll and climbing system's code being today's main focus. Telling a little about the system and why I decided to do this kind of climbing system.

Climbing System


Fast Research & Design

The quest for climbing started with researching the ways people have made climbing mechanics in unity. Before though, I set some boundaries such as it must have very little need for animations and that the implementation has to be easy for my kinematic character controller.

Minimizing Animation Amount

I thought about how I could minimize the need for animations and thought of making the player leap across the wall. This would result in not needing to blend and sync 4 climbing animations just for the movement which might've ended being boring after all. When the player is not leaping the character slowly slips down the surface eventually falling to the ground, adding a small mechanic in avoiding falling down.

ClimbingTechDemo

Easy Development

I found some amazing climbing tech demos, but these were not what I was looking for because of the complexity. Then after a little bit of browsing I came across a familiar site, Catlike Coding. There I found out I should just shift the gravity and project the movement input based on the wall normal, so I did. The leap and slip method helps fast development a lot too because there's no procedural animations. Now next is probably the hardest part that is the ledge detecting, grabbing and all the animation blending that come with them.

ClimberEditor GravityShiftingCode

Today's work

  • Platformer
    • Roll made a little longer
    • Climbing code
      • Detects wall at certain height and proximity
      • Player rotates to face wall normal
      • Gravity shifts to wall normal
      • "Climbable" physics layer
      • Movement input relative to wall normal
      • Leaps to direction of input
      • Slips constantly and slides off after certain time

Monday 30.5 | Roll & Air Control

3D Stealth Platformer Prototype

Today's focus has been on air control and getting the rolling animation working in unity.

Problems Implementing Roll

I wanted the roll animation to benefit from it's root motion, in hopes of making it look half decent. This meant that I would have to disable the characters movement when the roll was triggered and then enabling it after the roll had finished. So I needed to know when the animation would stop and call a function to set a boolean variable "rolling" to false, enabling the movement.

AnimationEvent

I tried doing this via Unity's animation events but had an issue where the events weren't triggering and read that it can be unreliable with transitions and such. More problems arose though as I tried implementing my own animation event system. I did this because someone had implemented a coroutine based system and I thought I'd try it out but got caught in trying to make it highly scalable which it really didn't need to be.

PlayerRoll

After getting back to Unity's animation events I realized it was the animators transition that messed with the event. This was fixed by triggering the event earlier in the animation lifetime. So what came of it was a mess and I should've just stuck with the animation events. Just another reminder to keep it simple.

Air Control & Rolling

  • Air control
    • Controllable from half influence to none
    • Character turns slower
    • Character only moves forward unlike when on ground
      • (On ground character moves exactly where joystick is pointing, rotation being a gimmick)
    • Animation events used to stop character controller movement when attacking to use root motion from the animations for precise attacking
  • Roll
    • Character horizontal movement stops to allow root motion to do its job
CharacterControllerFields

Sunday 29.5 | Movement

3D Stealth Platformer Prototype

This is the first daily post so I will be telling a little about where the project is right now as well as today's work.

Current state

This week I have worked on movement which needs some polishing and a whole roll mechanic before being able to move onto other things. After all the basics are in place I can start to thinking about what mechanics are still needed for fun gameplay.

  • Behaviour tree implementation with the help of this Behaviour Tree Tutorial
    • Currently the only behaviours the enemies have are chasing when they spot a player and patrolling.
  • Scivolo Character Controller as base. Scivolo Character Controller
    • Just moved from Unity's own third person controller to this one because of the added flexibility.
  • Environment from Unity's 3rd person template.
  • Animations from Mixamo. (Sword and Shield Pack)
  • Enemies and rest are from past projects of mine or from the Unity Starter Assets.
ScreenshotOfEnemyFromEditor PlayerAnimatorSimple

Movement

Today I focused on migrating away from using Unity's built-in Character Controller component. Reason being the very limited control you have over the Unity's solution and weird "physics" behaviour. For me this weird behaviour was a slowing down of the character when jumping and landing.

  • Going from unity template 3rd person to scivolo character controller
    • Extracting everything useful from template
      • Camera rotation
      • Animator and State setting from script
      • Own attack scripts moved
      • Running -> Walking -> Idle, Animation blending smoothed
      • Air control