/// <summary> /// Processes a building placement request and adds a new pending building to be placed. /// </summary> /// <param name="buildingPrefab">The Building prefab to be cloned and placed.</param> /// <param name="buildAround">Defines where the building will be placed around.</param> /// <param name="buildAroundRadius">How far should the building from its 'buildAround' position?</param> /// <param name="buildingCenter">The Building center instance that the new building will be placed under.</param> /// <param name="buildAroundDistance">Initial ditsance between the building and its 'buildAround' position.</param> /// <param name="rotate">Can the building be rotated while getting placed?</param> public void OnBuildingPlacementRequest(Building buildingPrefab, GameObject buildAround, float buildAroundRadius, Building buildingCenter, float buildAroundDistance, bool rotate) { //if the building center or the build around object hasn't been specified: if (buildAround == null || buildingCenter == null) { Debug.LogError("Build Around object or Building Center for " + buildingPrefab.GetName() + " hasn't been specified in the Building Placement Request!"); return; } //take resources to place building. gameMgr.ResourceMgr.UpdateRequiredResources(buildingPrefab.GetResources(), false, factionMgr.FactionID); //pick the building's spawn pos: Vector3 buildAroundPos = buildAround.transform.position; //for the sample height method, the last parameter presents the navigation layer mask and 0 stands for the built-in walkable layer where buildings can be placed buildAroundPos.y = gameMgr.TerrainMgr.SampleHeight(buildAround.transform.position, buildAroundRadius, 0) + gameMgr.PlacementMgr.GetBuildingYOffset(); Vector3 buildingSpawnPos = buildAroundPos; buildingSpawnPos.x += buildAroundDistance; //create new instance of building and add it to the pending buildings list: NPCPendingBuilding newPendingBuilding = new NPCPendingBuilding { prefab = buildingPrefab, instance = Instantiate(buildingPrefab.gameObject, buildingSpawnPos, buildingPrefab.transform.rotation).GetComponent <Building>(), buildAroundPos = buildAroundPos, buildAroundDistance = buildAroundDistance, center = buildingCenter, rotate = rotate }; //pick a random starting position for building by randomly rotating it around its build around positio newPendingBuilding.instance.transform.RotateAround(newPendingBuilding.buildAroundPos, Vector3.up, Random.Range(0.0f, 360.0f)); //keep initial rotation (because the RotateAround method will change the building's rotation as well which we do not want) newPendingBuilding.instance.transform.rotation = newPendingBuilding.prefab.transform.rotation; //initialize the building instance for placement: newPendingBuilding.instance.InitPlacementInstance(gameMgr, factionMgr.FactionID, buildingCenter.BorderComp); //we need to hide the building initially, when its turn comes to be placed, appropriate settings will be applied. newPendingBuilding.instance.gameObject.SetActive(false); newPendingBuilding.instance.ToggleModel(false); //Hide the building's model: //Call the start building placement custom event: CustomEvents.OnBuildingStartPlacement(newPendingBuilding.instance); //add the new pending building to the list: pendingBuildings.Push(newPendingBuilding); if (!IsActive) //if building placer was not active (had no building to place) { StartPlacingNextBuilding(); //immediately start placing it. heightCheckCoroutine = HeightCheck(heightCheckReload); //Start the height check coroutine to keep the building always on top of the terrain StartCoroutine(heightCheckCoroutine); } }
/// <summary> /// Starts placing the next building in the pending buildings list: First In, First Out /// </summary> private void StartPlacingNextBuilding() { //if there's no pending building: if (pendingBuildings.Count == 0) { StopCoroutine(heightCheckCoroutine); //stop checking for height return; //stop. } currPendingBuilding = pendingBuildings.Pop(); //get the next pending building to start placing it currPendingBuilding.instance.gameObject.SetActive(true); //activate it //reset building rotation/movement timer: placementMoveTimer = -1; //this will move the building from its initial position in the beginning of the placement process. placementMoveReloadIncCount = 0; placementDelayTimer = placementDelayRange.getRandomValue(); //start the placement delay timer. Activate(); //mark component as active }