Moving Structures

👍

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.

After a player places a structure, can they move it?

Yes, buildings can be moved after they are placed. This allows for game players to redesign their map and village based on how they would like to customize their base. You can enable or disable this feature. All of the scripting is located in Scripts/Creators/BaseCreator.cs

Grid coordinates system

Like many free to play strategy games - the player has an entire map that they can build their base on. In this case, each square corresponds to one grid coordinate. Moving structures moves then in this coordinate system. (You can choose whatever size map for your game, the demo map looks like the example below)

800

Map grid example. Click to view larger

How are buildings moved?

There are three different control types included in the City Building Kit highest package. These control schemes are pre-built for developers to be able to build any sort of mobile, desktop, or console game. The following is a table of different functions:

UseFunctionDescription
All UsesMove()Moving pad arrows that you can tap to move structures by one grid coordinate.
PC GamesMouseMove()Tracks the mouse to have structures following the mouse location. Great for Windows/Mac games.
Mobile GamesTouchMove()Tracks touch to have structures following the user's touch. Great for mobile games.

There is a moving pad button located in the game scene Canvas/ObjectSelectedPanel/BlockingMask/ButtonsGroup/MoveButton for each of the building types.

359

This button above activates the moving pad as seen in the below image

992
// Activated by the moving buttons located in UIAnchor - Bottom
// move pad activated and translated into position
	public void ActivateMovingPad()
	{
    // Checks if the buttons are already activated
		if (!MovingPad.activeSelf) 
		{
      // Activates the moving pad buttons
			MovingPadOn();
		}
	}

The buttons look like the following screenshot:

550

Moving pad controls appear. Click to view larger

Each of the moving pad buttons are relocated around the structure you have selected with the MovingPadOn() function in Scripts/Creators/BaseCreator.cs

protected void MovingPadOn()//move pad activated and translated into position
	{		
		MovingPad.SetActive (true);
						
		selectedStructure.transform.parent = MovingPad.transform;
		selectedGrass.transform.parent = MovingPad.transform;
			
		if (isReselect) 
		{
			selectedGrass.transform.position = new Vector3 (selectedGrass.transform.position.x,
			                                                selectedGrass.transform.position.y,
			                                                selectedGrass.transform.position.z - 2.0f);//move to front 

			selectedStructure.transform.position = new Vector3 (selectedStructure.transform.position.x,
			                                                    selectedStructure.transform.position.y,
			                                                    selectedStructure.transform.position.z - 6);//move to front
			displacedonZ = true;
		}
		((CameraController)cameraController).movingBuilding = true;
		
	}

Touch and drag for mobile games

For game players to be able to touch and drag buildings we've included touch controls for mobile games in addition to the mouse tracking for desktop games and the moving pad controls for fine tuned movement.

The following script excerpt below shows the TouchMove() function in the Scripts/Creators/BaseCreator.cs script which tracks touch movements and translates them into grid coordinate movement.

// BaseCreator.cs
// The following script gets the touch input from the mobile device
// and determines which grid coordinates to move the building
// -- Players can touch and drag buildings like this
//
	private void TouchMove()
	{
    
    // If a touch is registered
		if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)		        
		{
      // Get the location
			Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
			
      // Using simple arithmetic, determine the grid coordinate location
      // To begin moving the structures in
			if(touchDeltaPosition.x < 0)
			{
				if(touchDeltaPosition.y < 0)
				{
					MoveSW();
				}
				else if(touchDeltaPosition.y > 0)
				{
					MoveNW();
				}
			}
			else if(touchDeltaPosition.x > 0)
			{
				if(touchDeltaPosition.y < 0)
				{
					MoveSE();
					
				}
				else if(touchDeltaPosition.y > 0)
				{
					MoveNE();
				}
			}
		}
	}

How the placement follows the mouse

For Windows and Mac games, we also use Raycasting to determine the mouse location which is used for relocating structures by tracking the mouse movement and attaching the structure to the mouse location. This makes it much easier for computer game users to interact with your game than using the moving pad alternative also included.

The following script excerpt below shows the MouseMove() function in the Scripts/Creators/BaseCreator.cs which tracks mouse movements and translates them into grid coordinate movement similar to how TouchMove() tracks touch.

// The following function checks when the mouse has moved 
// and determines the grid coordinate direction that matches
// the direction the mouse has moved in

	public void MouseMove()
	{
    // Gets the mouse position
		GetMousePosition ();		
    // Calculates the difference between the last position and this one
		Vector2 deltaPosition = mousePosition - new Vector2(selectedStructure.transform.position.x,
		                                                    selectedStructure.transform.position.y);
		
    // Determine using simple arithmetic in which direction the mouse has moved
		if(Mathf.Abs(deltaPosition.x)>gridx||Mathf.Abs(deltaPosition.y)>gridy)
		{				
			if(deltaPosition.x < 0)
			{
				if(deltaPosition.y < 0)
				{
					MoveSW();
				}
				else if(deltaPosition.y > 0)
				{
					MoveNW();
				}
			}
			else if(deltaPosition.x > 0)
			{
				if(deltaPosition.y < 0)
				{
					MoveSE();
					
				}
				else if(deltaPosition.y > 0)
				{
					MoveNE();
				}
			}
		}
		
	}

Alternative movement control - arrows

Other than touch and mouse controls, you also can use the moving pad arrow buttons.

461

Moving pad arrow that triggers MoveNW() function. Click to view larger

Tapping the top left arrow button in the example image above will trigger the MoveNW() function in Scripts/Creators/BaseCreator.cs each one of these moving buttons initiates one of the four cases for the BaseCreator.cs Move function.

// Four different moving pad buttons (NW, NE, SE, SW)
// To transition the building by one grid coordinate.
	public void MoveNW(){Move(0);}	//	-+
	public void MoveNE(){Move(1);}	//	++
	public void MoveSE(){Move(2);}	//	+-
	public void MoveSW(){Move(3);}	//	--

The BaseCreator.cs Move function takes one of the four different ways to move in the grid coordinate structure (Northwest, Northeast, Southeast, and Southwest) and processes one of our different cases to step the building by one grid coordinate.

protected void Move(int i)
	{
		if (((Relay)relay).pauseMovement || ((Relay)relay).delay) return;
		
		((SoundFX)soundFX).Move(); 
    
		//cast float, otherwise  181/2 = 90, and this accumulats a position error;
		float stepX = (float)gridx / 2;
		float stepY = (float)gridy / 2;
    
		// Depending on the moving pad, simple arithmetic to move one grid coordinate.
		switch (i) 
		{
		case 0:
			MovingPad.transform.position += new Vector3(-stepX,stepY,0);		//NW	
			break;	
			
		case 1:
			MovingPad.transform.position += new Vector3(stepX,stepY,0);			//NE		
			break;
			
		case 2:
			MovingPad.transform.position += new Vector3(stepX,-stepY,0);		//SE		
			break;
			
		case 3:
			MovingPad.transform.position += new Vector3(-stepX,-stepY,0);		//SW		
			break;				
		}	
	}

Process to move a structure

First, select an object you would like to move.

636

Select object. Click to view larger

Then, tap the move button that appears in the bottom center of the screen.

550

Open move controls.

Moving pad arrows will appear around the structure. You can press the buttons or drag the building to relocate.

461

Tap an arrow to trigger moving process. Click to view larger

When finished, select the Checkmark button to save the new location.

550

Tap the checkmark to stop moving - or click on the building to drop.

How collision errors are avoided

When you reselect a building for moving or when you are placing a structure - the grass colliders prevent accidental collision errors from occurring. Like placing a building over the other.

The following function triggers when you are moving a building, and you can see the last two lines when enable the GrassColliders:

private void ReselectStructure()
	{
        MoveBuildingPanelController.Instance.Panel.SetActive(true);

		((Relay)relay).pauseInput = true;

		MovingPad.transform.position = 
			new Vector3(selectedStructure.transform.position.x,
				selectedStructure.transform.position.y, padZ);
			
		selectedGrass.GetComponentInChildren<GrassCollider>().enabled = true;
		((GrassCollider)selectedGrass.GetComponentInChildren<GrassCollider>()).isMoving = true;
	}

A preview of how the grass colliders turn from green to red when you move over an existing structure.

553

Grass tiles detect collision errors. Click to view larger

When the colliders sense an existing building - the OK button to finish relocating the building cannot be selected. You'll see in the BaseCreator.cs OK() function below (triggered by the checkmark button) that we first check if there is an existing building by determining the Grass Collider's status.

public void OK()
	{
		if (((Relay)relay).currentAlphaTween != null) 
		{			

			if (((Relay)relay).currentAlphaTween.inTransition)			//force fade even if in transition
				((Relay)relay).currentAlphaTween.CancelTransition ();

			((Relay)relay).currentAlphaTween.FadeAlpha (false, 1);
			((Relay)relay).currentAlphaTween = null;
		}



		Delay ();

		inCollision = selectedGrass.GetComponentInChildren<GrassCollider>().inCollision;

		if (!inCollision) 
		{

			if(allInstant)			
			PlaceStructureGridInstant ();			
			else
			PlaceStructure ();					
		}

		((Relay)relay).pauseMovement = false;	//the confirmation screen is closed
	}

What happens after the structure is placed?

If the structure has already been created, then the BaseCreator.cs PlaceStructureGridInstant() function is triggered. Otherwise, the PlaceStructure() function is triggered which then sets up the timing and contstruction of the building (for new placements)
save file example stores the grid coordinates

Can I disable the ability to move buildings?

Yes. The simplest way to remove the ability for players to move buildings after they have placed them is to disable the MoveButton Game Object from the Game scene hierarchy. See the below images.

1154

Also, in Scripts/Creators/BaseCreator.cs locate the ActivateMovingPad() function and uncomment the line MovingPadOn() as seen below:

// Excerpt from BaseCreator.cs
// This function is triggerd by the move buttons
// The example below comments the MovingPadOn() to disable
// moving pads

	public void ActivateMovingPad()
	{
		if (!MovingPad.activeSelf) 
		{
      // To disable moving, we will comment the following line
			//MovingPadOn();
		}
	}