/// <summary> /// Finds a random location and tries to create a hut at that location. Returns null on failure /// </summary> /// <param name="villageNode"></param> /// <returns></returns> private HutNode TryGenerateHut(VillageNode villageNode) { var villageData = villageNode.VillageData; // Strategy: A hut is spawned in a circular radius around the center of the village. Vector3 hutPosition = UtilityFunctions.GetRandomVector3(villageNode.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 = villageNode.FindAreaIfColliding(dummyArea); HutNode newHutNode; // If no colliding area, then can safely add a new hut if (collidingArea is null) { // Add new hut routine // Location already determined. Set rotation towards center of village Vector3 hutForward = villageNode.transform.position - dummyArea.Center; dummyArea.ObjectTransform.forward = hutForward; string hutName = $"{villageNode.Name}.Hut"; // Instantiation var hutNode = villageNode.CreateResidence <HutNode>(villageData.hutPrefab, dummyArea.Center, dummyArea.ObjectTransform.rotation, residenceName: hutName); newHutNode = hutNode; } else { // If snapping process is success, add Hut to this TiledArea var colldingTiledArea = collidingArea.TiledArea; // Snap to nearest empty space from colliding hut var newPosition = colldingTiledArea.SnapToClosestOpenSpace(dummyArea); dummyArea.ObjectTransform.position = newPosition; // Check if resultant open space is colliding with anything else var newCollidingArea = villageNode.FindAreaIfColliding(dummyArea); if (newCollidingArea is null) { // Add new hut routine string hutName = $"{villageNode.Name}.Hut"; // Instantiation var hutNode = villageNode.CreateResidence <HutNode>(villageData.hutPrefab, dummyArea.Center, dummyArea.ObjectTransform.rotation, parentTiledArea: colldingTiledArea, residenceName: hutName); newHutNode = hutNode; } else { newHutNode = null; } } Destroy(dummyObj); return(newHutNode); }
public void DebugSnapToAndConstructHut(Transform dummyObjTransform, IArea collidingArea) { var tiledArea = collidingArea.TiledArea; dummyObjTransform.rotation = tiledArea.centerTransform.rotation; var tempArea = new TempArea(dummyObjTransform, hutDimensions); var newPosition = tiledArea.SnapToClosestOpenSpace(tempArea); dummyObjTransform.position = newPosition; var newCollidingArea = FindAreaIfWithinAny(newPosition); Debug.Log($"Is snapped area part of a residence area? {!(newCollidingArea is null)}"); var hutRotation = dummyObjTransform.rotation; var hutPosition = dummyObjTransform.position; // Instantiation HutNode hutNode = CreateResidence <HutNode>(VillageData.hutPrefab, hutPosition, hutRotation, parentTiledArea: tiledArea, residenceName: defaultHutName); // TODO: Replace with sophisticated initialization hutNode.SetUpArea(hutNode.transform, hutDimensions); tiledArea.AddArea(hutNode); }
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); }