- Home /
Moving an Object to a precise spot
I'm trying to write a coroutine to move my blocks on the X axis at a certain speed until they reach a precise spot. I can't use Lerp because it isn't precise and I would like to base the animation on speed and not time.
My math sucks and I tried a lot of different ways, but floats are making my life really difficult.
Can someone help me?
using UnityEngine;
using System;
using System.Collections;
public class QuadB : MonoBehaviour
{
[SerializeField] Transform A = null;
[SerializeField] Transform B = null;
[SerializeField] float speed = 10;
void Start ()
{
StartCoroutine("me");
}
IEnumerator me()
{
float t = Mathf.Abs(transform.position.x - B.position.x);
float direction = (t) / (Mathf.Abs(t));
Debug.Log ("direction " + direction);
float x = -8;
while (x != 8)
{
float i = (float)Math.Round((Time.deltaTime * speed) / t, 2);
x += i;
x = (float)Math.Round(x, 2);
transform.position = new Vector3(x, transform.position.y);
Debug.Log("i " + i + " x " + x);
yield return null;
}
}
}
Edit: Corrected code formatting
Answer by Bunny83 · Jun 25, 2014 at 01:48 AM
Are you aware of the Mathf.MoveTowards function? It does exactly what you want
IEnumerator me()
{
Vector3 pos = transform.position;
float target = B.position.x;
while (pos.x != target)
{
pos.x = Mathf.MoveTowards(pos.x,target, Time.deltaTime * speed);
transform.position = pos;
yield return null;
}
}
If you're interested in what black magic is used inside $$anonymous$$oveTowards... here it is:
public static float $$anonymous$$oveTowards(float current, float target, float maxDelta)
{
if ($$anonymous$$athf.Abs(target - current) <= maxDelta)
{
return target;
}
return current + $$anonymous$$athf.Sign(target - current) * maxDelta;
}
and if you say "hey, what's $$anonymous$$athf.Sign", well it's just:
public static float Sign(float f)
{
return (f < 0f) ? -1f : 1f;
}
@meat5000: I barely used it. Can't even say for sure i ever used it :D I saw it when it was implemented but i never was in need of that feature. If something was already published, why send it back? So someone else will approve it again? :D
This is some serious black magic...
Thank you very much! The code works perfectly :)
Also I understood how it works!
Answer by TehJustice · Jun 24, 2014 at 09:43 PM
You'd probably be best served by finding a tweening engine that will do this for you. HOTween is fantasic.
Your code has lots of strange stuff going on though. I just hacked this together but it might help:
float distance = transform.position.x - B.position.x;
float remainingDistance = Mathf.Abs(distance);
while (remainingDistance > 0F) {
float i = Time.deltaTime * speed * distance;
remainingDistance -= Mathf.Abs(i);
if (remainingDistance < 0F) {
if (i < 0) {
i += remainingDistance;
}
else {
i -= remainingDistance;
}
}
transform.position = new Vector3(transform.position.x - i, transform.position.y, transform.position.z);
yield return null;
}
I think you wanted to write float i = (Time.deltaTime * speed) / distance;
But it doesn't mater because it doesn't place my cube in the precise spot and also the speed changes based on the distance :(
I tried to use Itween but it makes my game laggy at the start :(
@TehJustice: Sorry but to be honest, this looks as strange as the original code :D
Your answer
Follow this Question
Related Questions
Why is my Mathf.Movetowards Coroutine executing instantly? 2 Answers
Frame rate independent animation not working with Time.deltaTime or Coroutines 1 Answer
Trying to instantiate an object after 5 seconds while holding down a button 1 Answer
Simple shooting script causing heavy lag 2 Answers
Time Manager Class Implementation Like Coroutine in Unity 1 Answer