基本上,我有一个游戏,门票出现在屏幕的顶部。当一张票完成后,它就会被销毁,如果剩下的票之间存在差距,则票据会向下滑动以填补空白。我实际上它工作得很好,但它们只是跳到位置而且看起来不太漂亮。
如何将物体平稳地移动到目标位置?我已经尝试弄乱Lerp
和Smoothdamp
,但这两个似乎都产生了奇怪的结果(门票到处都是。这是我正在使用的相关代码:
public void SlideRail()
{
ticketList.RemoveAll(x => x == null);
int count = ticketList.Count;
for (int i = destroyedIndex; i < ticketList.Count; i++)
{
if (ticketList[i] != null)
{
ticketList[i].transform.Translate(Vector3.left * 35);
ticketList[i].GetComponent<Ticket>().index--;
}
}
indexer = railPosition.IndexOf(ticketList.Last().GetComponent<Ticket>().item_pos);
up = false;
}
DestroyedIndex是被销毁对象的索引(因此我们只在列表中移动对象) Up是一个激活SlideRail()的标志,当它设置为false时,方法结束,下一个方法继续。
然后在Update()方法中调用SlideRail:
void Update()
{
if (up && ticketList.Count > 2)
SlideRail();
if (Time.time > nextTicket)
{
nextTicket = Time.time + timeBetweenTickets;
StartCoroutine(WaitToPrint());
CreateTicket();
UpdatePosition();
}
}
我觉得我应该可以使用Translate
执行此操作,但我必须遗漏一些内容。
答案 0 :(得分:1)
通过这样的移动,您通常应该包含Time.deltaTime
(作为翻译中的一个因素)来将移动绑定到帧速率。 [编辑:将这句话翻译为framerate-independant,这就是我的意思。]
现在,就实际而言,看起来你只在一帧中进行了移动,因此你得到了这个跳跃(你总是在up
的末尾将SlideRail
设置为假。) / p>
这样做的一种可能方法是在触发时指定目标位置(任务完成,需要翻转),然后继续为每个对象调用ticketList[i].transform.position = Vector3.MoveTowards(ticketList[i].transform.position, targetPosition, speed * Time.deltaTime);
(由“到达目标位置”检查框架,例如使用if(Vector3.Distance(ticketList[i].transform.position, targetPosition) > someThreshold)
。你可以在此处添加一个else来直接设置在阈值范围内的位置(使阈值变小,使其不可见,例如0.1f),尽管你通常只需要这样的非线性函数,如lerp在最后减速并且可以停止。[编辑:由于浮点不精确,实际上使用阈值实际上总是一个好主意。]
答案 1 :(得分:0)
使用iTween,可将其简化为一行调用:
iTween.MoveTo(someGameObject, iTween.Hash("y", targetY,
"islocal", true,"easetype", iTween.EaseType.spring,
"time", 0.2f));
答案 2 :(得分:0)
我之前为自己写了这段代码,也许对你有帮助。
using System;
using System.Collections;
using UnityEngine;
public class MoveController : MonoBehaviour
{
public float moveTime;
public AnimationCurve moveSpeedCurve;
public AnimationCurve movePositionCurve;
public void StartMoving(Vector2 destination, Action action = null)
{
StartCoroutine(Move(destination, action));
}
IEnumerator Move(Vector3 destination, Action action = null)
{
float currentTime = 0;
float perc = 0;
Vector3 currentPos = transform.localPosition;
while (perc != 1)
{
currentTime += Time.deltaTime;
if (currentTime > moveTime)
{
currentTime = moveTime;
}
perc = moveSpeedCurve.Evaluate(currentTime / moveTime);
transform.localPosition = Vector2.LerpUnclamped(currentPos, destination, movePositionCurve.Evaluate(perc));
yield return null;
}
if (action != null)
action();
}
}