Skip to content

Instantly share code, notes, and snippets.

@Pikachuxxxx
Created June 24, 2020 09:42
Show Gist options
  • Save Pikachuxxxx/0bf012bd8d3c61e88ea683ec45e8cf71 to your computer and use it in GitHub Desktop.
Save Pikachuxxxx/0bf012bd8d3c61e88ea683ec45e8cf71 to your computer and use it in GitHub Desktop.
Unity Crowd NPC Behaviour
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