Пример #1
0
    /// <summary>
    /// Instantiate Residence Node, with the given parameters. If no TiledArea is specified, a new TiledArea is created and added to the region. Default rotation is identity. See overload including rotation
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="residencePrefab"></param>
    /// <param name="position"></param>
    /// <param name="rotation"></param>
    /// <param name="parentTiledArea"></param>
    /// <param name="residenceName"></param>
    /// <returns></returns>
    public T CreateResidence <T>(GameObject residencePrefab, Vector3 position, Quaternion rotation, TiledArea parentTiledArea = null, string residenceName = "defaultResidence") where T : MonoBehaviour, INode, IResidence, IArea
    {
        GameObject newResidence = Instantiate(residencePrefab, position, rotation);

        UtilityFunctions.PutObjectOnGround(newResidence.transform);

        T residenceNode = newResidence.AddComponent <T>();

        residenceNode.SetUp(residenceName);
        residenceNode.transform.parent = transform;

        residenceNode.SetUpResidence(this, new List <INode>());
        // TODO: Generalise hut dimensions using data of the hut prefab itself
        residenceNode.SetUpArea(residenceNode.transform, hutDimensions);
        AddLink(residenceNode);
        Residences.Add(residenceNode);
        Areas.Add(residenceNode);
        VillageData.SetHutCount(VillageData.HutCount + 1);
        // If tiled area was not provided, then create a new one
        if (parentTiledArea is null)
        {
            var newTiledArea = new TiledArea(residenceNode);
            TiledAreas.Add(newTiledArea);
        }
        else
        {
            parentTiledArea.AddArea(residenceNode);
        }

        return(residenceNode);
    }
Пример #2
0
 /// <summary>
 /// Instantiate Residence Node, with the given parameters. If no TiledArea is specified, a new TiledArea is created and added to the region.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="residencePrefab"></param>
 /// <param name="position"></param>
 /// <param name="parentTiledArea"></param>
 /// <param name="residenceName"></param>
 /// <returns></returns>
 public T CreateResidence <T>(GameObject residencePrefab, Vector3 position, TiledArea parentTiledArea = null, string residenceName = "defaultResidence") where T : MonoBehaviour, INode, IResidence, IArea
 {
     return(CreateResidence <T>(residencePrefab, position, Quaternion.identity, parentTiledArea, residenceName));
 }
Пример #3
0
    void GenerateHut(int numberOfResidents)
    {
        TiledArea newTiledArea = null;
        // Strategy: A hut is spawned in a circular radius around the center of the village.
        Vector3 hutPosition = UtilityFunctions.GetRandomVector3(transform.position, VillageData.hutSpawnRange);

        // Ensure no blockage by existing huts
        var dummyObj = new GameObject("Dummy Object");

        dummyObj.transform.position = hutPosition;
        var dummyArea = new TempArea(dummyObj.transform, hutDimensions);

        var collidingArea = FindAreaIfColliding(dummyArea);

        bool snappingOccurred = false;

        while (!(collidingArea is null))
        {
            var collidingTiledArea = collidingArea.TiledArea;
            hutPosition = collidingTiledArea.SnapToClosestOpenSpace(dummyArea);
            dummyObj.transform.position = hutPosition;
            collidingArea = FindAreaIfColliding(dummyArea);
            if (collidingArea is null)
            {
                snappingOccurred = true;
                newTiledArea     = collidingTiledArea;
                break;
            }
            hutPosition = UtilityFunctions.GetRandomVector3(transform.position, VillageData.hutSpawnRange);
            dummyObj.transform.position = hutPosition;
            collidingArea = FindAreaIfColliding(dummyArea);
        }

        // Checked for collision with existing hut

        // Orientation of the hut will be towards village center
        // But, if adding to an existing TiledArea, use that orientation instead

        if (snappingOccurred)
        {
            dummyObj.transform.rotation = newTiledArea.centerTransform.rotation;
        }
        else
        {
            var hutForward = transform.position - hutPosition;
            // Allignment
            dummyObj.transform.forward = hutForward;
        }

        // Instantiation
        HutNode hutNode = CreateResidence <HutNode>(VillageData.hutPrefab, hutPosition, dummyObj.transform.rotation, parentTiledArea: newTiledArea, residenceName: defaultHutName);

        Destroy(dummyObj);

        // TODO: Replace with sophisticated initialization


        // Pick a random subset of unhoused residents.
        var newResidents = RandomTools.RandomSubset(UnhousedVillagers.ToList(), numberOfResidents);

        hutNode.AddResidents(newResidents.Cast <INode>().ToList());
        hutNode.SetUpArea(hutNode.transform, hutDimensions);
        // Snap villagers to near the hut. Also rename them
        foreach (var villager in newResidents)
        {
            // spawn villager close to the hut
            var villagerSpawnDimensions = new Vector2(hutDimensions.x, hutDimensions.z);
            // spawn villager in the 2-D rectangular boundary around the hut, in the xz plane
            var villagerSpawnPosition = UtilityFunctions.GetRandomBoundaryPoint(villagerSpawnDimensions);
            // The rectangular boundary is oriented using transform.right and transform.forward
            villager.transform.position = hutNode.transform.position + hutNode.transform.forward * villagerSpawnPosition.x + hutNode.transform.right * villagerSpawnPosition.y;
            UtilityFunctions.PutObjectOnGround(villager.transform);
            // TODO set up regulated name/gameObject name schemes, so that gameObject name and actual name always match
            villager.gameObject.name = $"{villager.Name}";
        }

        UnhousedVillagers.ExceptWith(newResidents);
    }