Enemy AI & State Trees
I designed and implemented enemy AI behavior using Unreal Engine State Trees. This organizes enemy decision-making into structure states and transitions, making behaviors easier to develop, understand, and maintain.
Gameplay Programmer
GAMEPLAY PROGRAMMING / UNREAL
S.O.R.N. is a third-person mech action game developed by a 15-member team. Built in Unreal Engine 5, the project combines fast-paced combat, mission-based gameplay, and enemy AI systems. My contributions include prototyping and implementing enemy AI behavior using state trees, developing tools for designers to streamline level design, and developing a centralized player settings system for visual, camera, subtitle, and audio customization.
Experience S.O.R.N.'s mech combat, high-mobility gameplay, and mission environments.
I designed and implemented enemy AI behavior using Unreal Engine State Trees. This organizes enemy decision-making into structure states and transitions, making behaviors easier to develop, understand, and maintain.
S.O.R.N. combines mech combat with mission objectives and enemy encounters. These systems work together to establish the pacing and readability of combat throughout the player experience.
PLAYER CUSTOMIZATION
I implemented a centralized settings system that gives players control over visual presentation, camera behavior, subtitle preferences, and audio levels.
Runtime brightness adjustment using a dynamic material instance.
Player-adjustable camera FOV.
Subtitle visibility toggle and size adjustment.
Player-adjustable audio levels.
void USORNGameSettings::ApplySettings(bool bCheckForCommandLineOverrides)
{
Super::ApplySettings(bCheckForCommandLineOverrides);
//Engine only
if (GEngine)
{
GEngine->bSubtitlesEnabled = bSubtitles;
}
UWorld* World = GEngine ? GEngine->GetCurrentPlayWorld() : nullptr;
if (!World)
{
SaveSettings();
return;
}
for (TActorIterator<APostProcessVolume> It(World); It; ++It)
{
APostProcessVolume* PPV = *It;
if (PPV && PPV->bUnbound)
{
if (BrightnessBaseMaterial)
{
if (!BrightnessMID)
BrightnessMID = UMaterialInstanceDynamic::Create(BrightnessBaseMaterial, this);
PPV->Settings.AddBlendable(BrightnessMID, 1.0f);
}
if (BrightnessMID)
{
BrightnessMID->SetScalarParameterValue(TEXT("Brightness"), Brightness);
}
break;
}
}
}
Centralize player settings in one system instead of distributing settings logic across multiple components. This also simplifies integration with UI widgets.
I implemented controls for brightness, field of view, subtitle visibility and size, and volume levels. The settings system applied engine-level subtitle settings and validates the active world before applying world-specific changes. For brightness, the function locates an unbound post-process volume and applies a dynamic material instance that receives the player's brightness value at runtime.
Players can customize important visual, camera, subtitle, and audio preferences through a centralized settings system, improving flexibility and supporting accessibility.
ENVIRONMENT TOOLING
Create a way for designers to build cliff walls by drawing and adjusting a spline instead of manually placing individual assets.
The tool uses a designer-controlled spline to guide cliff mesh placement. IT randomly selects between two static meshes and applies randomized roation to introduce variation along the generated wall.
Designers can create and modify cliff walls directly in the editor, reducing repetitive placement work while retaining control over the environment layout.