Click to move (499240)

I’d just like to say before I get told “Learn how to use the search”, I have searched and I have found many threads about this type of scripting but they all are coded around other features or gameplay styles. I would also like to learn about my script instead of copying and pasting from someone who has it working.

I’ve created a script that lets my mouse pan around a Transform object (Player) and now I would like to get my player object (Testing with a sphere) to move to where ever I click. The code below works, I click and the sphere is teleported there but that’s not what I’m trying to do. I would like it so that the sphere moves to where I click, not teleport and I’d also like to stop the sphere from resetting its Y value to 0.

var player : Transform;
var speed = 4.0;
var dir : Vector3;
public var distance = 50;
 
function Update () 
{
if ( Input.GetKeyDown(KeyCode.Mouse0))
{
   	var hit : RaycastHit;
   	var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
   	
    if (Physics.Raycast (ray, hit, 500))
      {
      	var localHit = transform.InverseTransformPoint(hit.point);
		player.Translate((hit.point - player.position) * Time.deltaTime * distance);
      }
}
}

Thanks for taking the time to help.

have you tried making distance a float and using a smaller number? It should actually be speed not distance.

Hello,

You can just use Lerp you can control speed as it translates object from point A to point B:

it would be in format of:

Vector3.Lerp(player.position, hit.point, someSpeed)

You have nice example in the documentation.

The speed variable was for another line of code in the script, I did have it so I could control the speed but it wouldn’t go below 1 and even at 1 it was way too fast, the distance is actually how far you can go forward since if I set it at 100 I can pretty much travel half way across the map in one click.

I did look into using Lerp but I’ve never used it before and wasn’t completely sure how I would implement it. I will have a go now though, thank you.

There is such code in wiki.

yes that is because you call the translate with a large number. Set it at a lower number. Remember the translate is only being called then the raycast hits.

You should be thinking of it as a speed not a distance.

I already tried with a lower number, originally I was using 1 but what would happen is that when I click I would move forward only a tiny amount, this was with both GetKey and GetKeyDown. The higher the number the further I could move, which is why I named the variable “Distance”.

Using lerp I managed to get what I want, holding down the mouse button though. But now I’m stuck with two other problems, I need the character model to rotate to where the raycast hit is and I also need to stop the models center position from setting it’s Y value to 0 and being half in the ground… Any help?

so what you need to do is set a position to move too when you raycast then put the translate in a function that is always called to seperate it from the mouse.

So you mean like initiate the raycast to get the hit.point, make a variable called temp then do temp = hit.point and then instead of translating straight from the if getkeydown I run a seperate function that will move the player?

For rotating character you can use LookAt:

http://docs.unity3d.com/Documentation/ScriptReference/Transform.LookAt.html

As for translation, you just modify from and to vector so that Y value is constant so that your player will not move in that axis.

Thanks, it works great. How would I go about the Y value problem? I’ve only just started with raycasting/lerp/vector3.

If i understand correctly you don’t want your character to move on Y axis while doing the lerp, if this is the case then just set values before you do the lerp manually like this.

Vector3 from = new Vector3(player.possition.x, 0, player.possition.z);
Vector3 to = new Vector3(hit.point.x, 0, hit.point.z);

Now when you cast this to lerp function you will have object moving by X and Z coordinates and keeping Y at zero, or instead of zero any other value that is applicable.

I just tried to add your code but I get UCE0001: ‘;’ expected. I’ve made sure they both have them but still the same error.

I forgot ; at the end :slight_smile:

Corrected it now.

I already noticed it lol but I still get an error saying both lines don’t have a semicolon. :neutral:

Ok, sorry i did it without thinking in c#

Here is java script i just tested that translates object form → to

var from : Vector3;
var to : Vector3;

function Start () 
{
	from = Vector3(this.gameObject.transform.position.x, 0, this.transform.position.y);
	to = Vector3(0,0,0);
}

function Update ()
{
	this.gameObject.transform.position = Vector3.Lerp(from, to, Time.deltaTime * 0.5);
	from = Vector3(this.gameObject.transform.position.x, 0, this.transform.position.y);
}

You of course need to be careful because this will lerp object constantly so you can put some if statement to check is goal reached.

Of course it will teleport. You need to translate your player into a point between your source and destination points.

Like this sphere will slowly follow mouse cursor as long as it’s on the object tagged “ground” and as long as LMB is pressed.

#pragma strict
var player : Transform;
var speed = 4.0;

function Update () {
	if (Input.GetMouseButton(0)) {
	    var hit : RaycastHit;
    	var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    	if (Physics.Raycast (ray, hit, 500)) {
    		if (hit.transform.tag == "Ground") {
				player.LookAt(hit.point);
        		player.Translate(Vector3.forward * Time.deltaTime * speed);
        	}
      	}
	}
}

This is exactly what I’m looking for, the only thing I can’t seem to figure out is how I would stop it from translating the y value and pushing the sphere half way into the ground?

Yes, then you don’t have to hold down and keep calling the raycast.

Ahmmm that’s not so easy. I’d put the player inside an empty game object and adjusted it’s position so the player is always abothe the ground and rotates correctly, but who cares about easy solutions?

Not familiar with unity script so I switched to C# again.

using UnityEngine;
using System.Collections;

public class PlayerScript : MonoBehaviour {
	public Transform Player = null;
	public float Speed = 10;

	void Update () {
		// if player LMB is pressed
		if (Input.GetMouseButton (0)) {
			// create container to receive hit results
			RaycastHit hit;
			// create ray according to mouse cursot position on the screen
			Ray ray = camera.ScreenPointToRay (Input.mousePosition);
			// create layer mask for first user layer. I called this layer "Ground" and assigned to terrain
			int layerMask = 1 << 8;
			// cast ray
			if (Physics.Raycast (ray, out hit, 500, layerMask)) {
				//if ray hit a collider on it's way...
				//and point of collision is far enough from player
				if (Vector3.Distance(Player.position, hit.point) < 1) return;
				//save final destination poit
				Vector3 destination = hit.point;
				//and fix y axis
				destination.y = Player.position.y;
				//turn player to it's destination point
				Player.LookAt (destination);
				//move it a lil bit towards that point
				Player.Translate(Vector3.forward * Time.deltaTime * Speed);
				//one more raycast to find out y position of the ground in this point
				if (Physics.Raycast (new Vector3(Player.position.x, 200, Player.position.z), Vector3.down,out hit, 500, layerMask)) {
					//and fix position of the player by adding half of his height to y coordinate of the ground
					Player.position = new Vector3(hit.point.x, hit.point.y + 0.5f, hit.point.z);
				}
			}
		}