private void SpawnInvestigator(ShuffleSet <GameObject> invShuffle, Vector3 offset)
    {
        var investigator = GameObject.Instantiate(investigatorPrefab, transform);
        var model        = GameObject.Instantiate(invShuffle.Pop(), investigator.modelRoot);

        model.transform.localRotation = Quaternion.identity;
        model.transform.localScale    = Vector3.one;
        model.transform.localPosition = Vector3.zero;

        var startingPoint = houseController.GetStartingPoint();

        investigator.transform.position = startingPoint.position + offset;

        investigator.reactions.Clear();
        var hauntShuffle = new ShuffleSet <HauntType>((HauntType[])Enum.GetValues(typeof(HauntType)));

        for (var index = 0; index < reactionCount; index++)
        {
            if (hauntShuffle.IsEmpty())
            {
                break;
            }
            var reaction = new HauntReaction()
            {
                haunt = HauntType.Unknown
            };
            while (reaction.haunt == HauntType.Unknown || hauntShuffle.IsEmpty())
            {
                reaction.haunt = hauntShuffle.Pop();
            }
            if (reaction.haunt == HauntType.Unknown)
            {
                break;
            }
            reaction.reaction = index < fleeCount ? FearReaction.Flee : FearReaction.Approach;
            investigator.reactions.Add(reaction);
        }

        while (!hauntShuffle.IsEmpty())
        {
            investigator.reactions.Add(new HauntReaction()
            {
                reaction = FearReaction.Ignore, haunt = hauntShuffle.Pop()
            });
        }
        investigator.OnEscape   += HandleEscape;
        investigator.finalOffset = offset;
        investigator.Init(motorController, pathController, hauntController, houseController, fearController, barrierController, actionLock, cameraController);
        investigators.Add(investigator);
    }
    private void StartTheGame()
    {
        actionLock.Lock();
        actionLock.OnUnlock += HandleInvestigatorsPlaced;
        ui.HideWelcome();
        var roomShuffle = new ShuffleSet <Vector2Int>(houseController.GetNonStartingRooms());

        foreach (var investigator in investigators)
        {
            var position = roomShuffle.Pop();
            investigator.GoTo(houseController.TranslateInversePosition(position), () => {
                cameraController.RemoveFollowTillUnlock(investigator.transform);
            });
            cameraController.FollowTillUnlock(investigator.transform);
        }
    }
    public void Start()
    {
        actionLock        = new ActionLockController();
        barrierController = GetComponent <BarrierController>();
        fearController    = GetComponent <FearController>();
        keyBindings       = GetComponent <KeyBindingsController>();
        cameraController  = GetComponent <CameraController>();
        motorController   = GetComponent <KinimaticMotorController>();
        houseController   = GetComponent <HouseController>();
        hauntController   = GetComponent <HauntController>();
        pathController    = GetComponent <NodePathController>();

        barrierController.Init(actionLock);
        fearController.Init();
        keyBindings.Init();
        cameraController.Init(actionLock);
        motorController.Init();
        hauntController.Init(actionLock);
        houseController.Init(motorController, pathController, hauntController, barrierController);

        ui = GameObject.Instantiate(uiPrefab, transform);
        ui.OnEndOfNight += HandleEndOfNight;
        ui.Init(fearController, fearTarget, actionLock);

        houseController.Generate();

        var invShuffle        = new ShuffleSet <GameObject>(investigatorModels);
        var roomShuffle       = new ShuffleSet <Vector2Int>(houseController.GetNonStartingRooms());
        var rotationIncrement = 360.0f / investigatorCount;

        for (int i = 0; i < investigatorCount; i++)
        {
            var rotation = i * rotationIncrement;
            var offset   = Quaternion.Euler(0, rotation, 0) * (Vector3.right * offsetDistance);
            SpawnInvestigator(invShuffle, offset);
        }
        SpawnPlayer();
    }