/// <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); } }
public void StartPlacingBuilding(int id) { //make sure the building hasn't reached its limits: if (gameMgr.GetFaction(GameManager.PlayerFactionID).FactionMgr.HasReachedLimit(buildings[id].GetCode(), buildings[id].GetCategory())) { gameMgr.UIMgr.ShowPlayerMessage("Building " + buildings[id].GetName() + " has reached its placement limit", UIManager.MessageTypes.error); return; } //make sure that all required buildings to place this one are here: if (!gameMgr.GetFaction(GameManager.PlayerFactionID).FactionMgr.CheckRequiredBuildings(buildings[id])) { gameMgr.UIMgr.ShowPlayerMessage("Building requirements for " + buildings[id].GetName() + " are missing.", UIManager.MessageTypes.error); return; } //make sure we have enough resources if (!gameMgr.ResourceMgr.HasRequiredResources(buildings[id].GetResources(), GameManager.PlayerFactionID)) { gameMgr.UIMgr.ShowPlayerMessage("Not enough resources to launch task!", UIManager.MessageTypes.error); return; } //Spawn the building for the player to place on the map: currentBuilding = Instantiate(buildings[id].gameObject, new Vector3(0, 0, 0), buildings[id].transform.rotation).GetComponent <Building>(); lastBuildingID = id; //set the last building ID currentBuilding.InitPlacementInstance(gameMgr, GameManager.PlayerFactionID); //initiliaze the placement instance. //Set the position of the new building (and make sure it's on the terrain) if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit)) { Vector3 nextBuildingPos = hit.point; nextBuildingPos.y += buildingYOffset; currentBuilding.transform.position = nextBuildingPos; } gameMgr.SelectionMgr.Box.Disable(); //disable the selection box //Call the start building placement custom event: CustomEvents.OnBuildingStartPlacement(currentBuilding); }