Basic movement in a grid

This must be very basic thing to do but I can't figure it out. I'm trying to move things in a grid layout when user uses movement keys. I've got everything else figured out but I can't figure out how to actually move the thing. How can I animate the movement of 1 unit to about 0.5 seconds? If I use transform.position it move there, yes, but in one frame. It should also block moving it again before the new position has been reached so move commands won't stack up 60 times a second.

Another thing. This is a rpg style game, like the pokemon on handhelds. Should I use tiles for the maps or what? If I use tiles the hierarchy is full of them (think 300 x 300 map, so 9000 tiles) and I suspect it'll lag the game. How should I construct the terrain?

i made a script that can help you. i never used it in my project but i think you can use it now basicaly in these situations you should use coroutines. if you want to move something 16 meter in a second you should add 16*time.deltaTime to it each frame.

using UnityEngine;
using System.Collections;

public class move : MonoBehaviour

{

bool canmove = true; //indicate if a keyboard key can move a piece
Vector3 targetPosition; //temporary value for moving (used in coroutines)
public int speed = 10;
public int gridSize=1;

void Update()
{
    if (Input.GetKey(KeyCode.UpArrow) == true && canmove == true)
    {
        canmove = false;
        StartCoroutine (MoveInGrid((int)transform.position.x, (int)transform.position.y+gridSize, (int)transform.position.z));
    }
    if (Input.GetKey(KeyCode.RightArrow) == true && canmove == true)
    {
        canmove = false;
        StartCoroutine(MoveInGrid((int)transform.position.x+gridSize, (int)transform.position.y, (int)transform.position.z));
    }
    if (Input.GetKey(KeyCode.LeftArrow) == true && canmove == true)
    {
        canmove = false;
        StartCoroutine(MoveInGrid((int)transform.position.x-gridSize, (int)transform.position.y, (int)transform.position.z));
    }
    if (Input.GetKey(KeyCode.DownArrow) == true && canmove == true)
    {
        canmove = false;
        StartCoroutine(MoveInGrid((int)transform.position.x, (int)transform.position.y-gridSize, (int)transform.position.z));
    }
}

IEnumerator MoveInGrid(int x,int y,int z)
{
    while (transform.position.x != x || transform.position.y != y || transform.position.z != z)
        {
            //moving x forward
            if (transform.position.x < x)
            {
                //moving the point by speed 
                targetPosition.x = speed * Time.deltaTime;
                //check if the point goes more than it should go and if yes clamp it back
                if (targetPosition.x + transform.position.x > x)
                {
                    targetPosition.x = x - transform.position.x;
                }
            }
            //moving x backward
            else if (transform.position.x > x)
            {
                //moving the point by speed 
                targetPosition.x = -speed * Time.deltaTime;
                //check if the point goes more than it should go and if yes clamp it back
                if (targetPosition.x + transform.position.x < x)
                {
                    targetPosition.x = -(transform.position.x - x);
                }
            }
            else //x is unchanged so should be 0 in translate function
            {
                targetPosition.x = 0;
            }
            //moving y forward
            if (transform.position.y < y)
            {
                //moving the point by speed 
                targetPosition.y = speed * Time.deltaTime;
                //check if the point goes more than it should go and if yes clamp it back
                if (targetPosition.y + transform.position.y > y)
                {
                    targetPosition.y = y - transform.position.y;
                }
            }
            //moving y backward
            else if (transform.position.y > y)
            {
                //moving the point by speed 
                targetPosition.y = -speed * Time.deltaTime;
                //check if the point goes more than it should go and if yes clamp it back
                if (targetPosition.y + transform.position.y < y)
                {
                    targetPosition.y = -(transform.position.y - y);
                }
            }
            else //y is unchanged so it should be zero
            {
                targetPosition.y = 0;
            }
            //moving z forward
            if (transform.position.z < z)
            {
                //moving the point by speed 
                targetPosition.z = speed * Time.deltaTime;
                //check if the point goes more than it should go and if yes clamp it back
                if (targetPosition.z + transform.position.z > z)
                {
                    targetPosition.z = z - transform.position.z;
                }
            }
            //moving z backward
            else if (transform.position.z > z)
            {
                //moving the point by speed 
                targetPosition.z = -speed * Time.deltaTime;
                //check if the point goes more than it should go and if yes clamp it back
                if (targetPosition.z + transform.position.z < z)
                {
                    targetPosition.z = -(transform.position.z - z);
                }
            }
            else //z is unchanged so should be zero in translate function
            {
                targetPosition.z = 0;
            }
            transform.Translate(targetPosition);
            yield return 0;
        }
        //the work is ended now congratulation
        canmove = true;
    }

} the important function is MoveInGrid that takes values as target position in world space and move the gameobject to there. see my Update function to learn it's usage. i used local positions in my Update function. the script's gridsize is equal in x,y,z and you can set this size and speed inside inspector. the component is completely reusable but you can modify it or only use MoveInGrid coroutine.

I've put a grid movement script on the wiki here: http://wiki.unity3d.com/index.php/GridMove

I'm afraid the other script has some issues, such as being wayyyy too long ;), repeating the same transform.position twice on "grid lines" (leading to slight but visible hiccups when traversing more than one square in a row), and sometimes moving two squares at once.

As far as the maps go, they should be done using a single plane, where each square is an individually UV mapped tile, using a texture atlas. Using separate objects for each tile is a recipe for massively worse performance.