Vector3.Lerp in C#in unity不能平滑移动只是从一个位置捕捉到另一个位置

时间:2017-05-29 23:46:18

标签: c# android unity3d

我正在制作一款无穷无尽的跑步者,这款游戏非常适合安卓IronMan游戏。玩家将沿着球道直线飞行,并能够向左,向右,向上和向下移动。我设法将屏幕分成9个部分并实现一个小控制系统,识别玩家在哪里以及他想要移动的位置,如果他/她被允许移动到那里我设法让玩家移动到所需屏幕上的位置,但不是逐渐从一个点移动到另一个点,游戏对象只是从一个位置捕捉到另一个位置。请在下面找到我的代码,以便向一个方向移动:

public class PlayerControl : MonoBehaviour
{

// Declare Control Input
public KeyCode moveL;
public KeyCode moveR;
public KeyCode moveU;
public KeyCode moveD;

// Set movement distance
private float verticalIncrement = 3.0f;
private float horizontalIncrement = 5.0f;

// Set initial internal position of the craft
private int laneNum = 1;
private int rowNum = 1;

// Declare player Game object
GameObject spaceCraft;

// Set input lock
bool pressLockOn = false;

// Use this for initialization
void Start()
{
    spaceCraft = GameObject.FindGameObjectWithTag("Player");
}

// Update is called once per frame
void Update()
{        
    if (Input.GetKeyDown(moveR))
    {
        if (laneNum < 2)
        {
            // Retrieve craft current position coordinates
            float craftPositionX = spaceCraft.transform.localPosition.x;
            float craftPositionY = spaceCraft.transform.localPosition.y;

            // Save craft's desired position coordinates as string for comparison
            string newCraftPositionString = (craftPositionX + horizontalIncrement) + "" + craftPositionY;

            // Declare target box position coordinates for comparison
            string targetPositionString = null;

            // Find desired target box based on player's location and button pressed
            for (int i = 0; i < Initialization.positionCubesArray.Length; i++)
            {
                for (int j = 0; j < Initialization.positionCubesArray[i].Length; j++)
                {
                    // Declare temp GameObject to store desired target box 
                    GameObject target = Initialization.positionCubesArray[i][j];

                    // Retrieve target box location coordinates
                    float boxPosX = target.GetComponent<Transform>().localPosition.x;
                    float boxPosY = target.GetComponent<Transform>().localPosition.y;

                    // Save target box's coordinates as string for comparison
                    boxPositionString = boxPosX + "" + boxPosY;

                    // Check if craft's desired position matches found target
                    if (newCraftPositionString.Equals(targetPositionString))
                    {
                        // Set input lock on
                        pressLockOn = true;

                        // Move player's craft to desired location
                        spaceCraft.transform.localPosition = Vector3.Lerp(spaceCraft.transform.localPosition, target.transform.localPosition, 1f);                            

                        // Start coroutine to delay input lock for half a second
                        StartCoroutine(stopTime(0.5f));

                        // Check if craft traveled to desired location
                        if ((craftPositionX + "" + craftPositionY).Equals(newCraftPositionString) )
                        {
                            // Update internal position of the craft
                            laneNum++;  
                        }
                    }
                }
            }
        }
    }
...
}

IEnumerator stopTime(float amount)
{       
    yield return new WaitForSeconds(amount);
    pressLockOn = false;
}

我也尝试过本教程后的另一种方法:

https://www.youtube.com/watch?v=Zb7Th_H7bvw

但它也不起作用,并且根本不会移动我的玩家,因为旅程分数总是等于0.我也尝试将移动物体逻辑输出到循环中但也没有效果。请在下面找到更新的代码:

// Update is called once per frame
void Update()
{ 
    if (Input.GetKeyDown(moveR))
    {
        if (laneNum < 2)
        {
            // Declare target Dame object
            GameObject target;

            // Retrieve craft position coordinates
            float craftPositionX = spaceCraft.transform.localPosition.x;
            float craftPositionY = spaceCraft.transform.localPosition.y;

            // Retrieve desired craft's postiotn
            string newCraftPositionString = (craftPositionX + horizontalIncrement) + "" + craftPositionY;

            // Declare target box string for comparison
            string boxPositionString = null;

            // Declare initial temp i and j to export target game object from the loops
            int tempI = 0;
            int tempJ = 0;

            // Search for target game objects in 2D array
            for (int i = 0; i < Initialization.positionCubesArray.Length; i++)
            {
                // Setup found target flag
                bool foundTarget = false;
                for (int j = 0; j < Initialization.positionCubesArray[i].Length; j++)
                {
                    // Retrieve each target's coordinates
                    float boxPosX = Initialization.positionCubesArray[i][j].GetComponent<Transform>().localPosition.x;
                    float boxPosY = Initialization.positionCubesArray[i][j].GetComponent<Transform>().localPosition.y;

                    // Target coordinates string for comparison
                    boxPositionString = boxPosX + "" + boxPosY;

                    // Check if target's coordinates matches desired location's coordinates
                    if (newCraftPositionString.Equals(boxPositionString))
                    {                    
                        // Set temp i and j to export found target out off the loop
                        tempI = i;
                        tempJ = j;
                        print("Found Target\n " + tempI + " " + tempJ);
                        print("Target Postion: " + boxPositionString);

                        // Set found target flag to true
                        foundTarget = true;

                        // Break inner loop
                        break;
                    }
                }

                // Break outter loop
                if (foundTarget)
                {
                    break;
                }
            }

            print("New Crafft Position: " + newCraftPositionString + "\nTarget Position: " + boxPositionString);


            // Again chack if target's coordinates matches desired location's coordinates
            if (newCraftPositionString.Equals(boxPositionString))
            {
                // Retrieve found target from 2D array with temp i and j found in 2D for-loop
                target = Initialization.positionCubesArray[tempI][tempJ];

                // Set input lock on
                pressLockOn = true;

                float startTime = Time.time;
                float totalDistance = Vector3.Distance(spaceCraft.transform.localPosition, target.transform.localPosition);
                float currentDurration = Time.time - startTime;
                float journeyFraction = currentDurration / totalDistance;

                print("Start time: " + startTime + " | Total Distance: " + totalDistance
                    + "\nCurrent Durration: " + currentDurration + " | Journey fraction: " + journeyFraction);
                spaceCraft.transform.localPosition = Vector3.Lerp(spaceCraft.transform.localPosition, target.transform.localPosition, journeyFraction);

                // Start coroutine to delay input lock
                StartCoroutine(stopTime(0.5f));

                // Update internal craft coordinates
                if ((craftPositionX + "" + craftPositionY).Equals(newCraftPositionString))
                {
                    laneNum++;
                }
            }
        }
    }

我也尝试将startTime变量移动到Start方法,将currentDuration时间移动到更新方法的开头,就像在教程中一样,我的播放器会移动但不会移动到所需的位置,它只会移动很小但从未到达目标它会使整个移动的“系统”崩溃。

2 个答案:

答案 0 :(得分:2)

Lerp将通过因子插入两个值。例如,如果Lerp在0到20之间,因子为0.5,则结果为10,0为0,1为20,依此类推。

为什么我这么说?因为在您的代码中,您只需Lerp因子为1.0f,这将只返回最终值。

如果你想要一个平滑的插值,你必须以所需的速度从0到1“行进”。

答案 1 :(得分:1)

好的,我修好了它,它正在工作。现在代码也更清晰了。问题与我按下按钮的事实有关,而且位置只是更新一次。负责调用Lerp方法的代码不再在update方法中调用。