【问题标题】:Random Movement Script causes Unity to freeze随机移动脚本导致 Unity 冻结
【发布时间】:2019-11-03 16:12:38
【问题描述】:

我有一个由 16 个图块组成的网格。现在基本上我希望用户通过在网格内的选择上随机移动来找到通往最终位置的路径。

到目前为止,我设法创建了向上、向下、向左和向右移动台阶的功能。当我尝试以随机运动进行编码时,就会出现问题。理想情况下,这是以他不能越界的方式设置的。

这就是我要做的:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Move : MonoBehaviour

{
    void Up()
    {
        //get the Input from Horizontal axis
        float horizontalInput = Input.GetAxis("Horizontal");
        //get the Input from Vertical axis
        float verticalInput = Input.GetAxis("Vertical");

        //update the position
        transform.position = transform.position + new Vector3(0, 1.5f, 0);

        //output to log the position change
        Debug.Log(transform.position);
    }

    void Down()
    {
        //get the Input from Horizontal axis
        float horizontalInput = Input.GetAxis("Horizontal");
        //get the Input from Vertical axis
        float verticalInput = Input.GetAxis("Vertical");

        //update the position
        transform.position = transform.position + new Vector3(0, -1.5f, 0);

        //output to log the position change
        Debug.Log(transform.position);
    }

    void Left()
    {
        //get the Input from Horizontal axis
        float horizontalInput = Input.GetAxis("Horizontal");
        //get the Input from Vertical axis
        float verticalInput = Input.GetAxis("Vertical");

        //update the position
        transform.position = transform.position + new Vector3(-1.5f, 0, 0);

        //output to log the position change
        Debug.Log(transform.position);
    }

    void Right()
    {
        //get the Input from Horizontal axis
        float horizontalInput = Input.GetAxis("Horizontal");
        //get the Input from Vertical axis
        float verticalInput = Input.GetAxis("Vertical");

        //update the position
        transform.position = transform.position + new Vector3(1.5f, 0, 0);

        //output to log the position change
        Debug.Log(transform.position);
    }



    void Start()
    {
        var finalLocation = new Vector3(-0.5f, 0.5f, 0);
        var currentLocation = transform.position;

        while (currentLocation != finalLocation)
        {
            int randomNum = Random.Range(0, 3);

            if (randomNum == 0)
            {
                Up();
            }
            else if (randomNum == 1)
            {
                Down();
            }
            else if (randomNum == 2)
            {
                Left();
            }
            else if (randomNum == 3)
            {
                Right();
            }

        }
    }
}

更新的工作代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Move : MonoBehaviour

{
    void Up()
    {
        //update the position
        transform.position = transform.position + new Vector3(0, 1.5f, 0);

        //output to log the position change
        Debug.Log(transform.position);
    }

    void Down()
    {
        //update the position
        transform.position = transform.position + new Vector3(0, -1.5f, 0);

        //output to log the position change
        Debug.Log(transform.position);
    }

    void Left()
    {
        //update the position
        transform.position = transform.position + new Vector3(-1.5f, 0, 0);

        //output to log the position change
        Debug.Log(transform.position);
    }

    void Right()
    {
        //update the position
        transform.position = transform.position + new Vector3(1.5f, 0, 0);

        //output to log the position change
        Debug.Log(transform.position);
    }



    void Update()
    {
        var finalLocation = new Vector3(2.5f, 2.0f, -2.0f);
        var currentLocation = transform.position; 
        int randomNum = Random.Range(0, 4);

        if (currentLocation != finalLocation) { 
                if (randomNum == 0)
            {
                Up();
            }
            else if (randomNum == 1)
            {
                Down();
            }
            else if (randomNum == 2)
            {
                Left();
            }
            else if (randomNum == 3)
            {
                Right();
            }
            return;
        }
    }
}

我的最后一个问题是如何将这种随机性限制为仅坚持网格而不脱离网格。有什么想法吗?

【问题讨论】:

  • while 中可能存在问题,并且当前位置可能总是与最终位置不同,因此脚本陷入无限循环
  • 还有,你为什么要查询Input
  • @3Dave 有什么用?

标签: c# unity3d


【解决方案1】:

这里有一些问题:

  • horizontalInputverticalInput 永远不会在您的函数中使用

  • while(currentLocation != finalLocation) 这种情况在某些情况下可能会失败。 Unity 使用 float 作为坐标,这意味着它需要在同一位置,每个小数位都必须相同。

  • Random.Range(0, 3) 将返回一个介于 0(包括)和 3(不包括)之间的随机数,因此唯一可能的值将是 0、1 和 2。脚本永远不会调用 Right() 函数。

Unity 默认使用一个线程来运行您的脚本,如果您放置一个 while 循环将对象移动到某个位置,它将冻结整个游戏,直到对象位于正确的位置。我建议你使用Update() 函数,它每帧都会被调用。

【讨论】:

  • every decimal place need to be the same. 这并不完全正确:== operator for Vector3 使用 0.00001 的精度来表示相等。当以固定的步长移动对象时,至少不是完全不可能到达这里的某个位置(当然你是对的,一般来说代码没有多大意义)
  • 您可能也不想在Update 中调用它。以1.5 为单位将每一帧移动到新位置会产生巨大的抖动。
  • 是的,他需要乘以 Time.deltaTime 和输入值,但这不是问题。
  • 嗨@BlackDereker 感谢您的意见。我接受了您的建议并实施了更改,但是更新功能仍然崩溃。 time.deltatime 是什么意思?谢谢!
  • 你需要去掉while循环并用if替换它
【解决方案2】:

几个问题:

  1. 您的对象卡在无限的while 循环中,因为在您的随机移动脚本到达其finalLocation 之前,它不允许退出(并执行诸如渲染帧、获取用户输入等操作)。您没有给游戏时间做其他事情。
    您几乎肯定希望这是一个协程或 Update 函数。
  2. Random.Range 返回一个在min(包括)到max(不包括)范围内的int,所以你对它的调用永远不会返回3

【讨论】:

  • Random.Rangeint 值作为参数返回 int 值。第二个参数是独占的,所以 Random.Range(0,3) 可以返回任何值 0, 1, 2 .. 所以它肯定会永远返回 3
  • 你说得对,之前我只看到第一个带float参数的。
  • 嗨@Draco18s 感谢您的意见。我接受了您的建议并实施了更改,但是更新功能仍然崩溃。
  • @xalalau 你是怎么做到的?根本不应该有while 循环!
  • @derHugo 我设法使它工作谢谢。见上面的代码。一个问题也许有人可能会引导我朝着正确的方向前进,我希望“用户”能够在网格内移动,而不是像现在这样离开网格。
猜你喜欢
  • 2012-02-15
  • 1970-01-01
  • 2020-05-16
  • 2019-12-15
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多