Created
June 24, 2020 09:42
-
-
Save Pikachuxxxx/0bf012bd8d3c61e88ea683ec45e8cf71 to your computer and use it in GitHub Desktop.
Unity Crowd NPC Behaviour
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.AI; | |
public enum NPCType | |
{ | |
Loner, | |
Herders, | |
Atteners | |
} | |
public class NPC : MonoBehaviour | |
{ | |
//Public variables | |
public float moveSpeed; | |
public NPCType npcType; | |
//public NPCState npcState; | |
public Area[] npcAreas; | |
public StateManager playerState; | |
public AudioSource killSound; | |
public int killAlertRadius; | |
public NavMeshAgent meshAgent; | |
[Header("Character Settings")] | |
public Animator npcAnim; | |
#region Latch State Variables | |
protected Area previousAssignedArea = null; | |
protected Vector3 previousTarget = Vector3.zero; | |
protected Area assignedArea; | |
protected Vector3 target; | |
protected int selectedAreaIndex; | |
#endregion | |
public void MoveNPC(Vector3 targetPosition) | |
{ | |
meshAgent.speed = moveSpeed; | |
meshAgent.SetDestination(targetPosition); | |
} | |
public virtual void Die(Action killAction, Vector3 LKPlayerPos) | |
{ | |
assignedArea.NPCsList.Remove(gameObject); | |
npcAnim.SetTrigger(ACParams.NPCs.isDying); | |
killSound.Play(); | |
Destroy(gameObject, 10f); | |
} | |
public void AlertNearByNPCs(int alertRadius, Vector3 PlayerPosition) | |
{ | |
killSound.maxDistance = alertRadius; | |
killSound.Play(); | |
//Atteners.lastKnownPlayerPos = PlayerPosition [Pseudo Code] | |
} | |
public void UpdateNPCState() | |
{ | |
} | |
protected bool pathComplete() | |
{ | |
if (!meshAgent.pathPending) | |
{ | |
if (meshAgent.remainingDistance <= meshAgent.stoppingDistance) | |
{ | |
if (!meshAgent.hasPath || meshAgent.velocity.sqrMagnitude == 0f) | |
{ | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
protected void AssignArea() | |
{ | |
//choose a random areas from the list of areas | |
assignedArea = npcAreas[Random.Range(0, npcAreas.Length)]; | |
selectedAreaIndex = assignedArea.areaIndex; | |
if (previousAssignedArea == null) | |
previousAssignedArea = assignedArea; | |
if (assignedArea.isAccessible) | |
{ | |
if (assignedArea != previousAssignedArea) | |
{ | |
// now see if that area is of the right type for the NPC and if it is accessible | |
if (assignedArea.areaType == (AreaType)npcType) | |
{ | |
// If so then choose a paricular point in the area and move to that point | |
assignedArea.NPCsList.Add(gameObject); | |
previousAssignedArea.NPCsList.Remove(gameObject); | |
} | |
} | |
previousAssignedArea = assignedArea; | |
} | |
} | |
protected void AssignArea(bool getPoint) | |
{ | |
//choose a random areas from the list of areas | |
assignedArea = npcAreas[Random.Range(0, npcAreas.Length)]; | |
selectedAreaIndex = assignedArea.areaIndex; | |
if (previousAssignedArea == null) | |
previousAssignedArea = assignedArea; | |
if (previousTarget == Vector3.zero) | |
previousTarget = target; | |
if (assignedArea.isAccessible) | |
{ | |
if (assignedArea != previousAssignedArea) | |
{ | |
// now see if that area is of the right type for the NPC and if it is accessible | |
if (assignedArea.areaType == (AreaType)npcType) | |
{ | |
// If so then choose a paricular point in the area and move to that point | |
if (getPoint) | |
target = assignedArea.getAPlaceInArea; | |
assignedArea.NPCsList.Add(gameObject); | |
previousAssignedArea.NPCsList.Remove(gameObject); | |
assignedArea.NPCsDestination.Add(target); | |
previousAssignedArea.NPCsDestination.Remove(previousTarget); | |
} | |
} | |
previousAssignedArea = assignedArea; | |
previousTarget = target; | |
} | |
} | |
protected void AssignArea(bool getPoint, bool moveNPC) | |
{ | |
//choose a random areas from the list of areas | |
assignedArea = npcAreas[Random.Range(0, npcAreas.Length)]; | |
selectedAreaIndex = assignedArea.areaIndex; | |
if (previousAssignedArea == null) | |
previousAssignedArea = assignedArea; | |
if (previousTarget == Vector3.zero) | |
previousTarget = target; | |
if (assignedArea.isAccessible) | |
{ | |
if (assignedArea != previousAssignedArea) | |
{ | |
// now see if that area is of the right type for the NPC and if it is accessible | |
if (assignedArea.areaType == (AreaType)npcType) | |
{ | |
// If so then choose a paricular point in the area and move to that point | |
if (getPoint && moveNPC) | |
{ | |
target = assignedArea.getAPlaceInArea; | |
MoveNPC(target); | |
assignedArea.NPCsList.Add(gameObject); | |
previousAssignedArea.NPCsList.Remove(gameObject); | |
assignedArea.NPCsDestination.Add(target); | |
previousAssignedArea.NPCsDestination.Remove(previousTarget); | |
} | |
} | |
} | |
previousAssignedArea = assignedArea; | |
previousTarget = target; | |
} | |
} | |
public void ReshuffleNPCAreas(AreaType areaToMove) | |
{ | |
} | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
//#region Debug Draw | |
//protected void DrawPath() | |
//{ | |
// var nav = meshAgent; | |
// if (nav == null || nav.path == null) | |
// return; | |
// var line = this.GetComponent<LineRenderer>(); | |
// if (line == null) | |
// { | |
// line = this.gameObject.AddComponent<LineRenderer>(); | |
// line.material = new Material(Shader.Find("Sprites/Default")) { color = Color.yellow }; | |
// line.SetWidth(0.5f, 0.5f); | |
// line.SetColors(Color.red, Color.red); | |
// } | |
// var path = nav.path; | |
// line.SetVertexCount(path.corners.Length); | |
// for (int i = 0; i < path.corners.Length; i++) | |
// { | |
// line.SetPosition(i, path.corners[i]); | |
// } | |
//} | |
//#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment