SchultzGames
Para tirar dúvidas, crie um tópico especifico na área "Dúvidas em Geral" e aguarde ser respondido. Evite comentar em tópicos não relacionados a sua dúvida :D
TÓPICOS RECENTES:
Tópico:
Postado em:
Postado por:
Inimigo Com Movimento de Ondas(ZigZag)
Movimentação para todas as direções em um jogo multiplayer online
DKG - Dynamic Kit Generator
Stamina/Sede - Movimentação
Emissão de luz em objeto não estático.
Gerenciar carregamento de texturas
Texturas rosas ao extrair materiais do objeto, com modelo .dae
Modelador (Personagem + Roupa) com Direito a Remuneração
Pegar material especifico do objeto
ERRO AO UPAR NA GOOGLE PLAY STORE
[RESOLVIDO] Navegation Unity 3D
[TUTORIAL] AI Enemy 2.0 + animações ( Jogos de terror )
JOGO "CHALLENGE" FINALIZADO E DISPONÍVEL PARA BAIXAR.
preciso de um programador que entenda de Photon pago via Pix pela ajuda!!
[RESOLVIDO] Desativar e ativar objeto com o mesmo botão
Objetos da Unity com cores erradas.
[RESOLVIDO] Botão não está desativando pelo GetComponent
Adição de um Bone à outra Armature no Blender não funciona na Unity
Posição local do pixel de um quad
Shader Graph UI
Rotacionar objeto em apenas um eixo
[ASSET] Sistema completo de Auto Save para Editor
Criar uma aplicação tipo controle remoto bluetooth.
Easy Road 3d - Preciso de Ajuda
Alguem ai Entende de Multiplayer?
alguem pode me ajudar com essa adição de item numa lista?
APK para Android 12 não executa aplicação, Help Please
[TUTORIAL] Sprites Animados
REMOVER RESOLUÇOES
Unity > Editor > Any Android Device bugado!
Erro de Referência
terminei meu jogo, mas algo deu errado.
Erro ao iniciar jogo após a build
Posição Invertida No Multiplayer
Unity 5 - Invalid serialized file header
Character Controller Slide
Sombras desaparecem qnd o bake das luzes termina
Blender - Programa ou site que faça o Rig da face do Personagem
Meu PC deu pro mundo! e agora?
[RESOLVIDO] Player atravessa Parede mesmo com os Colliders
Movimentação 3D
[RESOLVIDO] - Blender - Erro deixa objeto Transparente
[ASSET] Criar TerrainLayer utilizando textura selecionada
Interrogação beta, jogo de puzzle 3D
[RESOLVIDO] Problemas com script (Movimentação em primeira pessoa)
[TUTORIAL] Busca Customizada De Objetos Na Cena
[RESOLVIDO] menu de troca de itens!!
[RESOLVIDO] Ajuda com script de dano por queda
PROCURO ARTISTA PARA PROJETO FPS CQB ( ARTES ESTILO RAINBOW SIX)
Versão Trial do meu jogo [O Sanatório Macabro]
Procuro por mentoria mobile
Corpo da cobra estilo Slither.io
[RESOLVIDO] Animação se repetindo mesmo com loop time desmarcado
mouselock
[RESOLVIDO] Como mostrar um valor em forma de texto na tela?
[RESOLVIDO] Ajuda com material na UI
Neural network treinar condução autónoma do carro
Como posso definir um código OnTriggerEnter2D para 2 Colliders específicos?
Joystick Virtual como adaptar a esse código ??
Quando recarrego o tiro sai junto como resolvo
Sistemas de Monetização
erros no unity(terrain)
sistema de paticulas em itens
Jogo de futebol em 2D
Imagen do botão sumiu
Movimento em 1° pessoa
[RESOLVIDO] Unity - Sugestão sobre a Tela Inicial/Introdutória
Alguém sabe usar spline mash , para fazer curvas num objeto3d?
PRECISO DE SCRIPTS PARA ADD INIMIGO NO MAPA
[RESOLVIDO] alguém sabe como fazer um unico Input fazer duas ações?
Jogo fechando e dando erros no console (MOBILE)
[DÚVIDA] alguém que já publicou na steam pode ajudar?
Duvida sobre transform.position!
como eu consigo chamar uma void pelo comando Input.GetKey?
como pegar as informações de um objeto que foi selecionado no unity
Fade In/Out em Teleporte
Mudar Direção dos Eixos - 2
Alguem pode me explicar como funciona o save?
Destroying assets is not permitted to avoid data loss.
Me ajude a resolver o Bug do sistema de portas.
Capsule Collider e Rigidbody
Estou com esses erros no asset que eu comprei 'EventReference' 'FMOD'
Servidor Node.JS dentro do UNITY?
Como gravar o nome de um personagem inserido pelo usuário no unity
Como colidir apenas com gameobjects com um tag específica
Como adicionar item em uma lista
Erro ao Construir arquivo Google play store Bundle
[TUTORIAL] Sistema de DIA E NOITE completo, com luzes noturnas e SISTEMA DE NUVENS
dano inimigo em player
Jogo de futebol em 2D
Como fazer uma mira de referencia (que fica no centro da tela)
Unity - Como sinalizar um objeto para o Jogador?
Ataque indo em direção do personagem mudando a velocidade
Unity - Traduzir os conteúdos do Jogo
Como fazer o objeto emitido pela partícula ser direcionado até outro objeto
Ajuda em script de inventario
Mudar as imagens da UI com InputSystem
Alguém sabe um componente estilo "Cloth" só que para projeto 2D
Textura PNG transparente fica preta na build
Hoje à(s) 12:52 am
Ontem à(s) 7:44 pm
Ontem à(s) 4:16 pm
Seg Jun 27, 2022 1:10 pm
Dom Jun 26, 2022 6:03 pm
Sab Jun 25, 2022 3:03 pm
Qua Jun 22, 2022 6:21 pm
Qua Jun 22, 2022 1:28 am
Ter Jun 21, 2022 11:42 pm
Ter Jun 21, 2022 2:27 pm
Seg Jun 20, 2022 4:08 pm
Dom Jun 19, 2022 4:38 pm
Dom Jun 12, 2022 12:52 pm
Qui Jun 09, 2022 12:43 am
Ter Jun 07, 2022 7:47 pm
Ter Jun 07, 2022 5:20 pm
Seg Jun 06, 2022 10:16 pm
Dom Jun 05, 2022 4:44 pm
Dom Jun 05, 2022 10:45 am
Dom Jun 05, 2022 9:59 am
Sab Jun 04, 2022 11:24 pm
Sab Jun 04, 2022 4:18 pm
Sab Jun 04, 2022 3:21 pm
Sab Jun 04, 2022 2:24 pm
Sab Jun 04, 2022 2:15 pm
Sex Jun 03, 2022 4:28 pm
Sex Jun 03, 2022 4:11 pm
Qui Jun 02, 2022 8:48 pm
Dom Maio 29, 2022 6:00 pm
Sex Maio 27, 2022 11:32 pm
Sex Maio 27, 2022 3:50 pm
Sex Maio 27, 2022 8:38 am
Qui Maio 26, 2022 6:47 pm
Ter Maio 24, 2022 4:28 pm
Ter Maio 24, 2022 11:01 am
Dom Maio 22, 2022 1:43 pm
Dom Maio 22, 2022 1:38 pm
Dom Maio 22, 2022 11:21 am
Sab Maio 21, 2022 8:01 am
Sex Maio 20, 2022 10:30 pm
Sex Maio 20, 2022 3:36 pm
Sex Maio 20, 2022 3:16 pm
Qui Maio 19, 2022 10:06 pm
Ter Maio 17, 2022 11:07 pm
Ter Maio 17, 2022 10:36 pm
Ter Maio 17, 2022 4:55 pm
Dom Maio 15, 2022 6:25 pm
Sab Maio 14, 2022 4:41 pm
Seg Maio 09, 2022 6:25 pm
Seg Maio 09, 2022 7:28 am
Sab Maio 07, 2022 10:40 am
Sab Maio 07, 2022 12:13 am
Qui Maio 05, 2022 8:48 pm
Qua Maio 04, 2022 10:37 am
Ter Maio 03, 2022 6:23 pm
Seg Maio 02, 2022 8:06 pm
Sab Abr 30, 2022 10:43 pm
Sab Abr 30, 2022 10:35 pm
Sab Abr 30, 2022 8:19 pm
Sab Abr 30, 2022 8:12 pm
Sab Abr 30, 2022 7:54 pm
Sab Abr 30, 2022 7:52 pm
Sab Abr 30, 2022 7:48 pm
Sab Abr 30, 2022 7:44 pm
Sab Abr 30, 2022 7:39 pm
Sab Abr 30, 2022 7:35 pm
Sex Abr 29, 2022 10:03 pm
Qui Abr 28, 2022 8:57 pm
Dom Abr 24, 2022 8:57 pm
Dom Abr 24, 2022 1:53 pm
Sab Abr 23, 2022 6:29 pm
Sab Abr 23, 2022 6:27 pm
Sab Abr 23, 2022 6:22 pm
Sex Abr 22, 2022 8:28 pm
Qui Abr 21, 2022 8:35 pm
Qui Abr 21, 2022 6:54 pm
Qui Abr 21, 2022 12:04 pm
Qui Abr 21, 2022 10:18 am
Qua Abr 20, 2022 6:31 pm
Qua Abr 20, 2022 11:34 am
Ter Abr 19, 2022 10:15 pm
Ter Abr 19, 2022 9:56 pm
Seg Abr 18, 2022 12:18 pm
Sab Abr 16, 2022 9:26 pm
Sab Abr 16, 2022 12:06 pm
Sex Abr 15, 2022 6:16 pm
Qui Abr 14, 2022 9:29 pm
Qui Abr 14, 2022 11:14 am
Qua Abr 13, 2022 6:09 pm
Qua Abr 13, 2022 11:30 am
Ter Abr 12, 2022 7:26 pm
Sab Abr 09, 2022 2:53 pm
Sex Abr 08, 2022 7:57 pm
Qui Abr 07, 2022 8:11 pm
Qua Abr 06, 2022 8:20 pm
Ter Abr 05, 2022 9:56 pm
Sab Abr 02, 2022 9:09 am
Sex Abr 01, 2022 1:55 pm
Qua Mar 30, 2022 10:06 pm
MarcosSchultz
kessisdiones
gabrimo
Mozinhas2
cyborggp
MarcosSchultz
MarcosSchultz
EricknhYT
SteveRogers
SteveRogers
Mozinhas2
DanielGemsYt
lauderson
Vorzoolvan
BlesseD
Emerson Beaver
kessisdiones
WLCS22
gabrimo
Eris
SteveRogers
AnderGames
Diomaker
EricknhYT
claudiano2020
Pokedlg
SteveRogers
lauderson
lauderson
WLCS22
Arcebispo
JoSanInk
Rangel Oblivion
claudiano2020
erickfabio366
Rangel Oblivion
Crash Psycho
WLCS22
Callyde Jr
Pedro1saac
dutrabr100
dutrabr100
AnderGames
Rangel Oblivion
dstaroski
FelipeSouza11
capim22
Rangel Oblivion
dstaroski
Patrick
dstaroski
SteveRogers
Rangel Oblivion
Magnatah
Rangel Oblivion
Charlesoff
Magnatah
stratengine
Magnatah
Magnatah
Magnatah
Magnatah
Magnatah
Magnatah
Magnatah
Magnatah
BlesseD
stratengine
SteveRogers
miguelsainz
claudiano2020
claudiano2020
claudiano2020
miguelsainz
SteveRogers
Triskal
Eris
pedro123
FelipeSouza11
estuartyy
SteveRogers
EricknhYT
azool
Lucas Andrade
stratengine
stratengine
adrianobros2
Pkneves
Pkneves
lilvinicin
Eris
WLCS22
Andrewkeny
WLCS22
SteveRogers
zeref
Crash Psycho
verme1311
Rangel Oblivion

Configurar NPCs

+2
MarcosSchultz
AdrianJps
6 participantes

Ir para baixo

DÚVIDA Configurar NPCs

Mensagem por Daniel Dória Seg Jul 30, 2018 3:54 pm

Baixei o Realistic FPS Prefab para concluir um projeto mas ao usar um player[AI] pronto ele não se meche para nada apenas respira mas se eu atirar eles cai e morre. Logo de cara vi que o Asset está todo desconfigurado já arrumei um bocado de coisas mas essa parte dos NPCs não estou conseguindo.



mas quando vou testar uma cena pronta que vem junto tudo funciona normal já tentei importar dela para minha cena mas não adianta eles voltam a ficar parados lá e não saem do lugar. estou a muito tempo procurando arrumar isso é horrível tentar fazer uma coisa o dia inteiro e não conseguir  alguém pode me ajudar?Distressed

Daniel Dória
Daniel Dória
Avançado
Avançado

Masculino PONTOS : 1898
REPUTAÇÃO : 31
Idade : 20
Respeito as regras : Configurar NPCs WvDYdlf

https://planecaos.jimdofree.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por AdrianJps Seg Jul 30, 2018 4:02 pm

Deixa a gente ver o Script do Npc
AdrianJps
AdrianJps
Iniciante
Iniciante

Masculino PONTOS : 2071
REPUTAÇÃO : 1
Idade : 24
Respeito as regras : Configurar NPCs WvDYdlf

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Daniel Dória Seg Jul 30, 2018 4:35 pm

AdrianJps escreveu:Deixa a gente ver o Script do Npc
AI:

Código:

http://AI.cs by Azuline Studios©️ All Rights Reserved
//Allows NPC to track and attack targets and patrol waypoints.
using UnityEngine;
using UnityEngine.AI;//
using System.Collections;
using System.Collections.Generic;

public class AI : MonoBehaviour {
   [HideInInspector]
   public bool spawned = false;
   [HideInInspector]
   public GameObject playerObj;
   [HideInInspector]
   public Transform playerTransform;
   [HideInInspector]
   public GameObject NPCMgrObj;
   [HideInInspector]
   public GameObject weaponObj;//currently equipped weapon object of player
   [HideInInspector]
   public FPSRigidBodyWalker FPSWalker;
   [HideInInspector]
   public NPCAttack NPCAttackComponent;
   [HideInInspector]
   public PlayerWeapons PlayerWeaponsComponent;
   private WeaponBehavior WeaponBehaviorComponent;
   [HideInInspector]
   public CharacterDamage TargetCharacterDamageComponent;
   [HideInInspector]
   public CharacterDamage CharacterDamageComponent;
   [HideInInspector]
   public NPCSpawner NPCSpawnerComponent;
   [HideInInspector]
   public NPCRegistry NPCRegistryComponent;
   [HideInInspector]
   public AI TargetAIComponent;
   [HideInInspector]
   public NavMeshAgent agent;
   [HideInInspector]
   public Collider[] colliders;
   private bool collisionState;
   [HideInInspector]
   public Animation AnimationComponent;
   [HideInInspector]
   public Animator AnimatorComponent;
   private float animSpeed;
   [HideInInspector]
   public bool recycleNpcObjOnDeath;
   [Tooltip("The object with the Animation/Animator component which will be accessed by AI.cs to play NPC animations. If none, this root object will be checked for the Animator/Animations component.")]
   public Transform objectWithAnims;
   [Tooltip("Chance between 0 and 1 that NPC will spawn. Used to randomize NPC locations and surprise the player.")]
   [Range(0.0f, 1.0f)]
   public float randomSpawnChance = 1.0f;
   
   //NPC movement speeds
   [Tooltip("Running speed of the NPC.")]
   public float runSpeed = 6.0f;
   [Tooltip("Walking speed of the NPC.")]
   public float walkSpeed = 1.0f;
   [Tooltip("Speed of running animation.")]
   public float walkAnimSpeed = 1.0f;
   [Tooltip("Speed of walking animation.")]
   public float runAnimSpeed = 1.0f;
   private float speedAmt = 1.0f;
   private float lastRunTime;//to prevent rapid walking, then running when following player
   
   [Tooltip("NPC yaw angle offset when standing.")]
   public float idleYaw = 0.0f;
   [Tooltip("NPC yaw angle offset when moving.")]
   public float movingYaw = 0.0f;
   private float yawAmt;

   [Tooltip("Sets the alignment of this NPC. 1 = friendly to player and hostile to factions 2 and 3, 2 = hostile to player and factions 1 and 3, 3 = hostile to player and factions 1 and 2.")]
   public int factionNum = 1;//1 = human(friendly to player), 2 = alien(hostile to player), 3 = zombie(hostile to all other factions)
   [Tooltip("If false, NPC will attack any character that attacks it, regardless of faction.")]
   public bool ignoreFriendlyFire;
   [HideInInspector]
   public bool playerAttacked;//to make friendly NPCs go hostile if attacked by player
   [HideInInspector]
   public float attackedTime;

   //waypoints and patrolling
   [HideInInspector]
   public Transform myTransform;
   private Vector3 upVec;//cache this for optimization;
   [Tooltip("True if NPC will hunt player accross map without needing to detect player first.")]
   public bool huntPlayer;
   [Tooltip("True if NPC should only follow patrol waypoints once.")]
   public bool patrolOnce;
   [Tooltip("True if NPC should walk on patrol, will run on patrol if false.")]
   public bool walkOnPatrol = true;
   private  Transform curWayPoint;
   [Tooltip("Drag the parent waypoint object with the WaypointGroup.cs script attached here. If none, NPC will stand watch instead of patrolling.")]
   public WaypointGroup waypointGroup;
   [Tooltip("The number of the waypoint in the waypoint group which should be followed first.")]
   public int firstWaypoint = 1;
   [Tooltip("True if NPC should stand in one place and not patrol waypoint path.")]
   public bool standWatch;
   [Tooltip("True if NPC is following player.")]
   public bool followPlayer;
   [Tooltip("True if NPC can be activated with the use button and start following the player.")]
   public bool followOnUse;
   [Tooltip("True if this NPC wants player to follow them (wont take move orders from player, only from MoveTrigger.cs).")]
   public bool leadPlayer;
   [HideInInspector]
   public bool orderedMove;
   [HideInInspector]
   public bool playerFollow;//true if this NPC wants player to follow them (wont take move orders from player, only from MoveTrigger.cs)
   private bool animInit;//to bypass normal AI update interval for correct animation initialization
   private bool animInitialized;//to only initialize animations once
   private float commandedTime;
   private float talkedTime;
   private bool  countBackwards = false;
   [Tooltip("Minimum distance to destination waypoint that NPC will consider their destination as reached.")]
   public float pickNextDestDist = 2.5f;
   private Vector3 startPosition;
   private float spawnTime;

   [Tooltip("Volume of NPC's vocal sound effects.")]
   public float vocalVol = 0.7f;
   [Tooltip("Sound to play when player commands NPC to stop following.")]
   public AudioClip stayFx1;
   [Tooltip("Sound to play when player commands NPC to stop following.")]
   public AudioClip stayFx2;
   [Tooltip("Sound to play when player commands NPC to start following.")]
   public AudioClip followFx1;
   [Tooltip("Sound to play when player commands NPC to start following.")]
   public AudioClip followFx2;
   [Tooltip("Sound to play when player commands NPC to move to position.")]
   public AudioClip moveToFx1;
   [Tooltip("Sound to play when player commands NPC to move to position.")]
   public AudioClip moveToFx2;
   [Tooltip("Sound to play when NPC has been activated more than joke activate times.")]
   public AudioClip jokeFx;
   [Tooltip("Sound to play when NPC has been activated more than joke activate times.")]
   public AudioClip jokeFx2;
   [Tooltip("Number of consecutive use button presses that activates joke fx.")]
   public int jokeActivate = 33;
   private float jokePlaying = 0.0f;
   private int jokeCount;
   
   [Tooltip("Sound effects to play when pursuing player.")]
   public AudioClip[] tauntSnds;
   [Tooltip("True if taunt sound shouldn't be played when attacking.")]
   public bool cancelAttackTaunt;
   private float lastTauntTime;
   [Tooltip("Delay between times to check if taunt sound should be played.")]
   public float tauntDelay = 2f;
   [Tooltip("Chance that a taunt sound will play after taunt delay.")]
   [Range(0.0f, 1.0f)]
   public float tauntChance = 0.5f;
   [Tooltip("Volume of taunt sound effects.")]
   public float tauntVol = 0.7f;
   [Tooltip("Sound effects to play when NPC discovers player.")]
   public AudioClip[] alertSnds;
   [Tooltip("Volume of alert sound effects.")]
   public float alertVol = 0.7f;
   private bool alertTaunt;
   
   
   [HideInInspector]
   public AudioSource vocalFx;
   private AudioSource footstepsFx;
   [Tooltip("Sound effects to play for NPC footsteps.")]
   public AudioClip[] footSteps;
   [Tooltip("Volume of footstep sound effects.")]
   public float footStepVol = 0.5f;
   [Tooltip("Time between footstep sound effects when walking (sync with anim).")]
   public float walkStepTime = 1.0f;
   [Tooltip("Time between footstep sound effects when running (sync with anim).")]
   public float runStepTime = 1.0f;
   private float stepInterval;
   private float stepTime;

   //targeting and attacking
   [Tooltip("Minimum range to target to start attack.")]
   public float shootRange = 15.0f;
   [Tooltip("Range that NPC will start chasing target until they are within shoot range.")]
   public float attackRange = 30.0f;
   [Tooltip("Range that NPC will hear player attacks.")]
   public float listenRange = 30.0f;
   [Tooltip("Time between shots (longer for burst weapons).")]
   public float shotDuration = 0.0f;
   [Tooltip("Speed of attack animation.")]
   public float shootAnimSpeed = 1.0f;
   [HideInInspector]
   public float attackRangeAmt = 30.0f;//increased by character damage script if NPC is damaged by player
   [Tooltip("Percentage to reduce enemy search range if player is crouching.")]
   public float sneakRangeMod = 0.4f;
   private float shootAngle = 3.0f;
   [Tooltip("Time before atack starts, to allow weapon to be raised before firing.")]
   public float delayShootTime = 0.35f;
   [Tooltip("Random delay between NPC attacks.")]
   public float randShotDelay = 0.75f;
   [Tooltip("Height of rayCast origin which detects targets (can be raised if NPC origin is at their feet).")]
   public float eyeHeight = 0.4f;
   [Tooltip("Draws spheres in editor for position and eye height.")]
   public bool drawDebugGizmos;
   [HideInInspector]
   public Transform target = null;
   [HideInInspector]
   public bool targetVisible;
   private float lastVisibleTime;
   private Vector3 targetPos;
   [HideInInspector]
   public float targetRadius;
   [HideInInspector]
   public float attackTime = -16.0f;//time last attacked
   private bool attackFinished = true;
   private bool turning;//true if turning to face target
   [HideInInspector]
   public bool cancelRotate;
   [HideInInspector]
   public bool followed;//true when npc is moving to destination defined by MoveTrigger.cs

   private float targetDistance;
   private Vector3 targetDirection;
   private RaycastHit[] hits;
   private bool sightBlocked;//true if sight to target is blocked
   [HideInInspector]
   public bool playerIsBehind;//true if player is behind NPC
   [HideInInspector]
   public float targetEyeHeight;
   private bool pursueTarget;
   [HideInInspector]
   public Vector3 lastVisibleTargetPosition;
   [HideInInspector]
   public float timeout = 0.0f;//to allow NPC to resume initial behavior after searching for target
   [HideInInspector]
   public bool heardPlayer = false;
   [HideInInspector]
   public bool heardTarget = false;
   [HideInInspector]
   public bool damaged;//true if attacked
   private bool damagedState;
   [HideInInspector]
   public float lastDamageTime;

   [HideInInspector]
   public LayerMask searchMask = 0;//only layers to include in target search (for efficiency)
   
   [HideInInspector]
   public RaycastHit attackHit;

   void Start(){
   
      NPCMgrObj = GameObject.Find("NPC Manager");
      NPCRegistryComponent = NPCMgrObj.GetComponent<NPCRegistry>();
      NPCRegistryComponent.Npcs.Add(myTransform.gameObject.GetComponent<AI>());//register this active NPC with the NPCRegistry
      playerObj = Camera.main.transform.GetComponent<CameraControl>().playerObj;
      
      Mathf.Clamp01(randomSpawnChance);

      agent = GetComponent<NavMeshAgent>();

      if(Random.value > randomSpawnChance){
         Destroy(myTransform.gameObject);
      }
   }
   
   void OnEnable(){
      
      myTransform = transform;
      upVec = Vector3.up;;
      startPosition = myTransform.position;
      timeout = 0.0f;
      attackedTime = -16f;//set to negative value to prevent NPCs from having larger search radius briefly after spawning
      if(jokeFx){
         jokePlaying = jokeFx.length * -2f;
      }
      
      collisionState = false;

      //initialize audiosource for footsteps
      footstepsFx = myTransform.gameObject.AddComponent<AudioSource>();
      footstepsFx.spatialBlend = 1.0f;
      footstepsFx.volume = footStepVol;
      footstepsFx.pitch = 1.0f;
      footstepsFx.dopplerLevel = 0.0f;
      footstepsFx.bypassEffects = true;
      footstepsFx.bypassListenerEffects = true;
      footstepsFx.bypassReverbZones = true;
      footstepsFx.maxDistance = 10.0f;
      footstepsFx.rolloffMode = AudioRolloffMode.Linear;
      footstepsFx.playOnAwake = false;
      
      vocalFx = myTransform.gameObject.AddComponent<AudioSource>();
      vocalFx.spatialBlend = 1.0f;
      vocalFx.volume = vocalVol;
      vocalFx.pitch = 1.0f;
      vocalFx.dopplerLevel = 0.0f;
      vocalFx.bypassEffects = true;
      vocalFx.bypassListenerEffects = true;
      vocalFx.bypassReverbZones = true;
      vocalFx.maxDistance = 10.0f;
      vocalFx.rolloffMode = AudioRolloffMode.Linear;
      vocalFx.playOnAwake = false;

      //set layermask to layers such as layer 10 (world collision) and 19 (interactive objects) for target detection
      searchMask = ~(~(1 << 10) & ~(1 << 0) & ~(1 << 13) & ~(1 << 11) & ~(1 << 20));
      
      //if there is no objectWithAnims defined, use the Animation Component attached to this game object
      if(objectWithAnims == null){objectWithAnims = transform;}

      AnimatorComponent = objectWithAnims.GetComponent<Animator>();//set reference to Mecanim animator component
      
      //initialize AI vars
      playerObj = Camera.main.transform.GetComponent<CameraControl>().playerObj;
      playerTransform = playerObj.transform;
      PlayerWeaponsComponent = Camera.main.transform.GetComponent<CameraControl>().weaponObj.GetComponentInChildren<PlayerWeapons>();
      FPSWalker = playerObj.GetComponent<FPSRigidBodyWalker>();
      NPCAttackComponent = GetComponent<NPCAttack>();
      CharacterDamageComponent = GetComponent<CharacterDamage>();

      //Get all colliders for this NPC's body parts
      colliders = GetComponentsInChildren<Collider>();
      
      attackRangeAmt = attackRange;

      AnimatorComponent.SetInteger("AnimState", 0);

      if(!spawned){//if spawned, SpawnNPC function will be called from NPCSpawner.cs. Otherwise, spawn now.   
         StopAllCoroutines();   
         StartCoroutine(SpawnNPC());
      }
      
   }

   //initialize NPC behavior
   public IEnumerator SpawnNPC(){

      yield return new WaitForSeconds(0.1f);//wait for object to initialize

      //initialize navmesh agent
      agent = GetComponent<NavMeshAgent>();
      agent.enabled = false;//Navmesh agent should also be deactivated on prefab to prevent error when spawning
       agent.enabled = true;
      agent.speed = runSpeed;
      agent.acceleration = 60.0f;

      if(!agent.isOnNavMesh){
         yield return null;//wait for navmesh agent to find navmesh and initialize
      }

      if(agent.isOnNavMesh){
         spawnTime = Time.time;
         StartCoroutine(PlayFootSteps());
         if(objectWithAnims != myTransform){
            StartCoroutine(UpdateModelYaw());
         }
         if(!huntPlayer){
            //determine if NPC should patrol or stand watch
            if(!standWatch && waypointGroup && waypointGroup.wayPoints[firstWaypoint - 1]){
               curWayPoint = waypointGroup.wayPoints[firstWaypoint - 1];
               speedAmt = runSpeed;
               startPosition = curWayPoint.position;
               TravelToPoint(curWayPoint.position);
               StartCoroutine(Patrol());
            }else{
               TravelToPoint(startPosition);
               StartCoroutine(StandWatch());
            }
         }else{
            //hunt the player accross the map
            factionNum = 2;
            target = playerTransform;
            targetEyeHeight = FPSWalker.capsule.height * 0.25f;
            lastVisibleTargetPosition = target.position + (target.up * targetEyeHeight);
            attackRange = 2048.0f;
            StartCoroutine(AttackTarget());

            speedAmt = runSpeed;
            TravelToPoint(playerObj.transform.position);
         }
      }else{
         Debug.Log("<color=red>NPC can't find Navmesh:</color> Please bake Navmesh for this scene or reposition NPC closer to navmesh.");
      }
   }

   //draw debug spheres in editor
   void OnDrawGizmos() {
      if(drawDebugGizmos){
         Gizmos.color = Color.yellow;
         Gizmos.DrawSphere(transform.position, 0.2f);
         Gizmos.color = Color.red;
         Gizmos.DrawSphere(transform.position + new Vector3(0.0f, eyeHeight, 0.0f), 0.2f);
      
         Vector3 myPos = transform.position + (transform.up * eyeHeight);
         Vector3 targetPos = lastVisibleTargetPosition;
         Vector3 testdir1 = (targetPos - myPos).normalized;
         float distance = Vector3.Distance(myPos, targetPos);
         Vector3 testpos3 = myPos + (testdir1 * distance);
         
         if (Physics.Linecast(myPos, targetPos)) {
            Gizmos.color = Color.red;
         }else{
            Gizmos.color = Color.green;
         }

         Gizmos.DrawLine (myPos, testpos3);
         Gizmos.DrawSphere(testpos3, 0.2f);

         
         if(target){
            Gizmos.color = Color.yellow;
            Gizmos.DrawLine (myPos, target.position + (transform.up * targetEyeHeight));
         }

         Gizmos.color = Color.green;
         Gizmos.DrawSphere(transform.position + (transform.forward * 0.6f) + (transform.up * eyeHeight), 0.2f);

//         Vector3 dirPerpGizmo = Vector3.Cross (transform.forward, Vector3.forward);
//         dirPerpGizmo.Normalize();
         Vector3 dirPerpGizmo = transform.forward;
         dirPerpGizmo = Quaternion.Euler(0, -90, 0) * dirPerpGizmo;
         agent = GetComponent<NavMeshAgent>();
         Gizmos.color = Color.blue;
         Gizmos.DrawSphere(transform.position + (transform.up * eyeHeight) + (dirPerpGizmo * agent.radius) , 0.2f);
         Gizmos.DrawSphere(transform.position + (transform.up * eyeHeight) - (dirPerpGizmo * agent.radius) , 0.2f);


      }
      
   }

   //For when an NPC starts moving from a stationary/idle stance.
   //This function bypasses normal AI Logic interval of 300ms (for efficiency) and runs the next AI logic pass immediately in the next frame.
   //Doing this prevents NPCs from sliding on the ground when first encountering target or player (prevents delay in movement anim init).
   private void InitializeAnim(){
      if(!animInit && !animInitialized){
         animInit = true;
         animInitialized = true;//to only initialize anims once
      }else{
         animInit = false;
      }
   }
   
   IEnumerator StandWatch(){
      while (true) {

         if(huntPlayer){
            StartCoroutine(SpawnNPC());
            yield break;
         }
         
         //expand search radius if attacked
         if(attackedTime + 6.0f > Time.time){
            attackRangeAmt = attackRange * 6.0f;//expand enemy search radius if attacked to defend against sniping
         }else{
            attackRangeAmt = attackRange;
         }

         //allow player to push friendly NPCs out of their way
         if(playerObj.activeInHierarchy && !collisionState && FPSWalker.capsule){
            foreach(Collider col in colliders){
               Physics.IgnoreCollision(col, FPSWalker.capsule, true);
            }
            collisionState = true;
         }

         CanSeeTarget();
         if ((target && targetVisible) || heardPlayer || heardTarget){
            yield return StartCoroutine(AttackTarget());
         }else{
            if(NPCRegistryComponent){
               NPCRegistryComponent.FindClosestTarget(myTransform.gameObject, this, myTransform.position, attackRangeAmt, factionNum);
            }
         }
         if(attackTime < Time.time){
            if((!followPlayer || orderedMove) && Vector3.Distance(startPosition, myTransform.position) > pickNextDestDist){
               if(!orderedMove){
                  speedAmt = walkSpeed;//walk to next patrol point, designated position, or starting point
               }else{
                  speedAmt = runSpeed;//run to position designated by player
               }
               InitializeAnim();
               TravelToPoint(startPosition);//
            }else if(followPlayer && !orderedMove && Vector3.Distance(playerObj.transform.position, myTransform.position) > pickNextDestDist){
               if(followPlayer && Vector3.Distance(playerObj.transform.position, myTransform.position) > pickNextDestDist * 2f){
                     speedAmt = runSpeed;//run to player if NPC is following and player is far away
                     lastRunTime = Time.time;
               }else{
                  if(lastRunTime + 2.0f < Time.time){
                     speedAmt = walkSpeed;//walk to player if within walking distance
                  }
               }
               InitializeAnim();
               TravelToPoint(playerObj.transform.position);
            }else{
               //play idle animation
               speedAmt = 0.0f;
               agent.isStopped = true;
               SetSpeed(speedAmt);

               if(attackFinished && attackTime < Time.time){
                  AnimatorComponent.SetInteger("AnimState", 0);
               }
               
            }
         }
         if(animInit){
            //only wait one frame till next pass so animations will be initialized now, instead of in 0.3 second normal AI calculation delay
            yield return null;
         }else{
            yield return new WaitForSeconds(0.3f);//wait 0.3 seconds (not every frame) untill next AI calculation (for efficiency)
         }
      }
      
   }
   
   IEnumerator Patrol(){
      while (true) {
      
         if(huntPlayer){
            StartCoroutine(SpawnNPC());
            yield break;
         }
         
         if(curWayPoint && waypointGroup){//patrol if NPC has a current waypoint, otherwise stand watch
            Vector3 waypointPosition = curWayPoint.position;
            float waypointDist = Vector3.Distance(waypointPosition, myTransform.position);
            int waypointNumber = waypointGroup.wayPoints.IndexOf(curWayPoint);

            //if NPC is close to a waypoint, pick the next one
            if((patrolOnce && waypointNumber == waypointGroup.wayPoints.Count - 1)){
               if(waypointDist < pickNextDestDist){
                  speedAmt = 0.0f;
                  startPosition = waypointPosition;
                  StartCoroutine(StandWatch());
                  yield break;//cancel patrol if patrolOnce var is true
               }
            }else{   
               if(waypointDist < pickNextDestDist){
                  if(waypointGroup.wayPoints.Count == 1){
                     speedAmt = 0.0f;
                     startPosition = waypointPosition;
                     StartCoroutine(StandWatch());
                     yield break;//cancel patrol if NPC has reached their only waypoint
                  }
                  curWayPoint = PickNextWaypoint (curWayPoint, waypointNumber);
                  if(spawned && Vector3.Distance(waypointPosition, myTransform.position) < pickNextDestDist){
                     walkOnPatrol = true;//make spawned NPCs run to their first waypoint, but walk on the patrol
                  }
               }
            }

            //expand search radius if attacked
            if(attackedTime + 6.0f > Time.time){
               attackRangeAmt = attackRange * 6.0f;//expand enemy search radius if attacked to defend against sniping
            }else{
               attackRangeAmt = attackRange;
            }
            
            //allow player to push friendly NPCs out of their way
            if(playerObj.activeInHierarchy && !collisionState && FPSWalker.capsule){
               foreach(Collider col in colliders){
                  Physics.IgnoreCollision(col, FPSWalker.capsule, true);
               }
               collisionState = true;
            }

            //determine if player is within sight of NPC
            CanSeeTarget();
            if((target && targetVisible) || heardPlayer || heardTarget){
               yield return StartCoroutine(AttackTarget());
            }else{
               if(NPCRegistryComponent){
                  NPCRegistryComponent.FindClosestTarget(myTransform.gameObject, this, myTransform.position, attackRangeAmt, factionNum);
               }
               // Move towards our target
               if(attackTime < Time.time){
                  if(orderedMove && !followPlayer){
                     if(Vector3.Distance(startPosition, myTransform.position) > pickNextDestDist){
                        speedAmt = runSpeed;
                        TravelToPoint(startPosition);
                     }else{
                        //play idle animation
                        speedAmt = 0.0f;
                        agent.isStopped = true;
                        SetSpeed(speedAmt);

                        if(attackFinished && attackTime < Time.time){
                           AnimatorComponent.SetInteger("AnimState", 0);
                        }
                        
                        StartCoroutine(StandWatch());//npc reached player-designated position, stop patrolling and wait here
                        yield break;
                     }
                  }else if(!orderedMove && followPlayer){
                     if(Vector3.Distance(playerObj.transform.position, myTransform.position) > pickNextDestDist){
                        if(Vector3.Distance(playerObj.transform.position, myTransform.position) > pickNextDestDist * 2f){
                           speedAmt = runSpeed;
                           lastRunTime = Time.time;
                        }else{
                           if(lastRunTime + 2.0f < Time.time){
                              speedAmt = walkSpeed;
                           }
                        }
                        TravelToPoint(playerObj.transform.position);
                     }else{
                        //play idle animation
                        speedAmt = 0.0f;
                        agent.isStopped = true;
                        SetSpeed(speedAmt);

                        if(attackFinished && attackTime < Time.time){
                           AnimatorComponent.SetInteger("AnimState", 0);
                        }
                        
                     }
                  }else{
                     //determine if NPC should walk or run on patrol
                     if(walkOnPatrol){speedAmt = walkSpeed;}else{speedAmt = runSpeed;}
                     TravelToPoint(waypointPosition);
                  }
               }
            }
         }else{
            StartCoroutine(StandWatch());//don't patrol if we have no waypoints
            yield break;
         }
         yield return new WaitForSeconds(0.3f);
      }

   }


   void CanSeeTarget(){
   
      if(spawnTime + 1f > Time.time){//add small delay before checking target visibility
         return;
      }
      
      //stop tracking target if it is deactivated
      if((TargetAIComponent && !TargetAIComponent.enabled) || (target && !target.gameObject.activeInHierarchy)){
         target = null;
         TargetAIComponent = null;
         targetVisible = false;
         heardTarget = false;
         return;
      }

      //target player
      if((factionNum != 1 || playerAttacked) && FPSWalker.capsule){

         float playerDistance = Vector3.Distance(myTransform.position + (upVec * eyeHeight), playerTransform.position + (upVec * FPSWalker.capsule.height * 0.25f));

         //listen for player attacks
         if(!heardPlayer && !huntPlayer && FPSWalker.dropTime + 2.5f < Time.time){
            if(playerDistance < listenRange && (target == playerTransform || target == FPSWalker.leanObj.transform || target == null)){
               if(PlayerWeaponsComponent && PlayerWeaponsComponent.CurrentWeaponBehaviorComponent){
                  WeaponBehaviorComponent = PlayerWeaponsComponent.CurrentWeaponBehaviorComponent;
                  if(WeaponBehaviorComponent.shootStartTime + 2.0f > Time.time && !WeaponBehaviorComponent.silentShots){
                     if(target == FPSWalker.leanObj.transform){
                        targetEyeHeight = 0.0f;
                        target = FPSWalker.leanObj.transform;
                        pursueTarget = true;
                     }else{
                        targetEyeHeight = FPSWalker.capsule.height * 0.25f;
                        target = playerTransform;
                     }
                     timeout = Time.time + 6.0f;
                     heardPlayer = true;
                     return;
                  }
               }
            }
         }

         if(huntPlayer){
            targetEyeHeight = FPSWalker.capsule.height * 0.25f;
            target = playerTransform;
         }

         if(playerDistance < attackRangeAmt){

            //target lean collider if player is leaning around a corner
            if(Mathf.Abs(FPSWalker.leanAmt) > 0.1f
            && playerDistance > 2.0f && target == playerTransform
            && (attackedTime + 6.0f > Time.time || heardPlayer)){//allow player to peek around corners undetected if they haven't attacked this npc
               targetEyeHeight = 0.0f;
               target = FPSWalker.leanObj.transform;
            }
            //target main player object if they are not leaning
            if((Mathf.Abs(FPSWalker.leanAmt) < 0.1f || playerDistance < 2.0f) && target == FPSWalker.leanObj.transform){
               targetEyeHeight = FPSWalker.capsule.height * 0.25f;
               target = playerTransform;
            }

         }

      }

      //calculate range and LOS to target
      if(target == playerTransform || target == FPSWalker.leanObj.transform || (TargetAIComponent && TargetAIComponent.enabled && target != null)){
         Vector3 myPos = myTransform.position + (upVec * eyeHeight);
         targetPos = target.position + (target.up * targetEyeHeight);

         targetDistance = Vector3.Distance(myPos, targetPos);
         targetDirection = (targetPos - myPos).normalized;

         Vector3 targetDirPerp = Vector3.Cross (targetDirection, Vector3.forward);
         targetDirPerp.Normalize();

         if(targetDistance > attackRangeAmt){
            sightBlocked = true;
            targetVisible = false;
            return;//don't continue to check LOS if target is not within attack range
         }

         //check LOS with raycast
         hits = Physics.RaycastAll (myPos, targetDirection, targetDistance, searchMask);

         sightBlocked = false;

         //detect if target is behind NPC
         if(!huntPlayer
         && timeout < Time.time
         && attackedTime + 6.0f < Time.time
         && ((target == playerTransform || target == FPSWalker.leanCol) && !heardPlayer)
         && !FPSWalker.sprintActive){
            Vector3 toTarget = (targetPos - myPos).normalized;
            if(Vector3.Dot(toTarget, transform.forward) < -0.45f){
               sightBlocked = true;
               playerIsBehind = true;
               targetVisible = false;
               return;
            }
         }
         
         playerIsBehind = false;

         //check if NPC can see their target
         for(int i = 0; i < hits.Length; i++){
            if((!hits[i].transform.IsChildOf(target)//hit is not target
            && !hits[i].transform.IsChildOf(myTransform))//hit is not NPC's own colliders
             || (!playerAttacked//attack player if they attacked us (friendly fire)
                && (factionNum == 1 && target != playerObj && (hits[i].collider == FPSWalker.capsule//try not to shoot the player if we are a friendly NPC
                         || hits[i].collider == FPSWalker.leanCol)))
            ){
               sightBlocked = true;
               break;
            }
            if(hits[i].transform.IsChildOf(target)){
               attackHit = hits[i];
               break;
            }
         }
         
         if(!sightBlocked){
            if(target != FPSWalker.leanObj.transform){
               pursueTarget = false;
               targetVisible = true;
               return;
            }else{
               pursueTarget = true;//true when NPC has seen only the player leaning around a corner
               targetVisible = true;
               return;
            }
         }else{
            if(TargetAIComponent && !huntPlayer){
               if(TargetAIComponent.attackTime > Time.time && Vector3.Distance(myTransform.position, target.position) < listenRange ){
                  timeout = Time.time + 6.0f;
                  heardTarget = true;
               }
            }
            targetVisible = false;
            return;
         }
         
      }else{
         targetVisible = false;
         return;
      }
   
   }
   
   IEnumerator Shoot(){

      attackFinished = false;

      //don't move during attack
      speedAmt = 0.0f;
      SetSpeed(speedAmt);
      agent.isStopped = true;


      // Start shoot animation
      AnimatorComponent.SetInteger("AnimState", 3);
      AnimatorComponent.SetTrigger("Attack");


      // Wait until delayShootTime to allow part of the animation to play
      yield return new WaitForSeconds(delayShootTime);
      //attack
      NPCAttackComponent.Fire();
      if(cancelAttackTaunt){
         vocalFx.Stop();
      }
      attackTime = Time.time + 2.0f;
      // Wait for the rest of the animation to finish
      yield return new WaitForSeconds(delayShootTime + Random.Range(shotDuration, shotDuration + 0.75f));

      attackFinished = true;

      AnimatorComponent.SetInteger("AnimState", 0);
      

   }
   
   IEnumerator AttackTarget(){
      while (true) {
      
         if(Time.timeSinceLevelLoad < 1f){//add small delay before checking target visibility
            yield return new WaitForSeconds(1.0f);
         }
         
         // no target - stop hunting
         if(target == null || (TargetAIComponent && !TargetAIComponent.enabled) && !huntPlayer){
            timeout = 0.0f;
            heardPlayer = false;
            heardTarget = false;
            damaged = false;
            TargetAIComponent = null;
            yield break;
         }
         
         //play a taunt if hunting target
         if(lastTauntTime + tauntDelay < Time.time
         && Random.value < tauntChance
         && (alertTaunt || alertSnds.Length <= 0)){
            if(tauntSnds.Length > 0){
               vocalFx.volume = tauntVol;
               vocalFx.pitch = Random.Range(0.94f, 1f);
               vocalFx.spatialBlend = 1.0f;
               vocalFx.clip = tauntSnds[Random.Range(0, tauntSnds.Length)];
               vocalFx.PlayOneShot(vocalFx.clip);
               lastTauntTime = Time.time;
            }
         }
         
         //play alert sound if target detected
         if(!alertTaunt){
            if(alertSnds.Length > 0){
               vocalFx.volume = alertVol;
               vocalFx.pitch = Random.Range(0.94f, 1f);
               vocalFx.spatialBlend = 1.0f;
               vocalFx.clip = alertSnds[Random.Range(0, alertSnds.Length)];
               vocalFx.PlayOneShot(vocalFx.clip);
               lastTauntTime = Time.time;
               alertTaunt = true;
            }
         }
         
         float distance = Vector3.Distance(myTransform.position, target.position);
         
         if(!huntPlayer){
            
            //search for player if their attacks have been heard
            if(heardPlayer && (target == playerTransform || target == FPSWalker.leanObj.transform)){
               InitializeAnim();
               speedAmt = runSpeed;
               SearchTarget(lastVisibleTargetPosition);
            }
            //search for target if their attacks have been heard
            if(heardTarget){
               InitializeAnim();
               speedAmt = runSpeed;
               SearchTarget(lastVisibleTargetPosition);
            }
      
            // Target is too far away - give up   
            if(distance > attackRangeAmt){
               speedAmt = walkSpeed;
               target = null;
               yield break;
            }
            
         }else{
            InitializeAnim();
            target = playerTransform;
            speedAmt = runSpeed;
            TravelToPoint(target.position);
         }

         if(pursueTarget){//should NPC attack player collider or leaning collider?
            lastVisibleTargetPosition = FPSWalker.leanObj.transform.position;
         }else{
            lastVisibleTargetPosition = target.position + (target.up * targetEyeHeight);
         }

         CanSeeTarget();
         if(targetVisible){
            timeout = Time.time + 6.0f;
         
            if(distance > shootRange){
               if(!huntPlayer){
                  SearchTarget(lastVisibleTargetPosition);
               }
            }else{//close to target, rotate NPC to face it
               if(!turning){
                  StopCoroutine("RotateTowards");
                  StartCoroutine(RotateTowards(lastVisibleTargetPosition, 20.0f, 2.0f));
               }
               speedAmt = 0.0f;
               SetSpeed(speedAmt);
               agent.speed = speedAmt;
            }

            InitializeAnim();
            speedAmt = runSpeed;

            Vector3 forward = myTransform.TransformDirection(Vector3.forward);
            Vector3 targetDirection = lastVisibleTargetPosition - (myTransform.position + (myTransform.up * eyeHeight));
            targetDirection.y = 0;
            
            float angle = Vector3.Angle(targetDirection, forward);
            
            // Start shooting if close and player is in sight
            if(distance < shootRange && angle < shootAngle){
               if(attackFinished){
                  yield return StartCoroutine(Shoot());
               }else{
                  speedAmt = 0.0f;
                  SetSpeed(speedAmt);
                  agent.isStopped = true;
               }
            }
            
         }else{
            if(!huntPlayer){
               if(attackFinished || huntPlayer){
                  if(timeout > Time.time){
                     InitializeAnim();
                     speedAmt = runSpeed;
                     SetSpeed(speedAmt);
                     SearchTarget(lastVisibleTargetPosition);
                  }else{//if timeout has elapsed and target is not visible, resume initial behavior
                     heardPlayer = false;
                     heardTarget = false;
                     alertTaunt = false;
                     speedAmt = 0.0f;
                     SetSpeed(speedAmt);
                     agent.isStopped = true;
                     target = null;
                     yield break;
                  }
               }
            }
         }
         
         if(animInit){
            //only wait one frame till next pass so animations will be initialized now, instead of in 0.3 second normal AI calculation delay
            yield return null;
         }else{
            yield return new WaitForSeconds(0.3f);//wait 0.3 seconds (not every frame) untill next AI calculation (for efficiency)
         }

      }
   }

   //look for target at a location
   void SearchTarget( Vector3 position  ){
      if(attackFinished){
         if(target == playerTransform || target == FPSWalker.leanObj.transform || (TargetAIComponent && TargetAIComponent.enabled)){
            if(!huntPlayer){
               speedAmt = runSpeed;
               TravelToPoint(target.position);
            }
         }else{
            timeout = 0.0f;
            damaged = false;
         }
      }
   }

   //rotate to face target
   public IEnumerator RotateTowards( Vector3 position, float rotationSpeed, float turnTimer, bool attacking = true ){
      float turnTime;
      turnTime = Time.time;

      SetSpeed(0.0f);
      agent.isStopped = true;

      while(turnTime + turnTimer > Time.time && !cancelRotate){
         turning = true;

         if(pursueTarget){
            position = FPSWalker.leanObj.transform.position;
         }else{
            if((target && attacking && (target == playerTransform || (TargetAIComponent && TargetAIComponent.enabled)))){
               lastVisibleTargetPosition = target.position + (target.up * targetEyeHeight);
            }else{
               lastVisibleTargetPosition = position;
            }
         }
         
         Vector3 direction = lastVisibleTargetPosition - myTransform.position;
         direction.y = 0;
         if(direction.x != 0 && direction.z != 0){
            // Rotate towards the target
            myTransform.rotation = Quaternion.Slerp (myTransform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
            myTransform.eulerAngles = new Vector3(0, myTransform.eulerAngles.y, 0);
            yield return null;
         }else{
            break;//stop rotating
         }
      }
      cancelRotate = false;
      turning = false;
   }
   
   //Allow tweaking of model yaw/facing direction from the inspector for NPC alignment with attack direction
   private IEnumerator UpdateModelYaw(){
      while(true){
         
         if(stepInterval > 0.0f){
            yawAmt = Mathf.MoveTowards(yawAmt, movingYaw, Time.deltaTime * 180.0f);
         }else{
            yawAmt = Mathf.MoveTowards(yawAmt, idleYaw, Time.deltaTime * 180.0f);
         }

         objectWithAnims.transform.localRotation = Quaternion.Euler(0.0f, yawAmt, 0.0f);

         yield return null;
      }
   }

   //set navmesh destination and set NPC speed
   void TravelToPoint( Vector3 position  ){
      if(attackFinished){
         agent.SetDestination(position);
         agent.isStopped = false;
         agent.speed = speedAmt;
         SetSpeed(speedAmt);
         
      }
   }
   
   //pick the next waypoint and determine if patrol should continue forward or backward through waypoint group
   Transform PickNextWaypoint( Transform currentWaypoint, int curWaypointNumber  ){
      
      Transform waypoint = currentWaypoint;

      if(!countBackwards){
         if(curWaypointNumber < waypointGroup.wayPoints.Count -1){
            waypoint = waypointGroup.wayPoints[curWaypointNumber + 1];
         }else{
            waypoint = waypointGroup.wayPoints[curWaypointNumber - 1];
            countBackwards = true;
         }
      }else{
         if(curWaypointNumber != 0){
            waypoint = waypointGroup.wayPoints[curWaypointNumber - 1];
         }else{
            waypoint = waypointGroup.wayPoints[curWaypointNumber + 1];
            countBackwards = false;
         }
      }
      return waypoint;
   }

   //play animations for NPC moving state/speed and set footstep sound intervals
   void SetSpeed( float speed  ){
      if (speed > walkSpeed && agent.hasPath){
         AnimatorComponent.SetInteger("AnimState", 2);
         stepInterval = runStepTime;
      }else{
         if(speed > 0.0f && agent.hasPath){
            AnimatorComponent.SetInteger("AnimState", 1);
            stepInterval = walkStepTime;
         }else{
            if(attackFinished && attackTime < Time.time){
               AnimatorComponent.SetInteger("AnimState", 0);
            }
            stepInterval = -1.0f;
         }
      }
   }

   IEnumerator PlayFootSteps(){
      while(true){
         if(footSteps.Length > 0 && stepInterval > 0.0f ){
            footstepsFx.pitch = 1.0f;
            footstepsFx.volume = footStepVol;
            footstepsFx.clip = footSteps[Random.Range(0, footSteps.Length)];
            footstepsFx.PlayOneShot(footstepsFx.clip);
         }
         yield return new WaitForSeconds(stepInterval);
      }
   }
   
   //Interact with NPC when pressing use key over them
   public void CommandNPC () {
      if(factionNum == 1 && followOnUse && commandedTime + 0.5f < Time.time){
         orderedMove = false;
         cancelRotate = false;
         commandedTime = Time.time;
         if(attackFinished && !turning){
            StopCoroutine("RotateTowards");
            StartCoroutine(RotateTowards(playerTransform.position, 10.0f, 2.0f, false));
         }
         if(!followPlayer){
            if((followFx1 || followFx2) && ((jokeFx && jokePlaying + jokeFx.length < Time.time) || !jokeFx)){
               if(Random.value > 0.5f){
                  vocalFx.clip = followFx1;
               }else{
                  vocalFx.clip = followFx2;
               }
               vocalFx.pitch = Random.Range(0.94f, 1f);
               vocalFx.spatialBlend = 1.0f;
               vocalFx.PlayOneShot(vocalFx.clip);
            }
            followPlayer = true;
         }else{
            if((stayFx1 || stayFx2) && ((jokeFx && jokePlaying + jokeFx.length < Time.time) || !jokeFx)){
               if(Random.value > 0.5f){
                  vocalFx.clip = stayFx1;
               }else{
                  vocalFx.clip = stayFx2;
               }
               vocalFx.pitch = Random.Range(0.94f, 1f);
               vocalFx.spatialBlend = 1.0f;
               vocalFx.PlayOneShot(vocalFx.clip);
            }
            startPosition = myTransform.position;
            followPlayer = false;
         }
      }
      if(jokeFx && factionNum == 1 && followOnUse){
         if(jokeCount == 0){
            talkedTime = Time.time;
         }
         if(talkedTime + 0.5f > Time.time){
            talkedTime = Time.time;
            jokeCount++;
            if(jokeCount > jokeActivate){
               if(!jokeFx2){
                  vocalFx.clip = jokeFx;
               }else{
                  if(Random.value > 0.5f){
                     vocalFx.clip = jokeFx;
                  }else{
                     vocalFx.clip = jokeFx2;
                  }
               }
               vocalFx.pitch = Random.Range(0.94f, 1f);
               vocalFx.spatialBlend = 1.0f;
               vocalFx.PlayOneShot(vocalFx.clip);
               jokePlaying = Time.time;
               jokeCount = 0;
            }
         }else{
            jokeCount = 0;
         }
      }
   }
   
   //Move an NPC to a specific position
   public void GoToPosition (Vector3 position, bool runToPos) {
      if(runToPos){
         orderedMove = true;
      }else{
         orderedMove = false;
      }
      cancelRotate = true;
      startPosition = position;
   }

//   //used to change the faction of the NPC
   public void ChangeFaction(int factionChange){
      target = null;
      factionNum = factionChange;
   }

}

Vou mandar os outros scripts pera aí
Daniel Dória
Daniel Dória
Avançado
Avançado

Masculino PONTOS : 1898
REPUTAÇÃO : 31
Idade : 20
Respeito as regras : Configurar NPCs WvDYdlf

https://planecaos.jimdofree.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Daniel Dória Seg Jul 30, 2018 4:36 pm

AdrianJps escreveu:Deixa a gente ver o Script do Npc
CHARACTER DAMAGE:

Código:

http://CharacterDamage.cs by Azuline Studios©️ All Rights Reserved
//Applies damage to NPCs
using UnityEngine;
using System.Collections;

public class CharacterDamage : MonoBehaviour {
   public UnityEngine.Events.UnityEvent onDie; // for save addon by PixelCrushers
   private AI AIComponent;
   private RemoveBody RemoveBodyComponent;
   [Tooltip("Number of hitpoints for this character or body part.")]
   public float hitPoints = 100.0f;
   private float initialHitPoints;
   [Tooltip("Force to apply to this collider when NPC is killed.")]
   public float attackForce = 2.75f;
   [Tooltip("Item to spawn when NPC is killed.")]
   public GameObject gunItem;
   [Tooltip("Weapon mesh to hide when NPC dies (replaced with usable gun item).")]
   public Transform gunObj;
   private GameObject gunInst;
   [Tooltip("Rotation of spawed gun object after NPC death.")]
   public Vector3 gunItemRotation = new Vector3(0.0f, 180.0f, 180.0f);
   
   private Rigidbody[] bodies;
   [Tooltip("True if ragdoll mode is active for this NPC.")]
   public bool ragdollActive;
   private bool ragdollState;
   
   [Tooltip("If NPC only has one capsule collider for hit detection, replace the NPC's character mesh with a ragdoll, instead of transitioning instantly to ragdoll.")]
   public Transform deadReplacement;
   private Transform dead;
   [Tooltip("Sound effect to play when NPC dies.")]
   public AudioClip dieSound;
   [Tooltip("Determine if this object or parent should be removed on death. This is to allow for different hit detection collider types as children of NPC parent.")]
   public bool notParent;
   [Tooltip("Should this NPC's body be removed after Body Stay Time?")]
   public bool  removeBody;
   [Tooltip("Time for body to stay in the scene before it is removed.")]
   public float bodyStayTime = 15.0f;
   [Tooltip("Time for dropped weapon item to stay in scene before it is removed.")]
   public float gunStayTime = -1f;
   
   [Tooltip("Chance between 0 and 1 that death of this NPC will trigger slow motion for a few seconds (regardless of the body part hit).")]
   [Range(0.0f, 1.0f)]
   public float sloMoDeathChance = 0.0f;
   [Tooltip("True if backstabbing this NPC should trigger slow motion for the duration of slo mo backstab time.")]
   public bool sloMoBackstab = true;
   [Tooltip("Duration of slow motion time in seconds if slo mo death chance check is successful.")]
   public float sloMoDeathTime = 0.9f;
   [Tooltip("Duration of slow motion time in seconds if this NPC is backstabbed.")]
   public float sloMoBackstabTime = 0.9f;
   
   //vars related to attacker position (for physics, and other effects)
   private Vector3 attackerPos2;
   private Vector3 attackDir2;
   private Transform myTransform;
   private bool explosionCheck;
   private LayerMask raymask = 1 << 13;

   void OnEnable (){
      myTransform = transform;
      RemoveBodyComponent = GetComponent<RemoveBody>();
      Mathf.Clamp01(sloMoDeathChance);
      if(removeBody && RemoveBodyComponent){//remove body timer starts if RwmoveBody.cs script is enabled
         RemoveBodyComponent.enabled = false;
      }
      if(!AIComponent){
         AIComponent = myTransform.GetComponent<AI>();
      }
      initialHitPoints = hitPoints;
      bodies = GetComponentsInChildren<Rigidbody>();
   }
   
   void Update () {
      if(bodies.Length > 1){
         if(!ragdollActive){//deactivate ragdoll mode
            if(!ragdollState){
               foreach(Rigidbody rb in bodies){
                  rb.isKinematic = true;
               }

               AIComponent.AnimatorComponent.enabled = true;
               
               if(gunObj){
                  gunObj.gameObject.SetActive(true);
                  if(gunInst){
                     Destroy(gunInst);
                  }
               }
               ragdollState = true;
            }
         }else{//activate ragdoll mode
            if(ragdollState){

               AIComponent.AnimatorComponent.enabled = false;
               
               foreach(Collider col in AIComponent.colliders){
//                  foreach(Collider col2 in AIComponent.colliders){
//                     Physics.IgnoreCollision(col, col2, false);//ignore collisions with other body part colliders (is this even needed???)
//                  }
                  if(AIComponent.FPSWalker.gameObject.activeInHierarchy){
                     Physics.IgnoreCollision(col, AIComponent.FPSWalker.capsule, true);//ignore collisions with player
                  }
               }
               foreach(Rigidbody rb in bodies){
                  rb.isKinematic = false;
               }
               if(gunObj){//spawn gun pickup object
                  gunObj.gameObject.SetActive(false);
                  gunInst = Instantiate(gunItem, gunObj.position, gunObj.rotation) as GameObject;
                  foreach(Collider col in AIComponent.colliders){
                     Physics.IgnoreCollision(col, gunInst.GetComponent<Collider>(), true);//ignore collisions with other body part colliders
                  }
                  gunInst.transform.Rotate(gunItemRotation);
                  Vector3 tempGunpos = gunInst.transform.position + (transform.forward * 0.45f);
                  gunInst.transform.position = tempGunpos;
                  if(gunStayTime > 0.0f && gunInst.GetComponent<WeaponPickup>()){
                     gunInst.GetComponent<WeaponPickup>().StartCoroutine(gunInst.GetComponent<WeaponPickup>().DestroyWeapon(gunStayTime));
                  }
               }
               ragdollState = false;
            }
         }
      }
   }
   
   //damage NPC
   public void ApplyDamage ( float damage, Vector3 attackDir, Vector3 attackerPos, Transform attacker, bool isPlayer, bool isExplosion, Rigidbody hitBody = null, float bodyForce = 0.0f ){

      if (hitPoints <= 0.0f){
         return;
      }

      if(!AIComponent.damaged
      && !AIComponent.huntPlayer
      && (((hitPoints / initialHitPoints) < 0.65f))//has NPC been damaged significantly?
      && attacker
      && !isExplosion
      ){
         if(!isPlayer){
            if(attacker.GetComponent<AI>().factionNum != AIComponent.factionNum){
               AIComponent.target = attacker;
               AIComponent.TargetAIComponent = attacker.GetComponent<AI>();
               AIComponent.targetEyeHeight = AIComponent.TargetAIComponent.eyeHeight;
               AIComponent.damaged = true;
            }
         }else{
            if(!AIComponent.ignoreFriendlyFire){//go hostile on a friendly if they repeatedly attacked us
               AIComponent.target = AIComponent.playerObj.transform;
               AIComponent.targetEyeHeight = AIComponent.FPSWalker.capsule.height * 0.25f;
               AIComponent.playerAttacked = true;
               AIComponent.TargetAIComponent = null;
               AIComponent.damaged = true;
            }
         }
         
      }
      
      //prevent hitpoints from going into negative values
      if(hitPoints - damage > 0.0f){
         if(AIComponent.playerIsBehind && (AIComponent.PlayerWeaponsComponent.CurrentWeaponBehaviorComponent.meleeSwingDelay > 0 || AIComponent.PlayerWeaponsComponent.CurrentWeaponBehaviorComponent.meleeActive)){
            hitPoints -= damage * 32.0f;//backstab npc
            if(sloMoBackstab){
               AIComponent.PlayerWeaponsComponent.FPSPlayerComponent.StartCoroutine(AIComponent.PlayerWeaponsComponent.FPSPlayerComponent.ActivateBulletTime(sloMoBackstabTime));
            }
         }else{
            hitPoints -= damage;
         }
      }else{
         hitPoints = 0.0f;   
      }
      
      attackDir2 = attackDir;
      attackerPos2 = attackerPos;
      explosionCheck = isExplosion;
      
      //to expand enemy search radius if attacked to defend against sniping
      AIComponent.attackedTime = Time.time;
      
      //Kill NPC
      if (hitPoints <= 0.0f){
         onDie.Invoke(); // for save addon by PixelCrushers
         AIComponent.vocalFx.Stop();
            
         if(sloMoDeathChance >= Random.value && isPlayer){
            AIComponent.PlayerWeaponsComponent.FPSPlayerComponent.StartCoroutine(AIComponent.PlayerWeaponsComponent.FPSPlayerComponent.ActivateBulletTime(sloMoDeathTime));
         }
         if(bodies.Length < 2){//if NPC is only using one capsule collider for collision, instantiate ragdoll, instead of activating existing body part rigidbodies
            Die();
         }else{
            if(!ragdollActive){
               RagDollDie(hitBody, bodyForce);
            }
         }
      }
   }
   
   //this method called if NPC has died and has more than one capsule collider for collision, so transition to ragdoll
   void RagDollDie(Rigidbody hitBody, float bodyForce) {
      if (dieSound){
         PlayAudioAtPos.PlayClipAt(dieSound, transform.position, 1.0f);
      }
      
      AIComponent.NPCRegistryComponent.UnregisterNPC(AIComponent);//unregister NPC from main NPC registry
      if(AIComponent.spawned && AIComponent.NPCSpawnerComponent){
         AIComponent.NPCSpawnerComponent.UnregisterSpawnedNPC(AIComponent);//unregister NPC from spawner registry
      }

      AIComponent.AnimatorComponent.enabled = false;
      
      ragdollActive = true;
      if(AIComponent.NPCAttackComponent.muzzleFlash){
         AIComponent.NPCAttackComponent.muzzleFlash.enabled = false;
      }
      AIComponent.NPCAttackComponent.enabled = false;
      AIComponent.StopAllCoroutines();
      AIComponent.agent.enabled = false;
      AIComponent.enabled = false;
      StartCoroutine(ApplyForce(hitBody, bodyForce));
      //initialize the RemoveBody.cs script attached to the NPC ragdoll
      if(RemoveBodyComponent){
         if(removeBody){
            RemoveBodyComponent.enabled = true;
            RemoveBodyComponent.bodyStayTime = bodyStayTime;//pass bodyStayTime to RemoveBody.cs script
         }else{
            RemoveBodyComponent.enabled = false;
         }
      }
   }
   
   public IEnumerator ApplyForce (Rigidbody body, float force) {
      yield return new WaitForSeconds(0.02f);
      if(!explosionCheck){
         //apply damage force to the ragdoll rigidbody
         body.AddForce(attackDir2 * attackForce, ForceMode.Impulse);
      }else{
         //apply explosive damage force to the ragdoll rigidbodies
         foreach(Rigidbody rb in bodies) {
            rb.AddForce((myTransform.position - (attackerPos2 + (Vector3.up * -2.5f))).normalized * Random.Range(2.5f, 4.5f), ForceMode.Impulse);
         }
      }
   }
   
   //this method called if the NPC dies and only has one capsule collider for collision
   //which will be instantiated in place of the main NPC object (which is removed from the scene)
   void Die() {
      
      RaycastHit rayHit;
      // Play a dying audio clip
      if (dieSound){
         PlayAudioAtPos.PlayClipAt(dieSound, transform.position, 1.0f);
      }

      AIComponent.NPCRegistryComponent.UnregisterNPC(AIComponent);//unregister NPC from main NPC registry
      if(AIComponent.spawned && AIComponent.NPCSpawnerComponent){
         AIComponent.NPCSpawnerComponent.UnregisterSpawnedNPC(AIComponent);//unregister NPC from spawner registry
      }

      AIComponent.agent.isStopped = true;
      AIComponent.StopAllCoroutines();
   
      // Replace NPC object with the dead body
      if (deadReplacement) {
         
         //drop arrows if corpse disappears
         ArrowObject[] arrows = gameObject.GetComponentsInChildren<ArrowObject>(true);
         foreach (ArrowObject arr in arrows) {
            arr.transform.parent = null;
            arr.myRigidbody.isKinematic = false;
            arr.myBoxCol.isTrigger = false;
            arr.gameObject.tag = "Usable";
            arr.falling = true;
         }
      
         dead = Instantiate(deadReplacement, transform.position, transform.rotation) as Transform;
         RemoveBodyComponent = dead.GetComponent<RemoveBody>();
   
         // Copy position & rotation from the old hierarchy into the dead replacement
         CopyTransformsRecurse(transform, dead);
         
         Collider[] colliders = dead.GetComponentsInChildren<Collider>();
         foreach(Collider col in colliders){
            Physics.IgnoreCollision(col, AIComponent.FPSWalker.capsule, true);
         }
         
         //apply damage force to NPC ragdoll
         if(Physics.SphereCast(attackerPos2, 0.2f, attackDir2, out rayHit, 750.0f, raymask)
         && rayHit.rigidbody
         && attackDir2.x !=0){
            //apply damage force to the ragdoll rigidbody hit by the sphere cast (can be any body part)
            rayHit.rigidbody.AddForce(attackDir2 * 10.0f, ForceMode.Impulse);
         
         }else{//apply damage force to NPC ragdoll if being damaged by an explosive object or other damage source without a specified attack direction
         
            Component[] bodies;
            bodies = dead.GetComponentsInChildren<Rigidbody>();
            foreach(Rigidbody body in bodies) {
               if(explosionCheck){
                  //if(body.transform.name == "Chest"){//only apply damage force to the chest of the ragdoll if damage is from non-player source
                     //calculate direction to apply damage force to ragdoll
                     body.AddForce((myTransform.position - (attackerPos2 + (Vector3.up * -2.5f))).normalized * Random.Range(4.5f, 7.5f), ForceMode.Impulse);
                  //}
               }else{
                  if(body.transform.name == "Chest"){//only apply damage force to the chest of the ragdoll if damage is from non-player source
                     //calculate direction to apply damage force to ragdoll
                     body.AddForce((myTransform.position - attackerPos2).normalized * 10.0f, ForceMode.Impulse);
                  }
               }
            }
         }
         
         //initialize the RemoveBody.cs script attached to the NPC ragdoll
         if(RemoveBodyComponent){
            if(removeBody){
               RemoveBodyComponent.enabled = true;
               RemoveBodyComponent.bodyStayTime = bodyStayTime;//pass bodyStayTime to RemoveBody.cs script
            }else{
               RemoveBodyComponent.enabled = false;
            }
         }
         
         //Determine if this object or parent should be removed.
         //This is to allow for different hit detection collider types as children of NPC parent.
         if(notParent){
            Destroy(transform.parent.gameObject);
         }else{
            Destroy(transform.gameObject);
         }
         
      }
   
   }
   
   static void CopyTransformsRecurse ( Transform src , Transform dst ){
      dst.position = src.position;
      dst.rotation = src.rotation;
      
      foreach(Transform child in dst) {
         // Match the transform with the same name
         Transform curSrc = src.Find(child.name);
         if (curSrc)
            CopyTransformsRecurse(curSrc, child);
      }
   }
}

NPC ATTACK

Código:

http://NPCAttack.cs by Azuline Studios©️ All Rights Reserved
//Manages timers for enemy attacks, damage application to other objects, and sound effects.
using UnityEngine;
using System.Collections;

public class NPCAttack : MonoBehaviour {
   private AI AIComponent;
   private   WeaponEffects WeaponEffectsComponent;
   private FPSRigidBodyWalker FPSWalker;
   private GameObject playerObj;

   private Transform myTransform;
   private Vector3 targetPos;
   [Tooltip("Maximum range of NPC attack.")]
   public float range = 100.0f;
   [Tooltip("Random range in units around target that NPC attack will hit (so NPCs won't have perfect aim).")]
   public float inaccuracy = 0.5f;
   [Tooltip("Fire rate of NPC attack.")]
   public float fireRate = 0.097f;
   [Tooltip("Number of attacks to fire in quick succession during NPC attack (for automatic weapons).")]
   public int burstShots = 0;
   [Tooltip("Maximum number of random shots to add to end of attack (so automatic weapons will fire different number of bullets per attack).")]
   public int randomShots = 0;
   [Tooltip("Physics force to apply to collider hit by NPC attack.")]
   public float force = 20.0f;
   [Tooltip("Damage to inflict per NPC attack.")]
   public float damage = 10.0f;
   [Tooltip("True if this is a melee attack (so actions like blocking can identify attack type).")]
   public bool isMeleeAttack;
   private float damageAmt;
//   public int bulletsPerClip = 50;
//   public int ammo = 150;
//   public float reloadTime = 1.75f;
   
   private bool doneShooting = true;
   private int shotsFired;
   private bool randBurstState;
   private int randShotsAmt;
   private bool  shooting = false;
   private bool  reloading = false;
   private bool  mFlashState = false;
   //private bool  noAmmoState = false;

   private Vector3 rayOrigin;
   private Vector3 targetDir;
   private RaycastHit[] hits;
   private bool hitObject;

   [Tooltip("Muzzle flash object to display during NPC attacks.")]
   public Renderer muzzleFlash;
   private Transform muzzleFlashTransform;
   
   [Tooltip("Sound effect for NPC attack.")]
   public AudioClip firesnd;
   [Tooltip("Random pitch chosen between this value and 1.0 for NPC attack sound variety.")]
   public float fireFxRandPitch = 0.86f;
   private AudioSource aSource;
//   public AudioClip reloadsnd;
//   public AudioClip noammosnd;
   
//   private int bulletsLeft = 0;
   
   private float shootStartTime = 0.0f;
   
   void OnEnable (){
      
      myTransform = transform;
      if (muzzleFlash){
         muzzleFlashTransform = muzzleFlash.transform;
      }
      AIComponent = myTransform.GetComponent<AI>();
      WeaponEffectsComponent = AIComponent.playerObj.GetComponent<FPSPlayer>().weaponObj.GetComponent<WeaponEffects>();
      playerObj = Camera.main.transform.GetComponent<CameraControl>().playerObj;
      FPSWalker = playerObj.GetComponent<FPSRigidBodyWalker>();
      aSource = GetComponent<AudioSource>();

      //bulletsLeft = bulletsPerClip;
      shootStartTime = -fireRate * 2;
   }
   
   void Update (){
   
      if(shootStartTime + fireRate < Time.time){
         shooting = false;
      }
      
      //fire more shots per attack if burstShots or randomShots is greater than zero
      if(!doneShooting && shotsFired < (burstShots + randShotsAmt)
         && (AIComponent.target == AIComponent.playerTransform || AIComponent.target == AIComponent.FPSWalker.leanObj.transform || (AIComponent.TargetAIComponent && AIComponent.TargetAIComponent.enabled))){
         Fire();   
         if(!randBurstState){//get random number of shots to add to this burst for variation
            randShotsAmt = Random.Range(0,randomShots);
            randBurstState = true;
         }
      }else{//reset burst shooting vars
         doneShooting = true;
         shotsFired = 0;
         randBurstState = false;
      }
      
   }
   
   void LateUpdate (){
   
      //enable muzzle flash
      if (muzzleFlash){
         if(Time.time - shootStartTime < fireRate * 0.33){
            if(mFlashState){
               muzzleFlash.enabled = true;
               mFlashState = false;
            }
         }else{
            if(!mFlashState){
               // We didn't, disable the muzzle flash
               muzzleFlash.enabled = false;
            }
         }
      }
   
   }
   
   public void Fire (){
   
//      if (bulletsLeft == 0){
//         return;
//      }
      
      //fire weapon
      if(!reloading){
         if(!shooting){
            FireOneShot();
            shootStartTime = Time.time;
            shooting = true;
            doneShooting = false;
         }else{
            if(shootStartTime + fireRate < Time.time){
               shooting = false;
            }
         }
      }else{
         shooting = false;
      }
   
   }
   
   void FireOneShot (){
      RaycastHit hit;
      if(AIComponent.TargetAIComponent){
         if(Vector3.Distance(myTransform.position, AIComponent.lastVisibleTargetPosition) > 2.5f){
            targetPos = new Vector3(AIComponent.lastVisibleTargetPosition.x + Random.Range(-inaccuracy, inaccuracy),
                              AIComponent.lastVisibleTargetPosition.y + Random.Range(-inaccuracy, inaccuracy),
                              AIComponent.lastVisibleTargetPosition.z + Random.Range(-inaccuracy, inaccuracy));
         }else{
            targetPos = new Vector3(AIComponent.lastVisibleTargetPosition.x,
                                      AIComponent.lastVisibleTargetPosition.y,
                                      AIComponent.lastVisibleTargetPosition.z);
         }
      }else{
         if(Vector3.Distance(myTransform.position, AIComponent.lastVisibleTargetPosition) > 2.5f){//only calculate inaccuracy if target is not in close range
            if(FPSWalker.crouched || FPSWalker.prone){
               targetPos = new Vector3(AIComponent.lastVisibleTargetPosition.x + Random.Range(-inaccuracy, inaccuracy),
                                       AIComponent.lastVisibleTargetPosition.y + Random.Range(-inaccuracy, inaccuracy),
                                       AIComponent.lastVisibleTargetPosition.z + Random.Range(-inaccuracy, inaccuracy));
            }else{
               targetPos = new Vector3(AIComponent.lastVisibleTargetPosition.x + Random.Range(-inaccuracy, inaccuracy),
                                       AIComponent.lastVisibleTargetPosition.y + Random.Range(-inaccuracy, inaccuracy),
                                       AIComponent.lastVisibleTargetPosition.z + Random.Range(-inaccuracy, inaccuracy))
                  + (AIComponent.playerObj.transform.up * AIComponent.targetEyeHeight);
            }
         }else{
            targetPos = new Vector3(AIComponent.lastVisibleTargetPosition.x,
                                    AIComponent.lastVisibleTargetPosition.y,
                                    AIComponent.lastVisibleTargetPosition.z);
         }
      }

      rayOrigin = new Vector3(myTransform.position.x, myTransform.position.y + AIComponent.eyeHeight, myTransform.position.z);
      targetDir = (targetPos - rayOrigin).normalized;
      if (muzzleFlashTransform){
         WeaponEffectsComponent.BulletTracers(targetDir, muzzleFlashTransform.position, -3.0f, 0.0f, false);
      }

      hitObject = false;
      hit = new RaycastHit();
      
      // Did we hit anything?
      hits = Physics.RaycastAll (rayOrigin, targetDir, Vector3.Distance(rayOrigin, targetPos), AIComponent.searchMask);
      
      //check if NPC can see their target
      for(int i = 0; i < hits.Length; i++){
         if(!hits[i].transform.IsChildOf(myTransform) ){
            hitObject = true;
            hit = hits[i];
            break;
         }
      }
      
      if (hitObject) {
         // Apply a force to the rigidbody we hit
         if (hit.rigidbody){
            hit.rigidbody.AddForceAtPosition(force * targetDir / (Time.fixedDeltaTime * 100.0f), hit.point);
         }
      
         if(hit.collider){
            //draw impact effects where the weapon hit
            if(hit.collider.gameObject.layer != 20 && hit.collider.gameObject.layer != 11){
               if(!isMeleeAttack){
                  WeaponEffectsComponent.ImpactEffects(hit.collider, hit.point, true, false, hit.normal);
               }else{
                  WeaponEffectsComponent.ImpactEffects(hit.collider, hit.point, true, true, hit.normal);
               }
            }
            
            //calculate damage amount
            damageAmt = Random.Range(damage, damage + damage);   
            
            //call the ApplyDamage() function in the script of the object hit
            switch(hit.collider.gameObject.layer){
               case 0://hit object is an apple
                  if(hit.collider.gameObject.GetComponent<AppleFall>()){
                     hit.collider.gameObject.GetComponent<AppleFall>().ApplyDamage(damageAmt);
                  }   
                  //hit object is a breakable or explosive object
                  if(hit.collider.gameObject.GetComponent<BreakableObject>()){
                     hit.collider.gameObject.GetComponent<BreakableObject>().ApplyDamage(damageAmt);
                  }else if(hit.collider.gameObject.GetComponent<ExplosiveObject>()){
                     hit.collider.gameObject.GetComponent<ExplosiveObject>().ApplyDamage(damageAmt);
                  }else if(hit.collider.gameObject.GetComponent<MineExplosion>()){
                     hit.collider.gameObject.GetComponent<MineExplosion>().ApplyDamage(damageAmt);
                  }
                  break;
               case 13://hit object is an NPC
                  if(hit.collider.gameObject.GetComponent<CharacterDamage>()){
                     hit.collider.gameObject.GetComponent<CharacterDamage>().ApplyDamage(damageAmt, Vector3.zero, myTransform.position, myTransform, false, false);
                  }
                  if(hit.collider.gameObject.GetComponent<LocationDamage>()){
                     hit.collider.gameObject.GetComponent<LocationDamage>().ApplyDamage(damageAmt, Vector3.zero, myTransform.position, myTransform, false, false);
                  }
                  break;
               case 11://hit object is player
                  if(hit.collider.gameObject.GetComponent<FPSPlayer>()){
                     hit.collider.gameObject.GetComponent<FPSPlayer>().ApplyDamage(damageAmt, myTransform, isMeleeAttack);
                  }   
                  if(hit.collider.gameObject.GetComponent<LeanColliderDamage>()){
                     hit.collider.gameObject.GetComponent<LeanColliderDamage>().ApplyDamage(damageAmt);
                  }   
                  break;
               case 20://hit object is player lean collider
                  if(hit.collider.gameObject.GetComponent<FPSPlayer>()){
                     hit.collider.gameObject.GetComponent<FPSPlayer>().ApplyDamage(damageAmt, myTransform, isMeleeAttack);
                  }   
                  if(hit.collider.gameObject.GetComponent<LeanColliderDamage>()){
                     hit.collider.gameObject.GetComponent<LeanColliderDamage>().ApplyDamage(damageAmt);
                  }   
                  break;
               default:
                  break;   
            }
         }
         
      }

      aSource.clip = firesnd;
      aSource.pitch = Random.Range(fireFxRandPitch, 1);
      if(aSource.volume > 0){
         aSource.PlayOneShot(aSource.clip, 0.8f / aSource.volume);
      }
      
      //track ammo and fired shots amount
      //bulletsLeft--;
      shotsFired++;

      mFlashState=true;
      enabled = true;
      
      // Reload gun in reload Time      
//      if (bulletsLeft == 0){
//         Reload();   
//      }
      
   }
   
//   IEnumerator Reload (){
//      
//      if(ammo > 0){
//         audio.volume = 1.0f;
//         audio.pitch = 1.0f;
//         audio.PlayOneShot(reloadsnd, 1.0f / audio.volume);
//         
//         reloading = true;
//         // Wait for reload time first, then proceed
//         yield return new WaitForSeconds(reloadTime);
//         //set reloading var in ironsights script to true after reloading delay
//         reloading = false;
//   
//         // We have ammo left to reload
//         if(ammo >= bulletsPerClip){
//            ammo -= bulletsPerClip - bulletsLeft;
//            bulletsLeft = bulletsPerClip;
//         }else{
//            bulletsLeft += ammo;
//            ammo = 0;
//         }
//      }
//      
//   }
   
//   private int GetBulletsLeft(){
//      return bulletsLeft;
//   }
}

ESSES ACIMA SÃO OS SCRIPS DO PROPRIO NPC AGORA TEM UM COMPLEMENTO CHAMADO "[ZOMBIE NPC]TRIGGER" QUE TEM AMIS UM SCRIPT> Monster Trigger:
Código:

http://MonsterTrigger.cs by Azuline Studios©️ All Rights Reserved
//used to spawn NPCs after player enters trigger to set up traps and ambushes
using UnityEngine;
using System.Collections;

public class MonsterTrigger : MonoBehaviour {
   [Tooltip("NPC objects to deactivate on level load and activate when player walks into trigger.")]
   public GameObject[] npcsToTrigger;
   
   void Start () {
      //deactivate the npcs in the npcsToTrigger array on start up
      for (int i = 0; i < npcsToTrigger.Length; i++){
         if(npcsToTrigger[i]){
            npcsToTrigger[i].SetActive(false);
         }
      }
   }

   void OnTriggerEnter ( Collider col  ){
      if(col.gameObject.tag == "Player"){
         //activate the npcs in the npcsToTrigger array when object is picked up/used by player
         for (int i = 0; i < npcsToTrigger.Length; i++){
            if(npcsToTrigger[i]){
               npcsToTrigger[i].SetActive(true);
            }
         }         
         Destroy(transform.gameObject);
      }
   }
}


ACREDITO QUE ESTE ULTIMO É PARA MOSTRAR ONDE O NPC DEVE NASCER.
Daniel Dória
Daniel Dória
Avançado
Avançado

Masculino PONTOS : 1898
REPUTAÇÃO : 31
Idade : 20
Respeito as regras : Configurar NPCs WvDYdlf

https://planecaos.jimdofree.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por MarcosSchultz Seg Jul 30, 2018 4:47 pm

Não temos acesso ao asset, então não tem como saber o que pode estar errado... geralmente é falta de configuração no InputManager.

Tente ler a documentação ou mandar email diretamente para o criador do asset, informando os problemas, pois ele saberá o que é.
MarcosSchultz
MarcosSchultz
Administrador

Masculino PONTOS : 64013
REPUTAÇÃO : 2611
Idade : 25
Áreas de atuação : Administrador do fórum
Respeito as regras : Configurar NPCs Aad8pUi

https://www.schultzgames.com

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Daniel Dória Seg Jul 30, 2018 10:47 pm

Cara então me mande seu email que upo o asset no drive e te envio para você ver e me ajudar, não existe uma documentação explicando como usa o produto e os desenvolvedores não respondem email[Você verá muitas reclamações desse tipo se olhar na loja].
Daniel Dória
Daniel Dória
Avançado
Avançado

Masculino PONTOS : 1898
REPUTAÇÃO : 31
Idade : 20
Respeito as regras : Configurar NPCs WvDYdlf

https://planecaos.jimdofree.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Tiago95 Ter Jul 31, 2018 9:44 am

E se vc tentar importar o seu projeto p dentro da scene q veio o asset q está funcionando?

Tiago95
Avançado
Avançado

PONTOS : 1752
REPUTAÇÃO : 32
Respeito as regras : Configurar NPCs WvDYdlf

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Daniel Dória Qua Ago 01, 2018 12:02 pm

Tiago95 escreveu:E se vc tentar importar o seu projeto p dentro da scene q veio o asset q está funcionando?

Eu testei isso de varias maneiras e conclui que seja qual for o lugar que coloco o zumbi ou soldadinho mal para nascer ele sempre acaba nascendo no lugar onde seria o scene padrão do asset, mesmo que eu apague tudo daquele scene e bote o NPC em um lugar aleatório ele ficara parado nesse lugar fora da zona e quando eu for para o centro da scene ali estará ele flutuando como se estivesse caminhando em uma terra'in, e entrando em casas que não existem mais como se fosse uma área de spawn. Enfim, desisto desse asset estou migrando para o UNITz e ver se finalmente consigo um modo multiplayer ou boot funcional.

Daniel Dória
Daniel Dória
Avançado
Avançado

Masculino PONTOS : 1898
REPUTAÇÃO : 31
Idade : 20
Respeito as regras : Configurar NPCs WvDYdlf

https://planecaos.jimdofree.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Daniel Dória Seg Out 01, 2018 12:47 pm

Eu descobri nesses últimos dias que não importa qual for o asset de npc eles só funciona se a terrain estiver na posição padrão de quando inicia um projeto unity, se por exemplo arrastar ela para mais embaixo deixando a posicao y de 0 para -100 os npcs não se movem mais, a animação de movimentação as vezes podem até funcionar mas os players não se movem. Descobri também que eles atravessam paredes!
Alguem tem uma ideia para fazer funcionar isso seja na posição que for que a terra ou gameobject como chao estiver, e como fazer para não atravessarem paredes?
Daniel Dória
Daniel Dória
Avançado
Avançado

Masculino PONTOS : 1898
REPUTAÇÃO : 31
Idade : 20
Respeito as regras : Configurar NPCs WvDYdlf

https://planecaos.jimdofree.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Callyde Jr Ter Out 02, 2018 8:25 pm

Usando Layers e MeshColliders
Unity - Manual: Layers
Unity - Manual: Mesh Collider




Callyde Jr
Callyde Jr
Programador

Masculino PONTOS : 4270
REPUTAÇÃO : 441
Idade : 43
Áreas de atuação : Iniciante em modelagem Blender,Sketchup
Programador
Idealista

Meu Canal
https://www.youtube.com/ch
Respeito as regras : Configurar NPCs WvDYdlf

http://unnygames.000webhostapp.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Daniel Dória Qui Out 04, 2018 10:03 pm

Então se eu usar layers os inimigos do jogo vai funcionar normal mesmo se a escala do terreno estiver modificado? E quanto ao mesh collider eu ainda não vi o vídeo mas pelo que eu saiba colisores são colocados nos objetos, então um npc não detectaria ja que ele está configurado como um objeto animado que naturalmente quando se movimenta a animação atravessa aquele lugar como se nada existisse. Os npc como falei acima ele só funcionou no terreno na escala padrão de quando pega um terreno pronto de um projeto agora se eu junto esse terreno com um pedaco de Outro terreno quando o npc chegar aquele lugar ele não vai detectar o Outro terreno e vai atravessar o local, assim também com um objeto 3d ou qualquer outra coisa mesmo tendo terrain collider, box collider, mesh ou qualquer outro colisor tudo funciona normal para MEU PLAYER mas PARA OS NPCs nada adianta.
Daniel Dória
Daniel Dória
Avançado
Avançado

Masculino PONTOS : 1898
REPUTAÇÃO : 31
Idade : 20
Respeito as regras : Configurar NPCs WvDYdlf

https://planecaos.jimdofree.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Callyde Jr Sex Out 05, 2018 8:22 pm

Os NPCs se tiverem collisor eles nao atrevessam as paredes eles bate e ficam
Assets prontos sao bons para adiantar nossos projetos mais uns antigos ou novos as vezes vem bugs com scripts e outras coisas.
Eles tem que vim manual,suporte e videos para nos ajudar.
Uma vez baixei um asset de corridas de carros tive que deleta-lo ele veio todo em Java nao tinha suporte,videos nadinha.
Ia da um trabalho para arrumar que desisti e comecei fazer do zero um projeto desse vai demorar mais vale a pena.
Callyde Jr
Callyde Jr
Programador

Masculino PONTOS : 4270
REPUTAÇÃO : 441
Idade : 43
Áreas de atuação : Iniciante em modelagem Blender,Sketchup
Programador
Idealista

Meu Canal
https://www.youtube.com/ch
Respeito as regras : Configurar NPCs WvDYdlf

http://unnygames.000webhostapp.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por Daniel Dória Qui Jan 24, 2019 3:06 pm

Callyde Jr escreveu:Os NPCs se tiverem collisor eles nao atrevessam as paredes eles bate e ficam... 
Voltando aqui porque descobri que para os npc não atravessar paredes é necessário ter navmesh obstacle nos objetos, ele funciona como um box collider que só colide entre eles mesmo. 
E quanto ao problema deles não se movimentar descobri que eles só funciona em um terreno sem modificação na escala se tiver mais de um terreno ele vai ignorar e atravessar ou se coloca-los em cima de um objeto continuará sem movimentos um dia estudarei sobre isso também ...
Daniel Dória
Daniel Dória
Avançado
Avançado

Masculino PONTOS : 1898
REPUTAÇÃO : 31
Idade : 20
Respeito as regras : Configurar NPCs WvDYdlf

https://planecaos.jimdofree.com/

Ir para o topo Ir para baixo

DÚVIDA Re: Configurar NPCs

Mensagem por ProBrStalker Dom Jun 20, 2021 4:13 pm

Daniel Dória escreveu:
Callyde Jr escreveu:Os NPCs se tiverem collisor eles nao atrevessam as paredes eles bate e ficam... 
Voltando aqui porque descobri que para os npc não atravessar paredes é necessário ter navmesh obstacle nos objetos, ele funciona como um box collider que só colide entre eles mesmo. 
E quanto ao problema deles não se movimentar descobri que eles só funciona em um terreno sem modificação na escala se tiver mais de um terreno ele vai ignorar e atravessar ou se coloca-los em cima de um objeto continuará sem movimentos um dia estudarei sobre isso também ...
Bom, vamos lá, boa tarde, eu possuo +/- quatro anos de experiencia com o RFPS, e embora este tópico seja antigo, tudo o que você precisa fazer, é criar a NavMesh do terreno, e definir as casas, paredes, murros etc como objetos não andáveis, para que eles não atravessem o que você deseja....
Se eu não me engano, todas as documentações de cada versão do RFPS falam isso...eu li apenas até a 1.9...(não cheguei a ler mais sobre as novas...)
espero ter ajudado =)

*NavMesh obstacle serve apenas para objetos como barris, caixas, etc
ProBrStalker
ProBrStalker
Avançado
Avançado

Masculino PONTOS : 1971
REPUTAÇÃO : 12
Respeito as regras : Configurar NPCs WvDYdlf

https://redskygamesstudios.000webhostapp.com/

Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos