An eye for heuristics
An eye for heuristics
To streamline a survival management game, there is no shortcut to good UI
Systems design to create flow
To check the Chi of changing rooms, systems which are flexible to level design are needed
Player focused procedural generation
Give the player paths, reward them for straying
Determining a persona
Who is our game for
Juice
Juice
There are many items to create a unique room, some even using cellular automata art
User testing review
User testing review
Our game is nothing without user feedback. We frequently test Citadrill to our public
An eye for heuristics
An eye for heuristics
An eye for heuristics
Extensive research and comparison is being made behind UI and UX decisions.
Systems design for flow
Systems design for flow
Systems design for flow
Decisions fall into preparing, interpreting feedback, and adapting
Persona
Persona
Persona
Who is our game for?
Player focused procedural generation
Player focused procedural generation
Player focused procedural generation
Give the player a path, and prepare for them to leave it
Juice
Juice
Juice
Players are able to quickly determine whether they are in danger through intense and clear feedback
Post processing was modified over a curve and called back via other events to gain precise control
using Mali.Cinemachine_Extensions;
using System.Collections;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class DynamicPostProcessingController : MonoBehaviour
{
[SerializeField]
private VolumeProfile volumeProfile;
private ChromaticAberration chromaticAberrationEffect;
private LensDistortion lensDistortionEffect;
private Bloom bloomEffect;
private Vignette vignetteEffect;
private float chromaticAberrationIntensity = 0.1f; // Initial intensity value
private float lensDistortionIntensity = 0; // Initial intensity value
private float bloomIntensity = 0.5f; // Initial intensity value
private float vignetteIntensity = 0f; // Initial intensity value
Coroutine lastCoroutine;
public AnimationCurve curve;
public float duration = 1f;
public float startValue = 0f;
public float endValue = 1f;
public AnimationCurve curveDeath;
public float durationDeath = 1f;
[Header("Camera Shake")]
public float shakeDuration=0.5f;
public float amplitude;
public float frequency;
private float timer = 0f;
private float timerDeath = 0f;
private void Start()
{
// Ensure we have a reference to the Volume Profile
if (volumeProfile == null)
{
Debug.LogError("Volume Profile reference not set!");
return;
}
// Initialize the chromatic aberration effect
if (!volumeProfile.TryGet(out chromaticAberrationEffect))
{
Debug.LogError("Chromatic Aberration effect not found!");
return;
}
// Initialize the Lens Distortion effect
if (!volumeProfile.TryGet(out lensDistortionEffect))
{
Debug.LogError("Lens Distortion effect not found!");
return;
}
// Initialize the bloom effect
if (!volumeProfile.TryGet(out bloomEffect))
{
Debug.LogError("Bloom effect not found!");
return;
}
if (!volumeProfile.TryGet(out vignetteEffect))
{
Debug.LogError("Vignette effect not found!");
return;
}
// Set the initial intensity of chromatic aberration
chromaticAberrationIntensity = curve.Evaluate(1);
lensDistortionIntensity = curve.Evaluate(1);
bloomIntensity = curve.Evaluate(1);
vignetteIntensity = curve.Evaluate(1);
chromaticAberrationEffect.intensity.Override(chromaticAberrationIntensity);
lensDistortionEffect.intensity.Override(lensDistortionIntensity);
bloomEffect.intensity.Override(bloomIntensity);
vignetteEffect.intensity.Override(vignetteIntensity);
}
IEnumerator DamagePostProcessingCurve()
{
while (timer < duration)
{
float normalizedTime = timer / duration;
float curveValue = curve.Evaluate(normalizedTime);
chromaticAberrationIntensity = curveValue;
lensDistortionIntensity = curveValue;
lensDistortionEffect.intensity.Override(lensDistortionIntensity);
chromaticAberrationEffect.intensity.Override(chromaticAberrationIntensity);
timer += Time.deltaTime;
yield return null;
}
}
IEnumerator DeathPostProcessingCurve()
{
timerDeath = 0;
while (timerDeath < durationDeath)
{
float normalizedTime = timer / durationDeath;
float curveValue = curveDeath.Evaluate(normalizedTime);
vignetteIntensity = curveValue;
vignetteEffect.intensity.Override(vignetteIntensity);
bloomIntensity = curveValue;
bloomEffect.intensity.Override(bloomIntensity);
lensDistortionIntensity = curveValue;
lensDistortionEffect.intensity.Override(lensDistortionIntensity);
chromaticAberrationIntensity = curveValue;
chromaticAberrationEffect.intensity.Override(chromaticAberrationIntensity);
timerDeath += Time.deltaTime;
//Debug.Log("TimerDeath: " + timerDeath);
yield return null;
}
}
public void StartDamagePostProcessingCurve()
{
timer = 0;
lastCoroutine = StartCoroutine(DamagePostProcessingCurve());
CameraEffectsController.Instance.DoCameraShake(shakeDuration, 0.1f, 4f, VCAMType.Drill);
}
public void StartDeathPostProcessingCurve()
{
//StopAllCoroutines();
if(lastCoroutine != null) StopCoroutine(lastCoroutine);
lastCoroutine = StartCoroutine(DeathPostProcessingCurve());
//CameraEffectsController.Instance.DoCameraShake(shakeDuration, 0.1f, 4f, VCAMType.Drill);
using Mali.Cinemachine_Extensions;
using System.Collections;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class DynamicPostProcessingController : MonoBehaviour
{
[SerializeField]
private VolumeProfile volumeProfile;
private ChromaticAberration chromaticAberrationEffect;
private LensDistortion lensDistortionEffect;
private Bloom bloomEffect;
private Vignette vignetteEffect;
private float chromaticAberrationIntensity = 0.1f; // Initial intensity value
private float lensDistortionIntensity = 0; // Initial intensity value
private float bloomIntensity = 0.5f; // Initial intensity value
private float vignetteIntensity = 0f; // Initial intensity value
Coroutine lastCoroutine;
public AnimationCurve curve;
public float duration = 1f;
public float startValue = 0f;
public float endValue = 1f;
public AnimationCurve curveDeath;
public float durationDeath = 1f;
[Header("Camera Shake")]
public float shakeDuration=0.5f;
public float amplitude;
public float frequency;
private float timer = 0f;
private float timerDeath = 0f;
private void Start()
{
// Ensure we have a reference to the Volume Profile
if (volumeProfile == null)
{
Debug.LogError("Volume Profile reference not set!");
return;
}
// Initialize the chromatic aberration effect
if (!volumeProfile.TryGet(out chromaticAberrationEffect))
{
Debug.LogError("Chromatic Aberration effect not found!");
return;
}
// Initialize the Lens Distortion effect
if (!volumeProfile.TryGet(out lensDistortionEffect))
{
Debug.LogError("Lens Distortion effect not found!");
return;
}
// Initialize the bloom effect
if (!volumeProfile.TryGet(out bloomEffect))
{
Debug.LogError("Bloom effect not found!");
return;
}
if (!volumeProfile.TryGet(out vignetteEffect))
{
Debug.LogError("Vignette effect not found!");
return;
}
// Set the initial intensity of chromatic aberration
chromaticAberrationIntensity = curve.Evaluate(1);
lensDistortionIntensity = curve.Evaluate(1);
bloomIntensity = curve.Evaluate(1);
vignetteIntensity = curve.Evaluate(1);
chromaticAberrationEffect.intensity.Override(chromaticAberrationIntensity);
lensDistortionEffect.intensity.Override(lensDistortionIntensity);
bloomEffect.intensity.Override(bloomIntensity);
vignetteEffect.intensity.Override(vignetteIntensity);
}
IEnumerator DamagePostProcessingCurve()
{
while (timer < duration)
{
float normalizedTime = timer / duration;
float curveValue = curve.Evaluate(normalizedTime);
chromaticAberrationIntensity = curveValue;
lensDistortionIntensity = curveValue;
lensDistortionEffect.intensity.Override(lensDistortionIntensity);
chromaticAberrationEffect.intensity.Override(chromaticAberrationIntensity);
timer += Time.deltaTime;
yield return null;
}
}
IEnumerator DeathPostProcessingCurve()
{
timerDeath = 0;
while (timerDeath < durationDeath)
{
float normalizedTime = timer / durationDeath;
float curveValue = curveDeath.Evaluate(normalizedTime);
vignetteIntensity = curveValue;
vignetteEffect.intensity.Override(vignetteIntensity);
bloomIntensity = curveValue;
bloomEffect.intensity.Override(bloomIntensity);
lensDistortionIntensity = curveValue;
lensDistortionEffect.intensity.Override(lensDistortionIntensity);
chromaticAberrationIntensity = curveValue;
chromaticAberrationEffect.intensity.Override(chromaticAberrationIntensity);
timerDeath += Time.deltaTime;
//Debug.Log("TimerDeath: " + timerDeath);
yield return null;
}
}
public void StartDamagePostProcessingCurve()
{
timer = 0;
lastCoroutine = StartCoroutine(DamagePostProcessingCurve());
CameraEffectsController.Instance.DoCameraShake(shakeDuration, 0.1f, 4f, VCAMType.Drill);
}
public void StartDeathPostProcessingCurve()
{
//StopAllCoroutines();
if(lastCoroutine != null) StopCoroutine(lastCoroutine);
lastCoroutine = StartCoroutine(DeathPostProcessingCurve());
//CameraEffectsController.Instance.DoCameraShake(shakeDuration, 0.1f, 4f, VCAMType.Drill);