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)
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:
Use | Function | Description |
---|---|---|
All Uses | Move() | Moving pad arrows that you can tap to move structures by one grid coordinate. |
PC Games | MouseMove() | Tracks the mouse to have structures following the mouse location. Great for Windows/Mac games. |
Mobile Games | TouchMove() | 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.
This button above activates the moving pad as seen in the below image
// 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:
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.
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.
Then, tap the move button that appears in the bottom center of the screen.
Moving pad arrows will appear around the structure. You can press the buttons or drag the building to relocate.
When finished, select the Checkmark button to save the new location.
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.
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.
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();
}
}
Updated less than a minute ago