- Home /
Translate and Yield giving inaccurate results?
I need to transform.Translate (x, 0, 0) and yield (x seconds), and that seems to work fine and all, but I also need to incorporate a "fake-slow motion" effect (without using Time.timeScale) and my solution was to
transform.Translate (x * y, 0, 0) and yield (x / y seconds) where y is a fraction.
However produces different results from the original x translation and yield because the object ends up in a different place then where it should be. If I'm correct, multiplying and dividing the translate and yield should end up in the same place over a longer amount of time... right?
Thanks in advance!
A 2D puzzle platformer inspired by Inception with multiple "levels" each corresponding to different parts of the brain. And as you go farther down, just like in Inception, the higher levels become more and more slow, meaning you have to time things just right to make changes in the dreams within dreams.
Thanks for asking :D
Your logic does not make sense to me. If y is a fraction, it mean each step will be shorter, and each yield will be longer. I assume you do this in a loop. What is your end condition for the loop? Why not just increase the yield and leave the Translate() alone?
Why do this with yield, when you can just change your movement speed? Don't you use Time.deltaTime
?
$$anonymous$$aybe this will help:
function Update () {
if (move)
{
if (level == 1)
{
newSpeed = (-speed * mc.GetComponent(LevelController).value1);
waitTime = time / mc.GetComponent(LevelController).value1;
transform.Translate( newSpeed * Time.deltaTime, 0, 0);
}
}
}
function Activate () {
move = true;
if (level == 1)
yield Wait (time);
// / mc.GetComponent(LevelController).value1);
move = false;
}
function Wait (ntime : float) {
waitTime = ntime;
var t = 0.0;
while (t < waitTime) {
t += Time.deltaTime;
yield;
}
}
Answer by SomeGuy22 · Apr 06, 2013 at 12:37 AM
Okay so instead I just used a trigger system that turns off the movement instead of trying to time it, so now it only has to reduce the speed and no matter what speed when it hits the trigger it'll stop at that point.
Answer by Bunny83 · Apr 03, 2013 at 02:05 AM
I'm wondering why you use a yield in the first place... To get a smooth movement you should update your position every visual frame (so each update). When using WaitForSeconds the movement just gets choppy.
If I can't use Time.timeScale i would create a deltaTime wrapper class. Every object that has a movement function needs to use a wrapper instead of Time.deltaTime.
Something like that:
// C#
public class DTProvider
{
private static Stack<float> m_Layers = new Stack<float>();
private static float m_CurrentRealTime = 1.0f;
public static void AddLayer(float aScale)
{
m_Layers.Push(m_CurrentRealTime);
m_CurrentRealTime *= aScale;
}
public static void RemoveLayer()
{
if (m_Layers.Count > 0)
m_CurrentRealTime = m_Layers.Pop();
}
private float m_Scale = 1.0f;
public DTProvider()
{
m_Scale = 1.0f / m_CurrentRealTime;
}
public DTProvider(float aScale)
{
m_Scale = aScale;
}
public float DT
{
get
{
return Time.deltaTime * m_CurrentRealTime * m_Scale;
}
}
public static implicit operator float(DTProvider aProvider)
{
return aProvider.DT;
}
}
Every script that controls movement should create such a wrapper in Awake. That way it's movement is bound to the current time layer. All movement is simply multiplied with the DT value of the provider. When a new layer is added it will become the new "realtime" and everything from the "old" layer will get slower. When you remove a layer, objects on a deeper layer will get faster.
A movement script could look like this:
public class Movement : UnitySingleton<App>
{
DTProvider DT;
void Awake()
{
DT = new DTProvider();
}
void Update()
{
transform.Translate(5.0f*DT, 0, 0);
}
}
You can also create a provider for a certain timescale:
DT = new DTProvider(4.0f);
this would make the object move 4 times faster than realtime. Now when you add two layers of 0.5f the object would move at normal speed since 0.5f 0.5f == 0.25f. Since the object's private timescale is 4 the result will be 1.0f (==0.25f 4.0f). If you add another layer of 0.5f the speed will continue to slow down.
Thank you I understand what you're saying, but I'm talking about turning the movement on and off which means yielding to change the "move" variable off when an external script turns it on with a function. I don't see how I could use any other method to turn off movement after a set amount of time.... unless I used Triggers which could be a last resort, but I don't see why I can't wait for a scaled amount of time and then turn off the movement variable.