如何让Unity中的GameObjects平滑地在屏幕上平移?

时间:2018-04-17 19:51:23

标签: c# unity3d unity3d-2dtools

基本上,我有一个游戏,门票出现在屏幕的顶部。当一张票完成后,它就会被销毁,如果剩下的票之间存在差距,则票据会向下滑动以填补空白。我实际上它工作得很好,但它们只是跳到位置而且看起来不太漂亮。

如何将物体平稳地移动到目标位置?我已经尝试弄乱LerpSmoothdamp,但这两个似乎都产生了奇怪的结果(门票到处都是。这是我正在使用的相关代码:

    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执行此操作,但我必须遗漏一些内容。

3 个答案:

答案 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));

enter image description here

答案 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();
    }
}