/// <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); }
/// <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)); }
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); }