Some questions about RTS games

Alright, I’ve been developing a RTS game and I’ve run into these problems.
Please understand that I’m a noob still with Unity and this project is just to get my skills better so try to explain things as good as you can and try to provide scripts for me to learn. I think I’ve tried everything already what I can do with Unity.

  1. How to get buildings on top of the terrain? And how to check that terrain under that building is buildable (flat, not in a water or something else.) Now they spawn half way inside a terrain.

  2. Is it possible to do so that when you do collision with trees with tanks they do fall down? How?

  3. How to stop camera going outside of level? So that it will stop on border of the current level?

Thank you in advance.

This is my building script:

// Buildings health here.
var buildingHealth : float = 100;

var buildingTypes : GameObject[];
private var buildIndex : int = 0;

// Add a healthbar for buildings.
var healthBarPrefab : GameObject;
private var healthBar : GameObject;

var resourceCash : int = 100;

// Lets check if you click building.
function Start() {
	var go : GameObject = GameObject.Find("UnitManager"); // Finding right file to include.
	go.SendMessage("AddUnit", gameObject);
	
	// Lets tell unity where Healthbar should be.
	healthBar = Instantiate(healthBarPrefab, transform.position, Quaternion.identity);
	healthBar.transform.parent = gameObject.transform;
	healthBar.transform.position.y += 5;
	
	// Set unit selected as false.
	SetUnitSelected(false);
		
}

// This handles a collision, what happens when you shoot it.
function OnCollisionEnter (collision : Collision) {

buildingHealth -= 22;


healthBar.GetComponent("HealthBar").transform.localScale.x = buildingHealth/100.0;

			if (buildingHealth < 1)

			{

					Destroy(this.gameObject);
			
			}
	
}

function SetUnitSelected(selected : boolean) {
	isSelected = selected;
	healthBar.GetComponent("HealthBar").SetHealthEnabled(isSelected);
}

function SetSelected() {
	print("I got selected... " + name);
	var go : GameObject = GameObject.Find("UnitManager");
	go.SendMessage("AddSelectedUnit", gameObject);
}

function OnGUI(){
	if(GUI.Button(Rect(0,180,100,40),"Guard Tower")){
	buildIndex = 1;
	}
	else
	{
	buildIndex = 0;
}
}

function Build(buildingTypes : int){
   if(buildingTypes==1){ // removing resources
      if(resourceCash>50){ 
         resourceCash-=50;
}
}
}
function Update(){

if(Input.GetMouseButtonDown(2)){


	var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
	var hit : RaycastHit;
	if (Physics.Raycast (ray, hit, 300)) {
	
	Instantiate(buildingTypes[buildIndex],hit.point,Quaternion.identity);
		}
      }
    }

Tough project, I’ve dabbled in nearly all the genres and have only just started on a RTS.

1/ I am going to experiment with using a transparent cube scaled to the building size (you could use a version of your building mesh with a transparent renderer), have its collider set to trigger. Have the trigger toggle a boolean when the ‘footprint’ enters or leaves another collider. That’s for not building on other things. For the terrain my other idea was to raycast downwards from each corner of the footprint, if the gradient of the terrain is too steep then don’t build. Also considering including a raycast to check if over water or some other predefined un-buildable area (forest, etc).

2/ this would be normal collisions and physics and/or animations

3/ here is my camera script for the RTS I just started. The camera moves when the mouse approaches the sides of the screen, and at a speed which is a percentage of the distance to the edge (i.e. close to edge = faster). The values to clamp the camera to the size of the terrain are hard-coded, but I’m sure you can edit them for your purpose or expose them in the inspector :

#pragma strict

 // private 
var scrollSpeed : float = 1.0;
var zoomSpeed : float = 1.0;

var scrWidth : float;
var scrHeight : float;

var scrollInput : Vector2;
var zoomInput : float;

var progScrollSpeed : float;

function Start() 
{
	scrWidth = parseFloat( Screen.width );
	scrHeight = parseFloat( Screen.height );
}

function Update() 
{
	// Move Camera
	MoveCamera();
	
	// Zoom Camera
	ZoomCamera();
	
	// Clamp Camera
	ClampCamera();
	
}

function MoveCamera() 
{
	scrollInput = Vector2( Input.mousePosition.x / scrWidth, Input.mousePosition.y / scrHeight );
	
	progScrollSpeed = scrollSpeed * transform.position.y * 0.1;
	
	if ( scrollInput.x < 0.2 )
	{
		transform.position -= Vector3.right * (0.2 - scrollInput.x) * progScrollSpeed;
	}
	else if ( scrollInput.x > 0.8 )
	{
		transform.position += Vector3.right * (scrollInput.x - 0.8) * progScrollSpeed;
	}
	else if ( scrollInput.y < 0.15 )
	{
		transform.position -= Vector3.forward * (0.15 - scrollInput.y) * progScrollSpeed;
	}
	else if ( scrollInput.y > 0.85 )
	{
		transform.position += Vector3.forward * (scrollInput.y - 0.85) * progScrollSpeed;
	}
}

function ZoomCamera() 
{
	zoomInput = Input.GetAxis("Mouse ScrollWheel");
	
	var progZoomSpeed = zoomSpeed * transform.position.y;
	
	transform.position += transform.forward * zoomInput * progZoomSpeed;
}

function ClampCamera()
{
	transform.position.x = Mathf.Clamp( transform.position.x, -100.0, 100.0 );
	transform.position.y = Mathf.Clamp( transform.position.y, 5.0, 150.0 );
	transform.position.z = Mathf.Clamp( transform.position.z, -100.0, 100.0 );
}

here is a portion of my footprint script so far :

// ** HAVE Footprint following mouse position portion here
// show chosen building as footprint 
// that follows the mouse position
// use raycast idea to change material renderer for build-able here or not

footprint.renderer.enabled = true;

isBuildable = true; // true after footprint raycast and collider test

rayMousePos = Camera.main.ScreenPointToRay(Input.mousePosition);

if ( Physics.Raycast(rayMousePos, rayHit) )
{
    footprint.transform.position = rayHit.point + Vector3( 0.0, 0.75, 0.0 ); // Vector3 Y is offset from center of footprint
}

Regarding this ‘footprint’ , imagine a transparent box the size of the building following the mouse around. If this box intersects with any object then a boolean can be toggled to say cannot build here. If the footprint stops intersecting an objetc, the boolean returns to can build here.

Now imagine raycasting down from each corner. the height of the terrain at each raycast can be read, and then the angle of the terrain below the footprint can be calculated. If it is too steep, then don’t build.

Then imagine if those same 4 rays could see if the ground below them was water or forest, or enemy territory, then also it could be calculated don’t build.