Beispiel #1
0
 public void RemoveHouse(VillageHouseData house)
 {
     VillageSize--;
     VillageHouses.Remove(house);
     MonoBehaviour.Destroy(house.gameObject);
 }
    IEnumerator GenerateVillages(ChunkData chunkData)
    {
        float maxVillageDistance  = ProceduralTerrain.Current.TerrainHouseData.MaxDistanceOfVillage;
        int   minHousesPerVillage = ProceduralTerrain.Current.TerrainHouseData.MaxHousesPerVillage;
        int   maxHousesPerVillage = ProceduralTerrain.Current.TerrainHouseData.MinHousesPerVillage;

        //List to store individual villages
        List <VillageData> villageList = new List <VillageData>();
        //List to store objects that need deleting
        List <VillageData> villagesToDelete = new List <VillageData>();

        //Go through house, check through all other houses, if within maxVillageDistance, add them to village
        foreach (VillageHouseData house1 in chunkData.VillageHouseList)
        {
            //If already has a village, move to next house
            if (house1.Village != null)
            {
                continue;
            }

            foreach (VillageHouseData house2 in chunkData.VillageHouseList)
            {
                //Make sure not comparing to self
                if (house1 == house2)
                {
                    continue;
                }

                //House2 should not already have a village
                if (house2.Village != null)
                {
                    continue;
                }

                //If house1 doesnt have a village, create one
                if (house1.Village == null)
                {
                    VillageData thisVillage = new VillageData();
                    thisVillage.AddHouse(house1);
                    villageList.Add(thisVillage);
                }

                //If distance been house1 and house2 is less than the max village distance
                if (Vector3.Distance(house1.transform.position, house2.transform.position) < maxVillageDistance)
                {
                    //Assign house2 to village
                    house1.Village.AddHouse(house2);
                }
            }
        }

        //Assign village list to chunk
        chunkData.VillageList = villageList;

        //If village has less than required houses, delete it
        foreach (VillageData village in chunkData.VillageList)
        {
            if (village.VillageSize < minHousesPerVillage)
            {
                villagesToDelete.Add(village);
            }
        }

        for (int i = 0; i < villagesToDelete.Count; i++)
        {
            villageList.Remove(villagesToDelete[i]);
            villagesToDelete[i].DestroyVillage();
        }
        villagesToDelete.Clear();

        //Get middle point of villages
        Vector3 center = Vector3.zero;

        foreach (VillageData village in chunkData.VillageList)
        {
            foreach (VillageHouseData house in village.VillageHouses)
            {
                center += house.transform.position;
            }

            //Find average of all house positions
            center /= village.VillageSize;

            village.CenterPosition = center;
        }

        //If village has more than max number of houses, reduce amount of houses by removing the houses furthest from the center
        foreach (VillageData village in chunkData.VillageList)
        {
            //Keep removing houses until there is less than the max amount
            while (village.VillageSize > maxHousesPerVillage)
            {
                VillageHouseData furthestHouse    = village.VillageHouses[0];
                float            furthestDistance = float.MinValue;

                foreach (VillageHouseData house in village.VillageHouses)
                {
                    if (Vector3.Distance(house.transform.position, village.CenterPosition) > furthestDistance)
                    {
                        furthestDistance = Vector3.Distance(house.transform.position, village.CenterPosition);
                        furthestHouse    = house;
                    }
                }

                village.RemoveHouse(furthestHouse);
            }
        }

        //Find closest house to middle point of village and replace it
        foreach (VillageData village in chunkData.VillageList)
        {
            //Initialise
            VillageHouseData closestHouse    = village.VillageHouses[0];
            float            closestDistance = float.MaxValue;
            foreach (VillageHouseData house in village.VillageHouses)
            {
                if (Vector3.Distance(house.transform.position, village.CenterPosition) < closestDistance)
                {
                    closestDistance = Vector3.Distance(house.transform.position, village.CenterPosition);
                    closestHouse    = house;
                }
            }
            //Set center position for vilalge for this chunk
            village.LocalChunkCenterPosition = closestHouse.ChunkLocalPosition;
            //Delete closest house
            village.RemoveHouse(closestHouse);
            //Spawn village center prefab at location of closest house
            GameObject newCenter = Instantiate(ProceduralTerrain.Current.TerrainHouseData.VillageCenterPrefab.ObjectPrefab, closestHouse.transform.position, Quaternion.identity, closestHouse.transform.parent);
            village.VillageCenter = newCenter;
            chunkData.VillageCenterList.Add(newCenter);

            //Parent objects
            GameObject villageParent = new GameObject();
            villageParent.transform.SetParent(village.VillageCenter.transform.parent);
            villageParent.name = "Village";
            foreach (VillageHouseData house in village.VillageHouses)
            {
                house.transform.SetParent(villageParent.transform);
            }
            village.VillageCenter.transform.SetParent(villageParent.transform);
        }

        //Rotate houses to face village center
        foreach (VillageData village in chunkData.VillageList)
        {
            foreach (VillageHouseData house in village.VillageHouses)
            {
                house.transform.LookAt(village.VillageCenter.transform);
                //Make house flat, rather than tilted
                house.transform.localEulerAngles = new Vector3(0, house.transform.localEulerAngles.y, house.transform.localEulerAngles.z);
            }
        }

        //Make sure trees arent placed in village area
        int clearAreaRadius = ProceduralTerrain.Current.TerrainHouseData.ClearAreaRadiusAroundBuildings;

        foreach (VillageData village in chunkData.VillageList)
        {
            bool hasClearedAroundCenter = false;
            foreach (VillageHouseData house in village.VillageHouses)
            {
                Vector2 centerPosition = house.ChunkLocalPosition;
                //If the area around the village center hasnt been cleared yet, clear it
                if (!hasClearedAroundCenter)
                {
                    centerPosition = village.LocalChunkCenterPosition;
                    PreventSpawningInArea(chunkData, centerPosition, clearAreaRadius);
                    //Set centerPosition back to this houses position
                    centerPosition = house.ChunkLocalPosition;
                }
                //Prevent spawning of trees around this house
                PreventSpawningInArea(chunkData, centerPosition, clearAreaRadius);
            }
        }

        yield return(null);
    }
Beispiel #3
0
 public void AddHouse(VillageHouseData house)
 {
     house.AssignVillage(this);
     VillageHouses.Add(house);
     VillageSize++;
 }