- Home /
[Solved]How to destroy a turret in Tower Defense game
Hello guys, Im in trouble with the code used to destroy turret in my tower defense (TD) game. In normal TD game, we can only place turrets to shoot enemy, and upgrade them. These things I solved already, now I want enemy be able to shoot my turrets and destroy turrets, but I can't find the solution for my code. This is my code for placing turret and user interface:
//UI vars
var placementPlanesRoot : Transform;
var hoverMat : Material;
var placementLayerMask : LayerMask;
private var originalMat : Material;
private var lastHitObj : GameObject;
var allStructures : GameObject[];
var allStructureTextures: Texture[];
var structureIndex : int;
static var soundEnable : boolean = true;
//turrets cost
var turretCost : int[];
//GUISkin
var style1: GUIStyle;
var style2: GUIStyle;//blue, use when enough cash
var style3: GUIStyle;//red, use when out of cash
private var topPanelRect: Rect = new Rect(-3, -3, Screen.width+6, 28);
private var bottomPanelRect: Rect;
private var buildListRect: Rect;
private var towerUIRect: Rect;
//upgrade vars
private var chosenPlane : PlacementPlane;
private var structureToUpgrade : TurretBase;
private var upgradeStructure : GameObject;
private var upgradeCost : int;
var totalUpgradeBoxOpen : boolean = false;
var canTotalUpgrade : boolean = false;
var sellBoxOpen : boolean = false;
var canSell : boolean = false;
var upgradeTextures : Texture[];
var levelChange: LevelChange;
function Start () {
levelChange = GameObject.FindWithTag("LevelChange").GetComponent(LevelChange);
//Calculate rect for buildList
var width: int = 50;
var height: int = 50;
var x: int = 0;
var y: int = Screen.height-height-6-bottomPanelRect.height;
var menuLength: int = (allStructures.Length)*(width+15);
buildListRect= Rect(x, y, menuLength+3, height+10);
structureIndex = 0;
}
function Update () {
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if(Physics.Raycast(ray,hit,1000, placementLayerMask )){
if (lastHitObj) {
lastHitObj.renderer.material = originalMat;
}
lastHitObj = hit.collider.gameObject;
originalMat = lastHitObj.renderer.material;
lastHitObj.renderer.material = hoverMat;
}
else {
if(lastHitObj) {
lastHitObj.renderer.material = originalMat;
lastHitObj = null;
}
}
if (Input.GetMouseButtonDown(0) && lastHitObj && !totalUpgradeBoxOpen && !sellBoxOpen)
{
chosenPlane = lastHitObj.GetComponent(PlacementPlane);
if (chosenPlane.isOpen && turretCost[structureIndex]<= LevelChange.cashCount) {
var newStructure : GameObject = Instantiate(allStructures[structureIndex],lastHitObj.transform.position,Quaternion.identity);
chosenPlane.buildStructure = newStructure;
chosenPlane.isOpen = false;
LevelChange.cashCount-= turretCost[structureIndex];
}
else if (chosenPlane.buildStructure != null) {
//ShowTotalUpgradeBox();
canTotalUpgrade = true;
canSell = false;
}
}
}
function ShowTotalUpgradeBox() {
var upOption : int;
var sellOption : int;
structureToUpgrade = chosenPlane.buildStructure.GetComponent(TurretBase);
upgradeStructure = structureToUpgrade.Upgrade;
var x:int = Screen.width/2; var y:int = Screen.height/2;
if (upgradeStructure != null){
totalUpgradeBoxOpen = true; sellBoxOpen = false;
upgradeCost = structureToUpgrade.theUpgradeCost;
for (j = 0;j<3;j++) {
var upgradeContent : GUIContent = GUIContent(upgradeTextures[j], j.ToString());
if (GUI.Button(new Rect (x-64,y,64,64), upgradeContent)){
upOption = j;
if (upOption == 0) {Up();}
if (upOption == 1) {Sell();}
if (upOption == 2) {Cancel();}
}
else x+=64;
}
}
if (upgradeStructure == null) {
totalUpgradeBoxOpen = false; sellBoxOpen = true;
for(k=0;k<2;k++) {
var sellContent : GUIContent = GUIContent(upgradeTextures[k+1], k.ToString());
if (GUI.Button(new Rect (x-64,y,64,64), sellContent)){
sellOption = k;
if (sellOption == 0) {Sell();}
if (sellOption == 1) {Cancel();}
}
else x+=64;
}
}
}
function Up() {
if (LevelChange.cashCount >= upgradeCost) {
var spawnPos = structureToUpgrade.transform.position;
var spawnRot = structureToUpgrade.transform.rotation;
Destroy(structureToUpgrade.gameObject);
var newStructure : GameObject = Instantiate(upgradeStructure,spawnPos,spawnRot);
chosenPlane.buildStructure = newStructure;
LevelChange.cashCount-= upgradeCost;
totalUpgradeBoxOpen = false;
canTotalUpgrade = false;
sellBoxOpen = false;
canSell = false;
}
}
In this code, I deleted some functions which is not relevant. And the class "TurretBase" includes:
Upgrade: GameObject
theUpgradeCose : int
health, maxHealth : int
Class PlacementPlane includes:
buildStructure : GameObject
isOpen : boolean
My idea is that: when we click on the plane to place a turret, the variable "chosenPlane" will hold this plane, we can only place a turret to a plane which has "isOpen" is true and "buildStructure" is null.
Now when a enemy destroy a turret, I don't know how to change the variable "isOpen" and "buildStructure" of the plane where the turret was destroyed because I dont have any variables to control all the planes, I tried some ways but they didnt work. Anyone can give me some ideas about this?
Thank you very much and sorry about my bad English.
Answer by Xtro · Jul 30, 2013 at 06:07 PM
You have two options..
1) You can search the turret in the map (the plane array in your case. I assume your planes are registered in an array or something. If not, you can get all the planes by doing a Tag search for all object in the scene. You should set a tag to all your planes to be able to do that)
2) You can implement a link to the plane cell in the turret script. When you add the turret to the plane, turret also knows which plane it belongs. I's prefer this method.
So add method can be something like that.
void AddTurretToPlane(Turret t, Plane p){
p.Structure = t;
t.Plane = p;
}
The remove (destroy) function should be like that (You call this after you find the plane)
void DestroyTurretOnPlane(Plane p){
Destroy(p.buildStructure.gameobject)
p.buildStructure = null;
p.isOpen = true;
}
Does that work for you ?
Hello Xtro, can you help me one more time? All things seem to work well but the function DestroyTurretOnPlane, it said Destroying assets is not permitted to avoid data loss. If you really want to remove an asset use DestroyImmediate (theObject, true); I also change to DestroyImmediate but it said use Destroy ins$$anonymous$$d, I dont know what cause this problem?
Of-course the refinement of the solution is required. If you think you get the idea of the solution, you can mark my post as an answer to your question. Thank you too :)
Oops, I edited my comment so maybe you don't see my question :)Wait for your answer soon
I thought buildStructure was the gameobject you created as a turret on the plane, so I tried to destroy it.
Is it a link to a prefab in your project structure??? As far as I see from the error you talk about, you are trying to destroy an asset, not a game object.
How do you store the Turret gameobject(in the scene) into a plane script ?
Answer by dzuncoi · Jul 30, 2013 at 07:03 PM
Yes, all my planes have a tag and a layer too. I also think about your second method but my problem is that I cannot change 2 variables "isOpen" -> true and "buildStructure" -> null of that plane so that we can place another turret after that.
you shouldn't add an answer. If you need more help, please put comment under my answer.