Game Overview
Drojan is a 3D stealth/puzzle hacking game, featuring a drone as the player, where you navigate through the office building to find and steal back the firmware that makes servers unhackable. Along the way there are guards, employees and security cameras that will stop you from doing your job so easily. This project was developed as a final year project at University of Bolton, England.Story
A disgruntled Ex-employee of a private security firm, wants to steal back their firmware prototype that makes any server unhackable. But there is one set back, the security firm has their biometric data on record making it impossible for them to physically enter the building, so using a prototype drone that they have created, they will be able to break into the office to find and take back their firmware.My Roles
What the project taught me:
Guard Patrolling
A code sample taken from the guard controller that deals with how the AI patrols to the next waypoint in queue.void AGuardController::Patrol() { Guard = Cast<AGuardCharacter>(Blackboard->GetValueAsObject(SelfActor_Key)); // Set guard as selfactor from BB if (Guard != nullptr) // check to make sure its not null to avoid any crashes { for (int i = 0; i < Guard->TargetPoint.Num(); i++) { if (Guard->TargetPoint[NextTarget] != nullptr) // if the next target isnt null to avoid anycrashes { if (Guard->GetActorLocation().Equals(Guard->TargetPoint[NextTarget]->GetActorLocation(), 100.0f)) // guard location equal to target location with tolerence { IsMoving = false; if (!IsMoving) { if (NextTarget >= (Guard->TargetPoint.Num() - 1)) { NextTarget = 0; // Set back to 0 if no more targets } else { NextTarget = NextTarget + 1; // Go to next target if there is one to go to IsMoving = true; } } } else { BlackboardComp->SetValueAsVector(TargetPoint_Key, Guard->TargetPoint[NextTarget]->GetActorLocation()); // Set the vector of the target location -- passes to behavior tree IsMoving = true; // set this to true so we don't run the above code } } } } }
Guard Sight Perception
A code sample taken from the guard controller that shows how the guard can see the player through sight perception.GetAIPerceptionComponent()->GetActorsPerception(testActors[i], Info); if (Info.LastSensedStimuli[i].Type == 0) // Sight { const FAIStimulus Stimulus = Info.LastSensedStimuli[0]; if (Stimulus.WasSuccessfullySensed()) { // Player in sight Character = Cast<ADroneCharacter>(Info.Target); if (Character != nullptr) // Check if character isnt null { PlayerSpotted = true; // Set player spotted DelayTimer = 0.0f; // Reset delay timer } } else { PlayerSpotted = false; if (PlayerDetected) { LastKnownLocation = Stimulus.StimulusLocation; // Set last known location AIState = EAIState::SEARCH; // Change state BlackboardComp->SetValueAsEnum(EnumKey_Key, EAIState::SEARCH); // Update state in BB } } }
Exposing Functions & Variables
Examples of how functions and variables were exposed for the designers, to use with Blueprints.// All done in header files // BlueprintReadWrite allows the designer to call it in Blueprint and EditAnywhere will enable the designer to change this value on the fly UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="AI Perception") // UPROPERTY for variables bool PlayerSpotted = false; // BlueprintCallable lets the designer call this function to code UFUNCTION(BlueprintCallable, Category = "Camera View") // UFUNCTION for functions void HackingView(); UFUNCTION(BlueprintCallable, Category="Camera View") void PlayerView();
AI Demo
Game Trailer