/// <summary>
        /// get closest npc
        /// </summary>
        /// <returns>returns closest npc</returns>
        private NPCScript _getClosest()
        {
            NPCScript cur     = null;
            float     curDist = float.MaxValue;

            foreach (NPCGuardZone zone in m_CurrentZones)
            {
                for (int i = 0; i < zone.npc_list.Count; i++)
                {
                    NPCScript npc = zone.npc_list[i];
                    if (npc.isDead)
                    {
                        continue;
                    }
                    if (npc.npcState != NPCScript.NPCState.Chase)
                    {
                        float dist = Vector3.Distance(m_Player.transform.position, npc.transform.position);
                        if (dist < curDist)
                        {
                            curDist = dist;
                            cur     = npc;
                        }
                    }
                }
            }
            return(cur);
        }
예제 #2
0
        void _createNPCScript()
        {
            NPCScript npcscript = character.GetComponent <NPCScript>();

            if (!npcscript)
            {
                npcscript = Undo.AddComponent <NPCScript>(character);
            }
            npcscript.blockOdds      = 10;
            npcscript.attackInterval = 1.0f;
            Transform sweepCapsule = Utils.FindChildTransformByName(character.transform, "AttackSweepCapsule");
            Rigidbody sweepBody    = null;

            if (!sweepCapsule)
            {
                Debug.Log("Creating attack sweep capsule");
                sweepBody = Resources.Load <Rigidbody>("AttackSweepCapsule");
                sweepBody = Instantiate(sweepBody);
                sweepBody.transform.SetParent(npcscript.transform);
                sweepBody.transform.localPosition = new Vector3(0.0f, 1.276f, 0.0f);
                sweepBody.name = "AttackSweepCapsule";
            }
            if (!sweepBody)
            {
                Debug.LogError("Cannot find Rigidbody on 'AttackSweepCapsule'" + " < " + character.ToString() + ">");
                return;
            }
            npcscript.attackSweepBody = sweepBody;
        }
        /// <summary>
        /// add all npcs that are in range and under angle from direction to the list.
        /// </summary>
        /// <param name="range">range condition</param>
        /// <param name="angle">angle condition</param>
        /// <param name="position">test position</param>
        /// <param name="direction">test direction</param>
        /// <param name="npcList">list on which to add</param>
        public void CollectNpcsInRangeAngle(float range, float angle, Vector3 position, Vector3 direction, List <IGameCharacter> npcList)
        {
            npcList.Clear();

            for (int i = 0; i < m_Npcs.Length; i++)
            {
                NPCScript npc = m_Npcs[i];
                if (npc.isDead)
                {
                    continue;
                }
                if (npc.ragdollState != RagdollManager.RagdollState.Animated)
                {
                    continue;
                }
                Vector3 dir2npc = npc.transform.position - position;
                float   dist    = Vector3.Distance(position, npc.transform.position);
                if (dist <= range)
                {
                    float cur_angle = Vector3.Angle(direction, dir2npc.normalized);
                    if (cur_angle <= angle)
                    {
                        npcList.Add(npc);
                    }
                }
            }
        }
예제 #4
0
 /// <summary>
 /// Unity Start method
 /// Start is called on the frame when a script is enabled just before any of the Update methods is called the first time
 /// </summary>
 void Start()
 {
     // check if guard zone is assigned on all
     for (int i = 0; i < npc_list.Count; i++)
     {
         NPCScript npc = npc_list[i];
         npc.guardZone = this;
     }
 }
        /// <summary>
        /// add local avoidance around npcs and player
        /// </summary>
        /// <param name="move">ref current move velocity</param>
        private void _add_local_avoidance(ref Vector3 move)
        {
            float repulseDistance = avoidanceDistance;

            Vector3 toPlayer    = transform.position - m_Player.transform.position;
            Vector3 dir2player  = toPlayer.normalized;
            float   dist2player = toPlayer.magnitude;


            // avoidance of npcs
            float   power = 8;
            Vector3 force = Vector3.zero;

            for (int i = 0; i < m_NPCManager.npcs.Length; i++)
            {
                NPCScript npc = m_NPCManager.npcs[i];
                if (this == npc)
                {
                    continue;
                }
                if (npc.ragdollState != RagdollManager.RagdollState.Animated)
                {
                    continue;
                }

                Vector3 toNpc    = transform.position - npc.transform.position;
                Vector3 dir2npc  = toNpc.normalized;
                float   dist2npc = toNpc.magnitude;
                float   val      = Mathf.Clamp01(repulseDistance / dist2npc);
                val = Mathf.Pow(val, power);
                float strength = Mathf.Lerp(0.0f, 1.0f, val);
                force += dir2npc * strength;
            }
            // avoidance of player
            if (dist2player < 0.45f)
            {
                float val = Mathf.Clamp01(repulseDistance / dist2player);
                val = Mathf.Pow(val, power);
                float strength = Mathf.Lerp(0.0f, 1.0f, val) * 4f;
                force += dir2player * strength;
            }
            move += force;

#if SMOOTH_MOVEMENT
            avgMove[avgIdx] = move;
            avgIdx++;
            if (avgIdx >= avgMove.Length)
            {
                avgIdx = 0;
            }
#endif
        }
 /// <summary>
 /// provides info is any npc in combat
 /// </summary>
 /// <param name="caller">pass caller so it can be skipped</param>
 /// <returns>true or false</returns>
 public bool AnyNpcInCombat(NPCScript caller)
 {
     for (int i = 0; i < npcs.Length; i++)
     {
         NPCScript npc = npcs[i];
         if (npc == caller)
         {
             continue;
         }
         if (npc.inCombat)
         {
             return(true);
         }
     }
     return(false);
 }
 /// <summary>
 /// npc chase state
 /// </summary>
 private void chase()
 {
     NUM_CHASERS_GLOBAL = 0;
     foreach (NPCGuardZone zone in m_CurrentZones)
     {
         for (int i = 0; i < zone.npc_list.Count; i++)
         {
             zone.npc_list[i].npcState = NPCScript.NPCState.Return;
         }
         zone.numChasers = 0;
         for (int i = zone.numChasers; i < zone.allowedAttackers; i++)
         {
             NPCScript npc = _getClosest();
             if (npc)
             {
                 if (npc.isDead)
                 {
                     continue;
                 }
                 npc.startChase();
                 zone.numChasers++;
                 NUM_CHASERS_GLOBAL++;
             }
         }
         for (int i = 0; i < zone.npc_list.Count; i++)
         {
             NPCScript npc = zone.npc_list[i];
             if (npc)
             {
                 if (npc.isDead)
                 {
                     continue;
                 }
                 if (npc.npcState != NPCScript.NPCState.Chase)
                 {
                     npc.npcState = NPCScript.NPCState.Wait;
                 }
             }
         }
     }
 }
        /// <summary>
        /// number of npcs in range in current zone/s
        /// </summary>
        /// <returns></returns>
        public int NumInRangeInZone()
        {
            if (m_CurrentZones.Count == 0)
            {
                return(0);
            }
            int num = 0;

            foreach (NPCGuardZone zone in m_CurrentZones)
            {
                for (int i = 0; i < zone.npc_list.Count; i++)
                {
                    NPCScript npc = zone.npc_list[i];
                    if (npc.inAttackRange)
                    {
                        num++;
                    }
                }
            }
            return(num);
        }
        /// <summary>
        /// provides info of number of npcs in combat in current zone
        /// </summary>
        /// <returns>true or false</returns>
        public int NumNpcInCombatInZone()
        {
            if (m_CurrentZones.Count == 0)
            {
                return(0);
            }
            int count = 0;

            foreach (NPCGuardZone zone in m_CurrentZones)
            {
                for (int i = 0; i < zone.npc_list.Count; i++)
                {
                    NPCScript npc = zone.npc_list[i];
                    if (npc.inCombat)
                    {
                        count++;
                    }
                }
            }
            return(count);
        }
        /// <summary>
        /// return number of attacker in current zone
        /// </summary>
        /// <returns></returns>
        public int NumNpcAttackingInZone()
        {
            if (m_CurrentZones.Count == 0)
            {
                return(0);
            }
            int count = 0;

            foreach (NPCGuardZone zone in m_CurrentZones)
            {
                for (int i = 0; i < zone.npc_list.Count; i++)
                {
                    NPCScript npc = zone.npc_list[i];
                    if (npc.animator.GetCurrentAnimatorStateInfo(0).IsName("AttackCombo"))
                    {
                        count++;
                    }
                }
            }
            return(count);
        }
        /// <summary>
        /// number of npcs chasing in current zone/s
        /// </summary>
        /// <returns></returns>
        public int NumChasingInZone()
        {
            if (m_CurrentZones.Count == 0)
            {
                return(0);
            }

            int num = 0;

            foreach (NPCGuardZone zone in m_CurrentZones)
            {
                for (int i = 0; i < zone.npc_list.Count; i++)
                {
                    NPCScript npc = zone.npc_list[i];
                    if (npc.npcState == NPCScript.NPCState.Chase)
                    {
                        num++;
                    }
                }
            }
            return(num);
        }
 /// <summary>
 /// provides info is any npc is attacking in current zone
 /// </summary>
 /// <param name="caller">pass caller so it can be skipped</param>
 /// <returns>true or false</returns>
 public bool AnyNpcAttackingInZone(NPCScript caller)
 {
     if (m_CurrentZones.Count == 0)
     {
         return(false);
     }
     foreach (NPCGuardZone zone in m_CurrentZones)
     {
         for (int i = 0; i < zone.npc_list.Count; i++)
         {
             NPCScript npc = zone.npc_list[i];
             if (npc == caller)
             {
                 continue;
             }
             if (npc.animator.GetCurrentAnimatorStateInfo(0).IsName("AttackCombo"))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
 /// <summary>
 /// in current zone/s add all npcs that are in range and under angle of transform.forward to the list.
 /// </summary>
 /// <param name="range">range condition</param>
 /// <param name="angle">angle condition</param>
 /// <param name="xform">transform ( position/ forward )</param>
 /// <param name="npcList">list on which to add</param>
 public void CollectNpcsInRangeAngleInZone(float range, float angle, Transform xform, List <NPCScript> npcList)
 {
     npcList.Clear();
     if (m_CurrentZones.Count == 0)
     {
         return;
     }
     foreach (NPCGuardZone zone in m_NpcZones)
     {
         if (zone.playerInZone)
         {
             for (int i = 0; i < zone.npc_list.Count; i++)
             {
                 NPCScript npc = zone.npc_list[i];
                 if (npc.isDead)
                 {
                     continue;
                 }
                 if (npc.ragdollState != RagdollManager.RagdollState.Animated)
                 {
                     continue;
                 }
                 Vector3 dir2npc = npc.transform.position - xform.position;
                 float   dist    = Vector3.Distance(xform.position, npc.transform.position);
                 if (dist < range)
                 {
                     float cur_angle = Vector3.Angle(xform.forward, dir2npc.normalized);
                     if (cur_angle <= angle)
                     {
                         npcList.Add(npc);
                     }
                 }
             }
         }
     }
 }
        /// <summary>
        /// provides info is any npc in combat in current zone
        /// </summary>
        /// <param name="caller">pass caller so it can be skipped</param>
        /// <returns>true or false</returns>
        public bool AnyNpcInCombatInZone(NPCScript caller)
        {
            if (m_CurrentZones.Count == 0)
            {
                return(false);
            }

            foreach (NPCGuardZone zone in m_CurrentZones)
            {
                for (int i = 0; i < zone.npc_list.Count; i++)
                {
                    NPCScript npc = zone.npc_list[i];
                    if (npc == caller)
                    {
                        continue;
                    }
                    if (npc.inCombat)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
예제 #15
0
        /// <summary>
        /// Unity OnTriggerStay method
        /// OnTriggerStay is called once per frame for every Collider other that is touching the trigger
        /// </summary>
        /// <param name="col">collider staying in the trigger</param>
        void OnTriggerStay(Collider col)
        {
            if (m_CollectingNPCs)
            {
                if (col.tag == "NPC")
                {
                    NPCScript npc = col.GetComponent <NPCScript>();
                    if (npc)
                    {
                        if (!npc_list.Contains(npc))
                        {
                            npc.guardZone = this;
                            npc_list.Add(npc);
                        }
                    }
                }
            }

            // if player is inside, flag as true
            if (col.gameObject.tag == "Player")
            {
                m_PlayerInZone = true;
            }
        }