Reputation: 37
I've got some simple code here. The issue I am having is that the images contract to the center (local position Vector3.zero) at what seems to be nearly double the speed as they move away from the center. I believe I am using them same logic to move them so I was wondering if anyone could tell me what could cause such behavior.
Any advice on making the code itself better is also welcome but my main concern is the speed of the interpolation. I probably should have passed the current time via parameter instead of the total time but you know... I do not make perfect decisions the first time every time.
The specific lines in questions:
IEnumerator ContractImages(float totalTime)
{
yield return m_WaitForEndOfFrame;
m_CurrentContractionTime += Time.deltaTime;
float t = m_CurrentContractionTime / totalTime;
Debug.Log(string.Format("Expansion Rate Factor: {0}", t));
Debug.Log(string.Format("Current Expansion Time: {0}", m_CurrentContractionTime));
for (int i = 0; i < m_MovingImages.Length; i++)
{
var r = m_MovingImages[i].GetComponent<RectTransform>(); //Optimize
r.localPosition = Vector3.Lerp(r.localPosition, Vector3.zero, t);
}
if (m_CurrentContractionTime < totalTime)
m_ContractionRoutine = StartCoroutine(ContractImages(totalTime));
else if (m_ContractionRoutine != null)
{
StopCoroutine(m_ContractionRoutine);
InvokeContractionComplete();
m_CurrentContractionTime = 0;
}
}
IEnumerator ExpandImages(float totalTime)
{
yield return m_WaitForEndOfFrame;
m_CurrentExpansionTime += Time.deltaTime;
float t = m_CurrentExpansionTime / totalTime;
Debug.Log(string.Format("Expansion Rate Factor: {0}", t));
Debug.Log(string.Format("Current Expansion Time: {0}", m_CurrentExpansionTime));
for (int i = 0; i < m_MovingImages.Length; i++)
{
var r = m_MovingImages[i].GetComponent<RectTransform>(); //Optimize
r.localPosition = Vector3.Lerp(Vector3.zero, m_StartingVectors[i], t);
}
if (m_CurrentExpansionTime < totalTime)
m_ContractionRoutine = StartCoroutine(ExpandImages(totalTime));
else if (m_ContractionRoutine != null)
{
StopCoroutine(m_ExpansionRoutine);
InvokeExpansionComplete();
Debug.Log("Expansion Complete: " + totalTime / m_CurrentExpansionTime);
m_CurrentExpansionTime = 0;
}
}
Upvotes: 0
Views: 35
Reputation: 20259
Well the first difference that seems obvious is that in ContractImages
, you lerp from the current position, which grows ever closer to the destination, and in ExpandImages
, you lerp from a constant position. So of course the ContractImages
lerp will progress faster in the middle of the lerp.
For instance, assuming the expand position is new Vector3(1f,0f,0f)
and totalTime
is 1f
, and Time.deltaTime
is 0.1f
:
r.localPosition = Vector3.Lerp(new Vector3(1f,0f,0f), Vector3.zero, 0.1f);
// = new Vector3(0.9f, 0f, 0f);
// dist = 0.1f
r.localPosition = Vector3.Lerp(Vector3.zero, new Vector3(1f,0f,0f), 0.1f);
// = new Vector3(0.1f, 0f, 0f);
// dist = 0.1f
r.localPosition = Vector3.Lerp(new Vector3(0.9f,0f,0f), Vector3.zero, 0.2f);
// = new Vector3(0.78f, 0f, 0f);
// dist = 0.22f
r.localPosition = Vector3.Lerp(Vector3.zero, new Vector3(1f,0f,0f), 0.2f);
// = new Vector3(0.2f, 0f, 0f);
// dist = 0.2f
r.localPosition = Vector3.Lerp(new Vector3(0.78f,0f,0f), Vector3.zero, 0.3f);
// = new Vector3(0.546f, 0f, 0f);
// dist = 0.454f
r.localPosition = Vector3.Lerp(Vector3.zero, new Vector3(1f,0f,0f), 0.3f);
// = new Vector3(0.3f, 0f, 0f);
// dist = 0.3f
Basically, you should consider lerping between constants in both cases:
IEnumerator ContractImages(float totalTime)
{
yield return m_WaitForEndOfFrame;
m_CurrentContractionTime += Time.deltaTime;
float t = m_CurrentContractionTime / totalTime;
Debug.Log(string.Format("Expansion Rate Factor: {0}", t));
Debug.Log(string.Format("Current Expansion Time: {0}", m_CurrentContractionTime));
for (int i = 0; i < m_MovingImages.Length; i++)
{
var r = m_MovingImages[i].GetComponent<RectTransform>(); //Optimize
r.localPosition = Vector3.Lerp(m_StartingVectors[i], Vector3.zero, t);
}
if (m_CurrentContractionTime < totalTime)
m_ContractionRoutine = StartCoroutine(ContractImages(totalTime));
else if (m_ContractionRoutine != null)
{
StopCoroutine(m_ContractionRoutine);
InvokeContractionComplete();
m_CurrentContractionTime = 0;
}
}
Upvotes: 1