Diablo movement (almost complete)

Hi all guys.
I’m new in the Unity Community, and i think tath Unity3d is a fantastic software!! :slight_smile: :slight_smile:
My first post wants to be useful for anyone who would like to apply the “click to move style game Diablo”. :slight_smile:

[COLOR="green"]var obj:Transform;
var Terr:TerrainData;
var LimitTerrain:float = 5.0;
var hit:RaycastHit;
var move: boolean = false;
var speed: float;
private var typeMovementX: int;
private var typeMovementZ: int;

function Update ()
{
     
    if(Input.GetKeyDown("left ctrl"))
    {
        speed = speed * 4;
    }
    
    if(Input.GetKeyUp("left ctrl"))
    {
        speed = speed / 4;
    }

    if(Input.GetKeyDown(KeyCode.Mouse0))
    {
        var ray = Camera.main.ScreenPointToRay (Input.mousePosition); 
            if (Physics.Raycast (ray, hit, 10000))
            {
                if(hit.point.x >= obj.position.x)
                {
                    typeMovementX=0;
                }
                else
                {
                    typeMovementX=1;
                }
                
                 if(hit.point.z >= obj.position.z)
                {
                    typeMovementZ=0;
                }
                else
                {
                    typeMovementZ=1;
                }
                 move = true;
            }
    }	
    if(move)
    {
        //Muovo il giocatore
        var movePos = Vector3(hit.point.x,7,hit.point.z);
        MovePlayer(speed,movePos,hit,typeMovementX,typeMovementZ);
        if(move == true)
        {
            if(obj.transform.position == hit.point)
            {
                //Se il giocatore ha raggiunto la posizione, lo blocco
                move = false;
            }
        }       
    }
}

function MovePlayer (speed : int, movePos : Vector3 ,hit : RaycastHit,typeMovementX : int,typeMovementZ : int) 
{
	var dist = Vector3.Distance (obj.transform.position, movePos);
	var pos:Vector3;
	//obj.transform.LookAt(movePos);
	for (i = 0.0; i < 1.0; i += (speed * Time.deltaTime) / (dist * 20)) 
	{
	    //Controllo le coordinate dove si deve muovere il giocatore
	    if(typeMovementX==0  typeMovementZ==0)
	    {
	        pos=Vector3(transform.position.x+1,7,transform.position.z+1);
	    }
	    else
	    {
	        if(typeMovementX==1  typeMovementZ==1)
	        {
	            pos=Vector3(transform.position.x-1,7,transform.position.z-1);  
	        }
	        else
	        {
	            if(typeMovementX==0  typeMovementZ==1)
	            {
	                pos=Vector3(transform.position.x+1,7,transform.position.z-1);  
	            }   
	            else
	            {
	                if(typeMovementX==1  typeMovementZ==0)
	                {
	                    pos=Vector3(transform.position.x-1,7,transform.position.z+1);  
	                }   
	            }
	        }
	    }
	    	    	    
	    //Se il personaggio trova un collider si ferma
	    if(Physics.Linecast(transform.position,pos))
	    {
	        move = false;
	        break;
	    }
	    else
	    {
	        //Se la posizione in cui si vuole andare è all'interno del limite, il personaggio si può muovere
	        if((pos.x < (Terr.size.x - LimitTerrain))  (pos.x>LimitTerrain)  (pos.z < (Terr.size.z-LimitTerrain))  (pos.z>LimitTerrain))
            {
                obj.transform.position = Vector3.Lerp(obj.transform.position, movePos, i);
	            yield;
		        if (Input.GetKeyDown(KeyCode.Mouse0)) 
		        {
			        i = 1.0;
		        }
            }
	        else
	        {
	            //Blocco il movimento
	            move = false;
	            break;
	        }
	    }
	}
}[/COLOR]

This type of code allows to move an object (in my case a capsule), when you click the left mouse button on the terrain…
Script contain three particularity:

  • Constant velocity for the object;
  • Automatically control the collision with collider;
  • Limit movement on the terrain;

Now the Y coordinate is fixed to 7 for my test…
I think that the Y should match with the Y of the terrain. :slight_smile:

This new code fixed the Y coordinate… Now the character move according to the slope of the terrain. :smile:

[COLOR="green"]var obj:Transform;
var Terr:TerrainData;
var LimitTerrain:float = 5.0;
var hit:RaycastHit;
var move: boolean = false;
var speed: float;
private var typeMovementX: int;
private var typeMovementZ: int;

function Update ()
{[indent]
if(Input.GetKeyDown("left ctrl"))
{[indent]speed = speed * 4;[/indent]}
if(Input.GetKeyUp("left ctrl"))
{ [indent]speed = speed / 4;[/indent]
}
if(Input.GetKeyDown(KeyCode.Mouse0))
{[indent]
 var ray = Camera.main.ScreenPointToRay (Input.mousePosition); 
 if (Physics.Raycast (ray, hit, 10000))
 {
 [indent]if(hit.point.x >= obj.position.x)
{
[indent]typeMovementX=0;[/indent]
}
else
{
[indent]typeMovementX=1;[/indent]
}

if(hit.point.z >= obj.position.z)
{
[indent]typeMovementZ=0;[/indent]
}
else
{
[indent]typeMovementZ=1;[/indent]
}
move = true;
}[/indent]
}[/indent]	
[indent]if(move)
{
[indent]//Muovo il giocatore
var movePos = Vector3(hit.point.x,[COLOR="red"]Terra.activeTerrain.SampleHeight(obj.transform.position)+1[/COLOR],hit.point.z);
MovePlayer(speed,movePos,hit,typeMovementX,typeMov ementZ);
if(move == true)
{
[indent]if(obj.transform.position == hit.point)
{
[indent]//Se il giocatore ha raggiunto la posizione, lo blocco
move = false;[/indent]
}[/indent]
} [/indent]
}[/indent]
}


function MovePlayer (speed : int, movePos : Vector3 ,hit : RaycastHit,typeMovementX : int,typeMovementZ : int) 
{
[indent]
var dist = Vector3.Distance (obj.transform.position, movePos);
var pos:Vector3;
//obj.transform.LookAt(movePos);
for (i = 0.0; i < 1.0; i += (speed * Time.deltaTime) / (dist * 20)) 
{
[indent]
//Controllo le coordinate dove si deve muovere il giocatore
[COLOR="red"] if(typeMovementX==0  typeMovementZ==0)
	    {
[indent]
pos=Vector3(transform.position.x+1,Terra.activeTerrain.SampleHeight(obj.transform.position)+1,transform.position.z+1);
[/indent]
	    }
	    else
	    {
[indent]
	        if(typeMovementX==1  typeMovementZ==1)
	        {
[indent]
	            pos=Vector3(transform.position.x-1,Terra.activeTerrain.SampleHeight(obj.transform.position)+1,transform.position.z-1);  [/indent]
	        }
	        else
	        {
[indent]
	            if(typeMovementX==0  typeMovementZ==1)
	            {
	                [indent]pos=Vector3(transform.position.x+1,Terra.activeTerrain.SampleHeight(obj.transform.position)+1,transform.position.z-1);  [/indent]
	            }   
	            else
	            {
[indent]
	                if(typeMovementX==1  typeMovementZ==0)
	                {
[indent]
	                    pos=Vector3(transform.position.x-1,Terra.activeTerrain.SampleHeight(obj.transform.position)+1,transform.position.z+1);  
	               [/indent] }   
	            [/indent]}
	       [/indent] }
	    [/indent]}[/COLOR]
//Se il personaggio trova un collider si ferma
if(Physics.Linecast(transform.position,pos))
{
[indent]
move = false;
break;[/indent]
}
else
{
[indent]//Se la posizione in cui si vuole andare è all'interno del limite, il personaggio si può muovere
if((pos.x < (Terr.size.x - LimitTerrain))  (pos.x>LimitTerrain)  (pos.z < (Terr.size.z-LimitTerrain))  (pos.z>LimitTerrain))
{[indent]
[COLOR="red"]obj.transform.position = Vector3.Lerp(obj.transform.position, Vector3(movePos.x,pos.y,movePos.z), i);[/COLOR]
yield;
if (Input.GetKeyDown(KeyCode.Mouse0)) 
{[indent]i = 1.0;[/indent]}[/indent]}
else
{
[indent]//Blocco il movimento
move = false;
break;[/indent]
}
}[/indent]
}[/indent]
}[/indent][/COLOR]

Hello Steve,

Thanks for the contribution and welcome to the community! You might consider putting it on the Unity Wiki.

Fyi though, in the future you might want to use the bbcode code tags. It keeps all your indentation and formatting. People tend to hit the back button otherwise, as it’s very difficult to read.

Hi Quietus!
I’ve changed the indentation of the code… Is this correct now? :slight_smile:

Hey did you get the code working? If you did could you post it (in English) I was looking for the exact same thing I’m making a Diablo style game thanks

he actually means to wrap your code with code tags. [ code ] and [ /code ] (without the spaces) so that it looks like your quote does above.

Yeah!
Try it if you want and tell me if it does work correctly! :slight_smile:

What are you attaching the code to? A camera? The player controller or a simple game object?

This script must be attached to a game object.
In my case i have a capsule object (with main camera inside it), and i put this code in the capsule.

  • obj → capsule;
  • Terra → terrain;
  • Terr → terraindata;

Game object could be an imported model also if you want :smile:.