public void RemoveOccupier()
        {
            if (OccupyingNPC != null)
            {
                OccupyingNPC.OccupyingChair = null;
                OccupyingNPC = null;
            }

            Occupier = OccupierType.None;
        }
        public void AssignPlayerAsOccupier()
        {
            if (OccupyingNPC != null)
            {
                OccupyingNPC.OccupyingChair = null;
                OccupyingNPC = null;
            }

            Occupier = OccupierType.Player;
        }
        public void AssignFairyAsOccupier(ViveSR_Experience_NPCAnimationRef npc)
        {
            if (OccupyingNPC != null)
            {
                OccupyingNPC.OccupyingChair = null;
            }

            OccupyingNPC = npc;
            OccupyingNPC.OccupyingChair = this;
            Occupier = OccupierType.Fairy;
        }
        IEnumerator GenerateNPCs()
        {
            portalMgr.ClearAllPortals();
            isGeneratingNPC = true;

            ViveSR_Portal portal = Instantiate(PortalPrefeb.GetComponent <ViveSR_Portal>());

            portal.TransitionMaterialUpdateCB = TransitionMatCB;

            portal.transform.position = Portal_Pos;
            portal.transform.forward  = -Spawn_Fwd;

            portalMgr.AddPortal(portal.gameObject);
            portalMgr.UpdateViewerWorld();

            ViveSR_Experience_PortalAnimation pa = portal.GetComponent <ViveSR_Experience_PortalAnimation>();

            pa.PortalLogo.gameObject.layer = LayerMask.NameToLayer("VirtualWorldLayer");

            while (NPCRefs.Count < NumOfNPC && isGeneratingNPC)
            {
                ViveSR_Experience_NPCAnimationRef NPCRef = Instantiate(NPCPrefab).GetComponent <ViveSR_Experience_NPCAnimationRef>();
                NPCRefs.Add(NPCRef);

                NPCRef.transform.position = Spawn_Pos;
                NPCRef.transform.forward  = -Spawn_Fwd;

                NPCRef.NPCAnimController.Walk(Portal_Pos, () =>
                {
                    AssignClosestChair(NPCRef);
                });

                //next fairy
                yield return(new WaitForSeconds(2f));
            }

            if (pa != null)
            {
                pa.SetPortalScale(false);
            }

            isGeneratingNPC = false;
        }
        void AssignClosestChair(ViveSR_Experience_NPCAnimationRef NPCRef, ViveSR_Experience_Chair OldChair = null)
        {
            if (NPCRef.NPCAnimController.isActing)
            {
                return;
            }

            float minDist = 999;
            ViveSR_Experience_Chair targetChair = null;

            for (int i = 0; i < Chairs.Count; i++)
            {
                bool isChairOccupied = Chairs[i].Occupier != ViveSR_Experience_Chair.OccupierType.None;
                if (isChairOccupied)
                {
                    continue;
                }

                float distToNpc = Vector3.Distance(NPCRef.transform.position, Chairs[i].transform.position);

                if (distToNpc < minDist)
                {
                    minDist     = distToNpc;
                    targetChair = Chairs[i];
                }
            }

            if (targetChair != null)
            {
                targetChair.AssignFairyAsOccupier(NPCRef);
                NPCRef.NPCAnimController.StartAnimationSequence_ChairFound(targetChair);
            }
            else
            {
                if (OldChair != null)
                {
                    NPCRef.NPCAnimController.StartAnimationSequence_ChairNotFound(OldChair);
                }
            }
        }
        void YieldToPlayer()
        {
            //Player walks away from a chair;
            if (PlayersChair != null && Vector3.Distance(ViveSR_Experience.instance.PlayerHeadCollision.transform.position, PlayersChair.transform.position) > 1)
            {
                PlayersChair.RemoveOccupier();
                PlayersChair = null;
            }

            //player find a closet chair within a distance
            float minDist = 999;
            ViveSR_Experience_Chair targetChair = null;

            for (int i = 0; i < Chairs.Count; i++)
            {
                Vector3 chairPos      = Chairs[i].transform.position;
                Vector3 playerHeadPos = ViveSR_Experience.instance.PlayerHeadCollision.transform.position;

                float dist = Vector3.Distance(playerHeadPos, new Vector3(chairPos.x, playerHeadPos.y, chairPos.z));
                if (dist < minDist)
                {
                    minDist = dist;
                }
                else
                {
                    continue;  // this chair isn't the closest
                }
                if (minDist >= 1f)
                {
                    continue;                // the closest chair is too far
                }
                if (PlayersChair == Chairs[i])
                {
                    continue;                            // player is already using the closet chair.
                }
                targetChair = Chairs[i];
            }

            if (targetChair == null)
            {
                return;
            }

            //NPC on the chair yields to the player
            if (targetChair.OccupyingNPC != null)
            {
                if (targetChair.OccupyingNPC.NPCAnimController.isActing)
                {
                    return;
                }
                if (PlayersChair != null)
                {
                    PlayersChair.RemoveOccupier();
                }

                ViveSR_Experience_NPCAnimationRef NPCToYield = targetChair.OccupyingNPC;
                PlayersChair = targetChair;
                PlayersChair.AssignPlayerAsOccupier();
                NPCToYield.NPCAnimController.Stand(() => AssignClosestChair(NPCToYield, targetChair));
            }
            else
            {
                if (PlayersChair != null)
                {
                    PlayersChair.RemoveOccupier();
                }
                PlayersChair = targetChair;
                PlayersChair.AssignPlayerAsOccupier();
            }
        }