Defense Weapons

👍

Reminder - Keep Daily Backups

When working on a strategy game with a kit as big as the Complete Kit - always keep a working daily backup! Save yourself the trouble of rolling-back changes and losing work.

What are defense weapons?

When playing battle strategy games you'll always be able to build some sort of structure that defends your village or base from attacking players. In this case we've added a category in the store for you to place these defensive buildings.

The demo includes a few of these general buildings like the Archer tower or the Cannon. During gameplay they don't have much purpose but when you're attacking other players or other players are attacking your base - they play a huge role in defending your resources from being stolen.

686

Click to view larger.

Battle defense

During battle, defensive weapon buildings are the only ones which can actively protect your village and destroy enemy troops.

589

Battle defense preview.

Shop Menu

Here's a screenshot of the shop menu for the defensive weapon structures.

636

Click to view larger.

There are six examples included in the game, however the three main examples we recommend learning from are the Cannon, Archer Tower, and Catapult.

748

Click to view larger.

Where to find the defense store menu in Unity?

Open the game scene hierarchy and locate the ScrollViewDefense in UIAnchor > Anchor - Center > Shop > Main. Look at the below screenshot.

266

UIAnchor. Click to view larger.

Store Item UI

All of the store details seen in the below screenshot are taken from the XML/Weapons.xml file and loaded by Scripts/Creators/BaseCreator.cs (details below on what part of the script does this)

Although the screenshot below is for another building type in the store, the details apply to all buildings including defensive weapons since the store uses centralized BaseCreator.cs script.

483

Breakdown of the information shown to players in the store.

From Image AboveDescription
Item NameThis is the Name variable from XML/Weapons.xml
Time to Build (in Minutes)The TimeToBuild variable (in minutes) from Weapons.xml. How long the structure will take to to be created.
# Build / Level LimitThe number of this structure already created versus the number limited by their level in XML/EvolutionBuildings.xml. See Gameplay > XP and Levels documentation for details)
Currency CostThe Price variable from XML/Weapons.xml
Currency TypeThe Currency variable from XML/Weapons.xml (Either Gold, Mana, or Gems) You could change this to whatever currency you will have in your game and also add additional currencies.
View DescriptionShows the Description text variable from XML/Weapons.xml
Prefab ImageThe prefab image which you can edit from the UIAnchor: Center shop main menu. More details on how to change this under the Buildings > Part 2: Customize Menus page of the documentation

Weapons.xml Example

Here's an example of the simple cannon weapon in the XML. The Scripts/Creators/BaseCreator.cs will use these settings.

<Weapon>
	<Name>Cannon</Name>	
    <!--  name displayed in the store -->		
  
	<Description>Heavy Artilery.</Description>
    <!--  Description displayed in the store -->		
								
	<Currency>Gold</Currency>	
    <!-- Gold, Mana, or Crystals purchase currency -->		
  		
	<Price>100</Price>
  <!-- amount of resource necessary to pay for the building -->						
			
	<TimeToBuild>30</TimeToBuild>
  <!-- the time (in minutes) needed to create the building -->

	<Life>200</Life>
  <!-- hitpoints of the building -->
  
	<XpAward>100</XpAward>
  <!-- experience awarded for the completion of an object -->					
  
	<FireRate>2</FireRate>
  <!-- shots per second -->
  <!-- for version 6.0 this is defaulted to 1 shot per 2 seconds in Scripts/Weapons/TurrentControllerBase.cs where you see fireRate = 2.0f -->
</Weapon>

There are other values shown in the XML provided with the kit but we've just included these as a template for developers to work with.

A closer look at weapon XML

If you look closely in the above XML, you'll see the building costs 100 of of the Gold currency. You could use whatever currency you want in your game, in the demo we have two placeholders called Gold and Mana. (Plus one rare currency called Crystal Gems)

<Currency>Gold</Currency>		
	<Price>100</Price>

In addition, you'll notice that like other buildings it has an HP value for battle and a time to build (measured in minutes) for construction plus a 100 XP award if the player builds this structure.

<TimeToBuild>30</TimeToBuild>
	<Life>200</Life>
	<XpAward>100</XpAward>

And lastly, specific for weapons there is a firerate item in the XML but as of now this is not used in the TurrentControllerBase.cs script.

<FireRate>2</FireRate>

The Scripts/Weapons/TurrentControllerBase.cs script sets the FireRate for all weapons to a default of 1 shot every 2 seconds for developer testing of the kit.

To activate the FireRate XML object seen above, you'll need to edit the TurrentControllerBase.cs script to read and use the XML value rather than the default set near the top of the TurrentControllerBase.cs script as seen in the following excerpt:

// Bullet shooting rate
  // 2.0f = one shot every 2 seconds
  // You could also try 1.3f = one shot every 1.3 seconds 
	protected float 
		fireRate = 2.0f,
		elapsedTime;

Additional expansions

There are other XML expansions we've prepared for developers but as of version 6.0 these are read by Scripts/Creators/BaseCreator.cs but are not scripted for use yet in either the Scripts/Weapons TurrentControllerBase.cs or WeaponAnimationController.cs

<DamagePerSecond>25</DamagePerSecond>	
				<!-- Damange per second, alternative idea to fireRate -->					
		<Range>50</Range>
				<!-- Range of the attack object -->
		<DamageType>Area</DamageType>		
				<!-- Single target, Area splash-->
		<TargetType>Ground</TargetType>
				<!-- Ground, Air, Dual -->
		<PreferredTarget>Any</PreferredTarget>		
				<!-- Type of specific units -->
		<DamageBonus>0</DamageBonus>			
				<!-- Single target, Area splash-->

BaseCreator.cs - Where the XML is loaded into

In Scripts/Creators/BaseCreator.cs the building data from your XML file (seen above) is loaded using a common system for all the buildings like resource buildings, defense buildings, walls, decorations, and other buildings. Here's an excerpt from BaseCreator.cs of the XML data load:

//reads structures XML
protected void GetWeaponsXML()//reads buildings XML
	{
		XmlDocument xmlDoc = new XmlDocument(); 
		xmlDoc.LoadXml(StructuresXML.text); 
		XmlNodeList structureList = xmlDoc.GetElementsByTagName(structureXMLTag);//"Wall"

		foreach (XmlNode structureInfo in structureList)
		{
			XmlNodeList structureContent = structureInfo.ChildNodes;	
			dictionary = new Dictionary<string, string>();

			foreach (XmlNode structureItem in structureContent) // levels itens nodes.
			{
			
      // For each of the XML values, it stores the information
      // to be used later in BaseCreator.cs
				if(structureItem.Name == "Name")
				{
					dictionary.Add("Name",structureItem.InnerText); // put this in the dictionary.
				}
				if(structureItem.Name == "Description")
				{
					dictionary.Add("Description",structureItem.InnerText); // put this in the dictionary.
				}
				if(structureItem.Name == "Currency")
				{
					dictionary.Add("Currency",structureItem.InnerText);
				}
				if(structureItem.Name == "Price")
				{
					dictionary.Add("Price",structureItem.InnerText);
				}	
				if(structureItem.Name == "TimeToBuild")
				{
					dictionary.Add("TimeToBuild",structureItem.InnerText);
				}	
				if(structureItem.Name == "Life")
				{
					dictionary.Add("Life",structureItem.InnerText);
				}


				if(structureItem.Name == "XpAward")
				{
					dictionary.Add("XpAward",structureItem.InnerText); 
				}
        
      // The following two are not currently used in the demo
      // but have been provided for developers wishing to expand
      // their builings with upgrades. Additional scripting required.
        
				if(structureItem.Name == "Range")
				{
					dictionary.Add("Range",structureItem.InnerText);
				}

				if(structureItem.Name == "FireRate")
				{
					dictionary.Add("FireRate",structureItem.InnerText);
				}

				if(structureItem.Name == "DamageType")
				{
					dictionary.Add("DamageType",structureItem.InnerText);
				}
				if(structureItem.Name == "TargetType")
				{
					dictionary.Add("TargetType",structureItem.InnerText);
				}
				if(structureItem.Name == "PreferredTarget")
				{
					dictionary.Add("PreferredTarget",structureItem.InnerText);
				}
        
				if(structureItem.Name == "DamagePerSecond")
				{
					dictionary.Add("DamagePerSecond",structureItem.InnerText);
				}

				if(structureItem.Name == "DamageBonus")
				{
					dictionary.Add("DamageBonus",structureItem.InnerText);
				}
        
				if(structureItem.Name == "Upgrades")
				{
					dictionary.Add("Upgrades",structureItem.InnerText); 
				}
				if(structureItem.Name == "UpRatio")
				{
					dictionary.Add("UpRatio",structureItem.InnerText); 
				}
			}
			structures.Add(dictionary);
		}
	}

When the data is loaded, the store panels are updated with the appropriate information.

Construction limits with XP levels

Read the Gameplay > XP and Levels documentation page for more details about how the XML/EvolutionBuildings.xml file limits the number of certain Building.xml structures per level. Although the following example is not a defensive weapon, it's a good example to show since the store elements all act the same.

For example, game players could have a maximum of two gold mines at level one until the player reaches level two, in which the maximum increases to five (or whatever value you choose -- read XP and Levels documentation for more details)

158

1/2 gold mines built. Maximum not reached.

161

2/2 maximum reached, can't build more

This is relevant to mention now because the menu items are greyed out for buildings that the player can no longer build until they increase their base level through other ways of gaining XP. The function UpdateLabelStats()

// Excerpt from UpdateLabelStats()
// Check if the player is looking at items in the store that
// would exceed their XP level limits
buildingAllowed =(allowedStructures[i]-existingStructures[i]>0);

// Set the store item's label data
NameLbs[i].text = structures [i] ["Name"];
TimeLbs[i].text = structures [i] ["TimeToBuild"];

// Quantity - for example, 2/2 means they have reached the maximum of 2
QuantityLbs[i].text = existingStructures[i].ToString()+"/"+allowedStructures[i].ToString();
PriceLbs[i].text = structures [i] ["Price"];


// If they can build, set the normal store item background and label colors
if(buildingAllowed)
{
	NicheSprites[i].spriteName = "stone_niche";
	PortraitSprites[i].atlas = Portraits;

	NameLbs[i].color = brown;
	TimeLbs[i].color = brown;
	QuantityLbs[i].color = brown;
	PriceLbs[i].color = brown;
  
  
// If the player can no longer build this item, grey out the item in the store
} else {
	NicheSprites[i].spriteName = "stone_niche_bw";
	PortraitSprites[i].atlas = PortraitsBW;

	NameLbs[i].color = black;
	TimeLbs[i].color = black;
	QuantityLbs[i].color = black;
	PriceLbs[i].color = black;
}

What happens when the buy button is clicked for a store item?

When the player clicks one of the buttons to buy a building in the store, first one of the building functions is triggered, like this example below:

//receive a NGUI button message to build
	public void OnBuild0()	 { currentSelection=0; 	Verify(); }
//when a building construction menu button is pressed

Verify() is run shortly after, which initiates the conditions checking to see if the player actually can build what they want to build.

private void Verify()
	{
		if (isArray[currentSelection] == 0) 
		{			
			VerifyConditions ();
		}
		else 
		{			
			isField = true;
			drawingField = true;
			Delay ();
			VerifyConditions ();
		}
	}

VerifyConditions()

Can the player build this structure? In Scripts/Creators/BaseCreator.cs the VerifyConditions() script takes over once the store button has been pushed to determine if the following conditions are met and canBuild is set to true.

VerifyConditions() Test #1 - Maximum structures reached?

First, we check if the player's level restricts the structure from being made. Have they exceeded the number of structures allowed by their level in XML/EvolutionBuildings.xml? (See Gameplay > XP and Levels documentation for more information on this)

141

0 of 1 maximum structures built for the player's current level.

if (existingStructures[currentSelection] >= maxAllowed){				
      // Max already reached
    	// Fails the first test, set canBuild = false
			canBuild = false;
      
      // Throws an error message in the in-game messanger
			((Messenger)statusMsg).DisplayMessage("Maximum " + maxAllowed.ToString() + 
				" structures of type " +
				structures [currentSelection] ["Name"]+". "); 
        // Displays the hint:
        // you can have only X structures of this type for their level
}

VerifyConditions() Test #2 - Do they have enough funds?

The second test the player data must pass is their funds - do they have enough of the currency the building requires to be constructed?

// Get the building cost
int price = int.Parse (structures [currentSelection] ["Price"]);

// If the building cost is in Gold, do they have enough gold?
if (structures [currentSelection] ["Currency"] == "Gold"){

	// Finding out how much gold they have remaning if you subtract it
	int existingGold = ((Stats)stats).gold + ((Stats)stats).deltaGoldPlus - ((Stats)stats).deltaGoldMinus;

   // See if the gold remaining is less than the price
	if (existingGold < price) 
	{
  	// not enough
		canBuild = false;
		((Messenger)statusMsg).DisplayMessage("Not enough gold.");
    //updates hint text
	}
  
// Repeat the same above, but instead for the other currency (Mana)
} 
else  if (structures [currentSelection] ["Currency"] == "Mana")
{
	int existingMana = ((Stats)stats).mana + ((Stats)stats).deltaManaPlus - ((Stats)stats).deltaManaMinus;

	if(existingMana < price)
	{
		canBuild = false;
		((Messenger)statusMsg).DisplayMessage("Not enough mana.");//updates hint text
	}
  
// Repeat the same above but for the rare Crystal currency
// If you have additional currencies in your game, uncomment the //
// and repeat for each currency
}
else  //if (structures [currentSelection] ["Currency"] == "Crystals")
{
	int existingCrystals = ((Stats)stats).crystals + ((Stats)stats).deltaCrystalsPlus - ((Stats)stats).deltaCrystalsMinus;

	if(existingCrystals < price)
	{
		canBuild = false;
		((Messenger)statusMsg).DisplayMessage("Not enough crystals.");//updates hint text
	}
}

VerifyConditions() Test #3 - Do they have an available builder?

In the City Building Kit each building under construction takes one builder. Players get a certain number of builders to start with (default is 1 in the demo) and you can adjust this for your game. It costs extra rare gems to get additional builders like games such as Clash of Clans. (The builder hut is called a dobbit hut in the demo, read the Shop Menu > Resource Generators section on builders for more details.)

//builder available?
if (((Stats)stats).occupiedDobbits >= ((Stats)stats).dobbits) 
{
	canBuild = false;
	((Messenger)statusMsg).DisplayMessage("You need more dobbits.");
}

VerifyConditions() - If all tests pass, greenlight construction.

If the player's data passes all 3 tests and canBuild still is set to true, then the script adjusts the player data awarding the XP they get from the building XML (if any) and deducting the costs involved from the building currency and price.

if (canBuild) 
{
	((MenuMain)menuMain).constructionGreenlit = true;
  //ready to close menus and place the building; 
	//constructionGreenlit bool necessary because the command is sent by pressing the button anyway

	((Stats)stats).experience += int.Parse (structures [currentSelection] ["XpAward"]); 
  //increases Stats experience  
  // move this to building finished 

	if(((Stats)stats).experience>((Stats)stats).maxExperience)
	{
		((Stats)stats).level++;
		((Stats)stats).experience-=((Stats)stats).maxExperience;
		((Stats)stats).maxExperience+=100;
	}

	//pays the gold/mana price to Stats
	if(structures [currentSelection] ["Currency"] == "Gold")
	{

		((Stats)stats).SubstractResources (price, 0, 0);

	}
	else if(structures [currentSelection] ["Currency"] == "Mana")
	{

		((Stats)stats).SubstractResources (0, price, 0);
    

	}
	else //if(structures [currentSelection] ["Currency"] == "Crystals")
	{
        
// Repeats the same above but for the rare Crystal currency
// If you have additional currencies in your game, uncomment the //if(structures
// above and repeat for each currency in your game

		((Stats)stats).SubstractResources (0, 0, price);

	}

	UpdateButtons ();//payments are made, update all

	((Stats)stats).UpdateUI();
  //tells stats to update the interface - otherwise new numbers are updated but not displayed

	if (!isField || buildingFields) 
	{
		UpdateExistingStructures (+1);
    //an array that keeps track of how many structures of each type exist
		InstantiateStructure ();
	}
} 
else 
{
	((MenuMain)menuMain).constructionGreenlit = false;
  //halts construction - the button message is sent anyway, but ignored
}

ConstructionGreenlit = true is sent the MenuMain script which then deactivates the store panel the player was just on and waits for the building to be placed.

((MenuMain)menuMain).constructionGreenlit = true;
// ready to close menus and place the building; 
// constructionGreenlit bool necessary because the command is sent by pressing the button anyway