Your character is teleporting because the calculation you’re applying does not take the concept of time into account.
What you need is to calculate the new position each frame / physics frame instead of the arbitrary amount you’re adding each cycle.
try something like this
if (Input.GetKeyDown("w"))
{
transform.Translate(new Vector3(0, 0, 1) * Time.deltaTime);
}
I want to use GetKeyDown because I want my character to move somwhere each time I tap so 20 units every time I tap wasd I just want it to move smoothly each time I hit wasd
Then your issue is slightly more complex. You want to take a single input within a frame and translate it to smooth movement, right? This means you’re going to have to do something over x seconds.
Linear interpolate between two points (the starting position and ending position)
public static Vector3 Lerp(Vector3 a, Vector3 b, float t);
But you’re probably going to have to trigger it within a coroutine.
Something like this should move the player forward 1 unit linearly interpolated over 45 frames.
public class ExampleClass : MonoBehaviour
{
public int interpolationFramesCount = 45;
int elapsedFrames = 0;
private bool hasReachedDestination;
private bool isMoving;
private void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
if (!isMoving)
{
isMoving = true;
}
}
if (isMoving)
{
if (!hasReachedDestination)
{
StartCoroutine(Move());
}
}
}
private IEnumerator Move()
{
float interpolationRatio = (float)elapsedFrames / interpolationFramesCount;
Vector3 interpolatedPosition = Vector3.Lerp(0, 0, 0, 0, 0, 1, interpolationRatio);
if (elapsedFrames < interpolationFramesCount)
{
elapsedFrames = elapsedFrames + 1;
}
else
{
hasReachedDestination = true;
isMoving = false;
elapsedFrames = 0;
}
}
}
you could also use a slightly different method
public class ExampleClass : MonoBehaviour
{
// Transforms to act as start and end markers for the journey.
public Transform startMarker;
public Transform endMarker;
// Movement speed in units per second.
public float speed = 1.0F;
// Time when the movement started.
private float startTime;
// Total distance between the markers.
private float journeyLength;
void Start()
{
// Keep a note of the time the movement started.
startTime = Time.time;
// Calculate the journey length.
journeyLength = Vector3.Distance(startMarker.position, endMarker.position);
}
// Move to the target end position.
void Update()
{
// Distance moved equals elapsed time times speed..
float distCovered = (Time.time - startTime) * speed;
// Fraction of journey completed equals current distance divided by total distance.
float fractionOfJourney = distCovered / journeyLength;
// Set our position as a fraction of the distance between the markers.
transform.position = Vector3.Lerp(startMarker.position, endMarker.position, fractionOfJourney);
}
}
If that doesn’t work you are going to need to take the current position and add an arbitrary distance on yourself for the end position (maybe something like this). but you would have to account for which direction you are going.
destination = transform.position + new Vector3(transform.position.x, transform.position.y, transform.position.z + 1)
ok so there is another error for the IEnumerator Move() I am a little new to unity so I do not know what the error means do I have to add a return value or
Not sure. It can sometimes be difficult as I just wrote it without testing. The best thing to do would be to use debug log to check each step is actually being called.
For example, debug log something after the w key is pressed, then debug log something else just before isMoving is set to true… then debug log something just before the coroutine starts… then debug log something in the coroutine.
The next frame in Update() (which is where you put this) it will AGAIN start ANOTHER coroutine.
Why will it do that? Because iMoving is still true!
You do not clear isMoving until the elapsed time has passed.
None of this will ever work properly the way this is architected. You absolutely do not need a coroutine, and you CERTAINLY do not want a fresh one started every frame.
I’m not sure what you are trying to do but this sounds like SUPER SUPER SUPER simple stuff, covered by literally THOUSANDS of Youtube character movement tutorials out there. I suggest you set this project aside and go legitimately work through two or three very simple movement tutorials and get familiar with the different approaches to doing this stuff. Otherwise you are going to thrash endlessly with this stuff.
ALSO, feel free to take a look around the movement examples in my proximity_buttons package. Don’t use them in your code until you understand them. They’re really simple, honest.
proximity_buttons is presently hosted at these locations: