
NPCs in 3D Unity Game Design: Strategies for Hazard and Gameplay
Discover essential elements for NPCs in a 3D Unity game to provide both challenge and engaging gameplay, including insights on NavMesh, targeting, defense, and decision-making. Enhance your game with smart AI strategies.
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
DES315: Technical Design Methods Extra Credit Projects NPC version of your Bot Custom Arena
NPCs What does an NPC in a 3D Unity game need to include, to be potential hazard, but also to provide manageable gameplay (including a rhythm to attacks and pauses)? NavMesh Targeting Defense Decision Tree Predictability and Variety
NPCs: NavMesh NavMesh: a system in Unity to define walk-able and non-walkable areas for NPC AI, and give your NPC a smart route to navigate to a destination/target. Given an environment (Terrain and/or meshes), organize all Hierarchy elements under Empty Gos named Env_Walkable and Env_NotWalkable Window > AI > Navigation (to set object NavMesh properties and bake) 1a) Object tab: select all Walkable object/s in scene (terrain or meshes), turn on Navigation Static, and set Navigation Area = walkable 1b) Bake tab: Hit [Bake]. In the Scene view, turn on Show NavMesh to see the walkable area in blue. 2a) Object tab: select all NotWalkable object/s in scene (meshes), turn on Navigation Static, and set Navigation Area = not-walkable 2b) Bake tab: Hit [Bake]. In the Scene view, turn on Show NavMesh to see the interruptions in the walkable area around your meshes. 3) To get an interactive obstacle (moves holes in NavMesh if moved in scene): a) Select your not-walkable meshes, Re-bake with Navigation Static turned off. b) [Add Component] Navmesh Obstacle . Set shapes as desired (box or capsule). Set Carve = on, and re-Bake into the NavMesh!
NPCs: NavMesh Add the NavMeshAgent Component to any mobile GO (NPCs) to allow them to use a NavMesh: Make a simple NPC (cube, ScaleY=2). Parent to an EmptyGO named NPC (after setting both position transforms to zero). Select your NPC, add a box collider (move to cover base). [Add Component] NavMeshAgent. Set Speed (try 10 for a fast NPC) and AngularSpeed (how quickly it goes around obstacles: try 300) Create a C# script called NPCmove.cs. Add the AI namespace and NavMeshAgent: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class NPCmove : MonoBehaviour { NavMeshAgent myAgent; void Start() { myAgent = GetComponent<NavMeshAgent>(); } void Update() { RaycastHit hit; if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100)) { myAgent.destination = hit.point; } } }
NPCs: Targeting Enemies Targeting: how do we make our NPC move towards or shoot towards a target? A simple way in Unity is to rotate the NPC towards the target with transform.LookAt and then move forward on the z-axis (since forward is now looking-towards the target) public Transform target; public Rigidbody rb; public float speed = 1f; void Update() { // Rotate the camera every frame so it keeps looking at the target transform.LookAt(target); rb.velocity = transform.forward * m_Speed; } But the NavMeshAgent Component handles this directly: private NavMeshAgent myAgent; public Transform playerTarget; myAgent.destination = playerTarget.position; (Please see my sample monster script, NPC_PatrolAndAttack.cs, )
NPCs: Targeting Enemies: Loading Targets How do we load the opponent as the player target, or both players? Search for the Player1 or 2 tag and get the transform.GetChild(0). In our game, loading is complicated for Monsters, who may be in the scene before the players, and so cannot simply load them in the Start() function (unless they are instantiated by players touching a part of the map). My solution: I added a bool isCoop to the GameHandler, and one of the things this does (in addition to sending Game-Over results to a new EndSceneCoop) is to search for the monster with the tag CoopNPCMonster and flip a switch on a script component called NPC_LoadPlayers (add both to all monsters): GameObject.FindWithTag("CoopNPCMonster").GetComponent<NPC_LoadPlayers>().LoadPlayerTargets(); My sample monster script, NPC_PatrolAndAttack.cs, seeks out this switched- on bool playersReady and loads the players: player1Target = GameObject.FindWithTag("Player1").transform.GetChild(0).GetComponent<Transform>(); player2Target = GameObject.FindWithTag("Player2").transform.GetChild(0).GetComponent<Transform>();
NPCs: Targeting Enemies Other useful technique include: A* ( A-Star ) for pathfinding between nodes Raytracing to identify what the bot actually sees (as opposed to just measuring distance, which does not take into account any cover that the player may be trying to hide behind) Please see the short tutorial videos for these systems on our course site, Project 4!
NPCs: Defense Defense: How does the NPC defend itself from attack? One simple way (for NPCs that shoot projectiles) is to maintain a distance: look at the distance between the NPC and the Player/s, and stop moving towards the player when reaching a threshold, or move away if the player approaches within the threshold (backwards, if they are still looking at the player). Another is to limit the WoO (Window of Opportunity). Perhaps the NPC can hide behind obstacles, or its vulnerable area is occasionally protected, so the player needs to regularly change position and look for an opening to attack. Design for Timing Considerations: Here are Four Ways to Test Player Timing that could inspire bot or monster behavior: Anticipation Time Window of Opportunity (WoO) NPC Predictability Input Change Frequency NOTE: this project already has a pretty intensive Input Change Frequency, with 4 control buttons + weapons , so keep the other timing tests easy/large!
NPCs: Decision Tree We can create a complex webState changes based on proximity to player/enemy, enemy health, game time remaining, or other factors. Finite State Machines (FSM): A robust system in the Unity Animator panel to manage NPC behavior! 1. Create a new Animator, name it yourNPCname_FSM, and doubleclick to open the Animator panel. 2. RightClick in the Animator workspace to Create State > Empty, and set the name of the behavior in the Inspector. 3. Click [Add Behaviour], name it (like Patrol ), hit [Create and Add] to create the behavior script with Enter, Update, and Exit methods. Please see the short tutorial videos for these systems on our course site, Project 4! We can also simply create a tree of if-conditions and loops to determine the NPC behavior given specific conditions.
NPCs: Predictability and Variety Players want to be able to form strategies for dealing with your NPC, base don some amount of predictability. If the Monster has a patrol routine between 2-4 points. The NavMesh can be used to send the Monster to the next location among a sequence of transform.positions. What other predictability can be built into your Monster?
NPCs: Predictability and Variety Variety an be built into your NPC by offering conditional statements based on nearby environment or player actions. Consider using distance as your determining factor: public float distToPlayer1; public float distToPlayer2; public bool attackPlayer1 = false; public bool attackPlayer2 = false; void Update() { if ((player1Target != null)&& (player2Target != null)){ //get distances to players distToPlayer1 = Vector3.Distance(player1Target.position, gameObject.transform.position); distToPlayer2 = Vector3.Distance(player2Target.position, gameObject.transform.position); //is the player close enough to attack? if ((distToPlayer1 <= playerAttackDistance)&&(distToPlayer1 < distToPlayer2)) { attackPlayer1 = true; } else { attackPlayer1 = false; } if ((distToPlayer2 <= playerAttackDistance)&&(distToPlayer2 < distToPlayer1)) { attackPlayer2 = true; } else { attackPlayer2 = false; } } What other variety-behavior can be built into your Monster?
TRAPS: Basic Principles Anyone making a PvP Arena or Co-op Level is expected to include at least one kind of Trap . These can include ways to directly attack the player, or change something in the game space that significantly impacts gameplay (like flipping or rotating the world, or adding or removing higher ground). How do we avoid traps from feeling like just a hit-point tax? By making them work more like a puzzle to be solved than a danger to be endured. Consider repeating the Trap so players can learn to use it, and area design that offers players multiple solutions to the traps. What interesting player choices can you inspire with your trap ? Other considerations: You can include power-ups in your level for enhanced speed or to enhance damage done to opponents. You can (and should) add cover and vertical variation in your levels. See the critical Trap Questions on the next page:
TRAPS: Critical Questions Will players see the trap coming? Every trap should announce itself, overtly or subtly: some ways for the players to reasonably suspect that danger is near, so they do not feel the system is unfair. Will players be able to deal with the trap when it is sprung? As with the NPCs, Traps should consider Timing Tests for players: Anticipation Time, Window of Opportunity, Predictability, and Input Change Frequency. Will players feel the trap works consistently?Traps should be consistent to offer players predictability within which to strategize. Throughout a level, driving over the yellow squares will reliably electrify the player, etc. Will players feel cheated or lied to? Players should feel that the level is working within an established set of rules; the player may not yet know what all of those rules are, but it should not feel like chaos or constant gotchas. Avoid hitting the player suddenly from behind, or much faster than the average bot can move. Will players need to keep moving?The players should feel a constant pressure to act, to keep progressing forward. Notes inspired by this thread: https://bit.ly/39o0ri6
TO DO THIS WEEK 1. Please enter revisions and color-code your project #4 feature description on our Google Doc: PvP Trap Arena, PVP NPC Bot Co-op Trap-level, Co-op NPC Monster 2. Cooperate for Co-op: Review the list are you making an NPC Monster? Talk to people making the co-op levels to see which might be a good fit! 3. Change your Button Prefab link to a new scene: to the level if you are making a PvP or Co-op level, or to a new Scene to showcase your NPC behavior. 4. Progress your feature in Unity, to show next class. Try to stay in a prototyping mindset: resist the temptation to work on everything: stay focused on one question to answer and playtest. Close A loop! 5. Please read Jeff Orkin's 2006 paper on Finite State Machines, available on the course site. It offers insights into NPC behavior design and can inspire ideas for those creating new and exciting traps/spaces!