- Home /
Simple script to move object doesn't work
I've just trying to make this simple script for a basic cube that moves the cube on the Z and X axis with WASD inputs. To do this, I'm trying to have a target position, which the cube moves into (lerps into?) so the movement is fluid, and also the user can navigate several units, in different directions, and the block will continue to move to the desired position. Long story short, my script doesn't work at all. I'm using my limited knowledge to create something new, and it had failed. Could someone please help me get this working?
#pragma strict
var moveSpeed : float;
private var targetPosition : Transform;
function Start ()
{
targetPosition = GameObject.transform;
}
function Update ()
{
transform.position = Vector3.Lerp(GameObject.transform, endMarker.position, 1);
if (Input.GetKey ("w"))
targetPosition.x = targetPosition.x + 1;
if (Input.GetKey ("a"))
targetPosition.z = targetPosition.x + 1;
if (Input.GetKey ("s"))
targetPosition.x = targetPosition.x - 1;
if (Input.GetKey ("d"))
targetPosition.z = targetPosition.x - 1;
}
Cheers.
Answer by Alec-Slayden · Aug 17, 2013 at 01:14 AM
There are a number of things going wrong here.
Firstly, when accessing the game object that you put this script on, you'll want to use "gameObject", not "GameObject". The case is important. "gameObject" is a property that fetches the instance's gameObject data, from which you can access a transform. "GameObject" is the actual class itself, which has no transform to access. In addition, you can access the transform without going through the gameObject, since it is similarly a reference property. However that's not your main problem.
The main problem here is that you are confusing the Vector3 position data with the Transform itself. The transform of a gameObject is a special class storing position, rotation, and scalar data.. You're going to want your "targetPosition" variable to be a Vector3, not a transform, so you can apply it to the transform's position vector.
In addition, in your Lerp you're using a variable called "endMarker" that is never defined, though I presume you want to use your targetPosition instead, so we should swap that out.
The way Lerp works is that it takes the first parameter, and moves it towards the second parameter as the third parameter (time) approaches 1. This means that when the time parameter is 0, the result is always the first parameter. When the time parameter is 1, the result is always the second parameter. Your lerp is using "1" as the time parameter, which will cause it to always be at the destination, and you won't see any smoothing.
A lot of the time, you'll want to use a changing variable that moves toward 1 for a Lerp, to ensure the result moves between the two parameters. in this case, however, we're using the transform's position as an input, which itself is going to be changing, so we can use a static value and still get a smoothing effect. The static value can't be 0, or 1, of course, because then it will either never move, or never smooth.
To present an example, putting in 0.5f as the time parameter in this particular case will cause the position to move halfway toward the destination every frame. So if it's 2 meters away, next frame it'll be 1 meter, then 0.5 meters, etc.
But we are going to do something different. The value Time.deltaTime returns the number of seconds since the last frame occurred. If you added this into a variable every frame, it would add up to 1 over a second. Frequently such a variable is used for a Lerp's time parameter, for that reason. Since in this simplified lerp we can use a static value, however, we're just going to take the Time.deltaTime value itself. We are doing this because it will account for lag or varied frame-rates (since it returns how long it's been since the last frame), whereas simply plugging in our own float will not.
You have a variable "moveSpeed" which we're going to use as a multiplier to allow you to adjust how fast the lerp happens.
Here's some new code, with comments.
#pragma strict
var moveSpeed : float;
private var targetPosition : Vector3; //changed to a vector3
function Start ()
{
// Fetch the current position,
// instead of the actual transform.
targetPosition =transform.position;
}
function Update ()
{
// Again, fetch the position, not just transform,
// replace endMarker with targetPosition,
// and use our time value * multiplier.
transform.position = Vector3.Lerp( transform.position, targetPosition, Time.deltaTime * moveSpeed );
// code here is fine, but wordy.
// consider using "targetPosition.x += 1"
// or "targetPosition.x ++" which do the same thing.
// I changed references to z that were previously at x.
if (Input.GetKey ("w"))
targetPosition.x = targetPosition.x + 1;
if (Input.GetKey ("a"))
targetPosition.z = targetPosition.z + 1;
if (Input.GetKey ("s"))
targetPosition.x = targetPosition.x - 1;
if (Input.GetKey ("d"))
targetPosition.z = targetPosition.z - 1;
}
Wow, I didn't anticipate such an in depth answer. Thank you so much! The script works fine and I have a much clearer understanding of what I was doing now. Thanks again!
Your answer
Follow this Question
Related Questions
Vector3.Lerp making my object invisible. 2 Answers
smoothly change position of an Object 1 Answer
Object keeps moving when using Vector3.Lerp on transform.position 0 Answers
MOVE GameObject to point A to B and to B to A 2 Answers
How to use a Vector3.MoveTowards and the resulting position as an input for a normalised BlendTree 0 Answers