- Home /
constructing buildings rts style.
currently i have a co routine that starts after i lock the position of the building prefab. this coroutine is attached to my builder unit which simulates or "fakes" constructing a building. i have a delegate that i pass to my gui system ; which on button click does the entire "action" of construction.
problem:
the coroutine keeps starting over and over again for some reason. (Final Placement Method).
Construction Script:
public class Construction : MonoBehaviour {
public GameObject [] buildings;
public Action.myActions constructingBarr;
public Action.myActions constructingBase;
public Color MatColor {
get {
return materialColour;
}
set {
myRenderer.material.color
= value;
}
}
public bool IsPlaced {
get {
return isPlaced;
}
set {
isPlaced = value;
if(isPlaced!=false) {
StopCoroutine ("ConstructBuilding");
StartCoroutine ("ConstructBuilding");
}
}
}
private bool isPlaced;
private Builder myBuilder;
private Color materialColour;
private Renderer myRenderer;
private MeshRenderer myMesh;
private Transform currentBuilding;
private void Start() {
myBuilder = GetComponent <Builder> ();
myMesh = GetComponentInChildren <MeshRenderer> ();
}
private void FetchRenderer() {
try {
myRenderer = currentBuilding.
GetComponentInChildren<Renderer> ();
}catch {};
}
private void Update() {
LocatingBuildingPos ();
Debug.Log (isPlaced);
}
private void SaveOrginalMatColour () {
try{
materialColour =
myRenderer.material.color;
}catch {};
}
public bool InstantiateBuilding(GameObject building) {
currentBuilding = ((GameObject)Instantiate
(building)).transform;
FetchRenderer ();
return IsPlaced = !true;
}
public void CreateBase() {
InstantiateBuilding (buildings [1]);
SaveOrginalMatColour ();
}
public void CreateBarracks() {
InstantiateBuilding (buildings [0]);
SaveOrginalMatColour ();
}
public void LocatingBuildingPos() {
if (!IsPlaced) {
try {
var cameraYPos = Camera.main.transform.
position.y;
var mousePos = new Vector3
(Input.mousePosition.x,
Input.mousePosition.y,
cameraYPos);
var mousePosWorld =
Camera.main.ScreenToWorldPoint (mousePos);
currentBuilding.transform.position
= new Vector3 (mousePosWorld.x, 0,
mousePosWorld.z);
}
catch {};
}
FinalPlacement ();
}
IEnumerator ConstructBuilding () {
Vector3 previousBuilderPos = transform.position;
Vector3 buildingPos = currentBuilding.
transform.position;
SetConstructionTarget (buildingPos);
yield return new WaitForSeconds (4f);
IsNotConstructing (false);
MatColor = Color.red;
yield return new WaitForSeconds (4f);
MatColor = Color.yellow;
yield return new WaitForSeconds (8f);
MatColor = Color.green;
myBuilder.Target = previousBuilderPos;
yield return new WaitForSeconds (3f);
myRenderer.material.color = MatColor;
IsNotConstructing (true);
Debug.Log ("Construction Complete !");
}
public void IsNotConstructing(bool value) {
myMesh.enabled = value;
gameObject.collider.enabled = value;
currentBuilding.collider.enabled = value;
}
public void SetConstructionTarget(Vector3 target) {
myBuilder.Target = target;
}
public bool FinalPlacement () {
if (Input.GetMouseButtonDown (0)) {
return IsPlaced = !false;
} else {
return !IsPlaced;
}
}
private void OnEnable() {
constructingBarr += CreateBarracks;
constructingBase += CreateBase;
//constructingBarr += myEvent(buildings[1]);
//constructingBase += myEvent(buildings[0]);
}
private void OnDisable() {
constructingBarr -= CreateBarracks;
constructingBase -= CreateBase;
//constructingBarr -= myEvent(buildings[1]);
//constructingBase -= myEvent(buildings[0]);
}
}
BTW we really didn't need the entire class to solve this problem. The following would have been sufficient and got you better and quicker feedback
private bool isPlaced;
private void Update() {
LocatingBuildingPos ();
Debug.Log (isPlaced);
}
public void LocatingBuildingPos() {
if (!IsPlaced) {
// Do some stuff
}
FinalPlacement ();
}
public bool FinalPlacement () {
if (Input.Get$$anonymous$$ouseButtonDown (0)) {
return IsPlaced = !false;
} else {
return !IsPlaced;
}
}
thank you. do u $$anonymous$$d checking my other question ? http://answers.unity3d.com/questions/710815/setting-a-target-for-projectile.html
Answer by Em3rgency · May 19, 2014 at 12:38 PM
LocatingBuildingPos() is called every frame by Update(). FinalPlacement() is called every time LocatingBuildingPos() is called, because its outside the if statement.
So... FinalPlacement() is called every frame. You wrote your code that way.
Final placement locks the position of the building. where should i put it to avoid the calling everyframe
$$anonymous$$ost of the time you put a function inside an if with a bool to indicate if you want to call it.
// Set this to true when the conditions are satisfied to call final placement
private bool IWantToCallFinalPlacement;
if(IWantToCallFinalPlacement){
FinalPlacement();
IWantToCallFinalPlacement = false;
}
Also your return code for FinalPlacement() is weird.
basically what i am want to do is this:
-if i press right click -lock the position of the building where the mouse is and start construction.
is there another way besides that flag?
also can you take a look at my other question?
http://answers.unity3d.com/questions/710815/setting-a-target-for-projectile.html
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Displaying buildable area as an overlay on terrain 0 Answers
Lerp in Coroutine (Crazy Behavior) 2 Answers