【问题标题】:How to move cube in trajectory in Unity3D如何在 Unity3D 中沿轨迹移动立方体
【发布时间】:2019-05-14 18:27:08
【问题描述】:

当拖动鼠标移动到鼠标的某个位置及其拖动功率时,我需要使用点或箭头类型符号以轨迹运动方式移动立方体。

我使用 2D 项目中使用的代码以轨迹运动方式移动球,但它不起作用。

这是我尝试的代码

void Start()
{
    cam = Camera.main;
    cubeClick = GameObject.Find("Cube Click Area");
    trajectoryDots = GameObject.Find("Trajectory Dots");
    rb = Player.GetComponent<Rigidbody>();
    trajectoryDots.transform.localScale = new Vector3(
        initialDotSize, 
        initialDotSize, 
        trajectoryDots.transform.localScale.z);
    for (int dotNumber = 0; dotNumber < 40; dotNumber++)
    {
        Dots[dotNumber] = GameObject.Find("Dot (" + dotNumber + ")");
        if (DotSprite !=null)
        {
            Dots[dotNumber].GetComponent<SpriteRenderer>().sprite = DotSprite;
        }
    }
    for (int dotNumber = NumberOfDots; dotNumber < 40; dotNumber++)
    {
        GameObject.Find("Dot (" + dotNumber + ")").SetActive(false);
    }
    trajectoryDots.SetActive(false);


}


void Update()
{
    Ray camRay = cam.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;
    //RaycastHit2D hit = Physics2D.Raycast(cam.(Input.mousePosition), Vector2.zero);
    if (Physics.Raycast(camRay, out hit, 100f) && !cubeisClicked2)
    {
        if (hit.collider.gameObject.name == Player.name)
        {
            cubeisClicked = true;
        }
        else
        {
            cubeisClicked = false;
        }
    }
    else
    {
        cubeisClicked = false;
    }

    if (cubeisClicked2)
    {
        cubeisClicked = true;
    }

    if ((rb.velocity.x * rb.velocity.x) + (rb.velocity.y * rb.velocity.y) <= 0.0085f)
    {
        rb.velocity = new Vector2(0f, 0f);
    }
    else
    {
        trajectoryDots.SetActive(false);
    }
    cubePosition = Player.transform.position;
    if ((Input.GetKey(KeyCode.Mouse0) && cubeisClicked) && ((rb.velocity.x == 0f && rb.velocity.y == 0f)))
    {
        cubeisClicked2 = true;
        fingerPosition = cam.ScreenToWorldPoint(Input.mousePosition);
        fingerPosition.z = 0f;
        cubeFingerDiff = cubePosition - fingerPosition;
        ShotForce = new Vector2(cubeFingerDiff.x * shootingPowerX , cubeFingerDiff.y * shootingPowerY);
        if (Mathf.Sqrt((cubeFingerDiff.x * cubeFingerDiff.x) + (cubeFingerDiff.y * cubeFingerDiff.y) )>0.4f)
        {
            trajectoryDots.SetActive(true);

        }
        else
        {
            trajectoryDots.SetActive(false);
        }

        for (int dotNumber = 0; dotNumber < NumberOfDots; dotNumber++)
        {
            x1 = cubePosition.x * ShotForce.x * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
            y1 = cubePosition.y * ShotForce.y * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift) - (-Physics.gravity.y / 2f * Time.fixedDeltaTime * Time.fixedDeltaTime * (DotSeparation * dotNumber + dotShift) * (DotSeparation * dotNumber + dotShift));
            Dots[dotNumber].transform.position = new Vector3(x1, -y1, 0);
        }

        if (Input.GetKeyUp(KeyCode.Mouse0))
        {
            cubeisClicked2 = false;
            trajectoryDots.SetActive(false);

            rb.velocity = new Vector2 (ShotForce.x, ShotForce.y);;

        }


    }



}

它不起作用,它显示了如图所示的点。

它应该以用户拖动并指向要移动的位置的方式移动立方体。

【问题讨论】:

  • 它做什么而不是工作?结果与您期望的代码有何不同?
  • 请描述如何它不起作用
  • @Ruzihm 它不起作用意味着它只是显示如上图所示的点,无法通过按住帮助鼠标左键并拖动来移动点,也没有拍摄释放按钮时的立方体
  • 您将cubePosition.x * 更改为cubePosition.x +cubePosition.y * 更改为cubePosition.y + 并且单击和拖动时仍然得到相同的结果?另外,您是否将ShootingPowerXShootingPowerY 设置为0
  • @Ruzihm 我将 cubePosition.x * 更改为 cubePosition.x +,将 ShootingPowerX 更改为 6,将 ShootingPowerY 更改为 -1.5 它可以正确绘制,但不会随着鼠标移动而移动,并且不会在每个节点上跳跃鼠标离开,但有时它会离开

标签: c# unity3d game-physics


【解决方案1】:

主要的问题是使用cam.ScreenToWorldPoint(Input.mousePosition); 和透视相机总是返回相机的位置(这是一个非常常见的错误),所以不是使用鼠标位置与立方体,而是使用相机与立方体。

考虑到立方体与相机的比较位置,您需要使用另一种方法来使用鼠标的位置。

获得所需行为的一种方法是创建一个垂直于相机方向穿过立方体的平面,并查看鼠标光线与该平面相交的位置。此外,将cubeisClicked2 标志设置为 false,仅在我们实际单击平面时将其设置为 true:

cubePosition = Player.transform.position;
if ((Input.GetKey(KeyCode.Mouse0) && cubeisClicked) && ((rb.velocity.x == 0f && rb.velocity.y == 0f)))
{
    cubeisClicked2 = false;

    Plane cubePlane = new Plane(cam.transform.position - cubePosition, cubePosition);

    // reusing camRay

    // Determine if we are even hitting the plane
    float enter = 0.0f;

    if (cubePlane.Raycast(camRay, out enter))
    {
        cubeisClicked2 = true;
        fingerPosition  = camRay.GetPoint(enter);

此外,您需要在力和轨迹计算中包含 z 分量。您可能只使用shootingPowerX 来增强 z 组件的功能。还有就是我在cmets中提到的轨迹计算需要做一些改动:

        cubeFingerDiff = cubePosition - fingerPosition;
        ShotForce = new Vector3(cubeFingerDiff.x * shootingPowerX , cubeFingerDiff.y * shootingPowerY, cubeFingerDiff.z * shootingPowerX );
        if (cubeFingerDiff.magnitude>0.4f)
        {
            trajectoryDots.SetActive(true);

        }
        else
        {
            trajectoryDots.SetActive(false);
        }

        for (int dotNumber = 0; dotNumber < NumberOfDots; dotNumber++)
        {
            x1 = cubePosition.x + ShotForce.x * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
            y1 = cubePosition.y + ShotForce.y * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift) + (Physics.gravity.y / 2f * Time.fixedDeltaTime * Time.fixedDeltaTime * (DotSeparation * dotNumber + dotShift) * (DotSeparation * dotNumber + dotShift));
            z1 = cubePosition.z + ShotForce.z * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
            Dots[dotNumber].transform.position = new Vector3(x1, y1, z1);

然后,与其在同一个if 中检查GetKeyUp(KeyCode.Mouse0) 作为确定轨迹,还需要在它旁边检查是否找到轨迹:

        }
    } 
}

if (Input.GetKeyUp(KeyCode.Mouse0) && cubeisClicked2)
{
    cubeisClicked2 = false;
    trajectoryDots.SetActive(false);

    rb.velocity = new Vector3 (ShotForce.x, ShotForce.y, ShotForce.z);;

}

总而言之,它可能看起来像这样:

cubePosition = Player.transform.position;
if ((Input.GetKey(KeyCode.Mouse0) && cubeisClicked) && ((rb.velocity.x == 0f && rb.velocity.y == 0f)))
{
    cubeisClicked2 = false;
    Plane cubePlane = new Plane(cam.transform.position - cubePosition, cubePosition);

    // reusing camRay

    // Determine if we are even hitting the plane
    float enter = 0.0f;
    if (cubePlane.Raycast(camRay, out enter))
    {
        cubeisClicked2 = true;
        fingerPosition  = camRay.GetPoint(enter);

        cubeFingerDiff = cubePosition - fingerPosition;
        ShotForce = new Vector3(cubeFingerDiff.x * shootingPowerX , cubeFingerDiff.y * shootingPowerY, cubeFingerDiff.z * shootingPowerX );
        if (cubeFingerDiff.magnitude>0.4f)
        {
            trajectoryDots.SetActive(true);

        }
        else
        {
            trajectoryDots.SetActive(false);
        }

        for (int dotNumber = 0; dotNumber < NumberOfDots; dotNumber++)
        {
            x1 = cubePosition.x + ShotForce.x * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
            y1 = cubePosition.y + ShotForce.y * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift) + (Physics.gravity.y / 2f * Time.fixedDeltaTime * Time.fixedDeltaTime * (DotSeparation * dotNumber + dotShift) * (DotSeparation * dotNumber + dotShift));
            z1 = cubePosition.z + ShotForce.z * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
            Dots[dotNumber].transform.position = new Vector3(x1, y1, z1);
        }
    }         
}

if (Input.GetKeyUp(KeyCode.Mouse0) && cubeisClicked2)
{
    cubeisClicked2 = false;
    trajectoryDots.SetActive(false);

    rb.velocity = new Vector3 (ShotForce.x, ShotForce.y, ShotForce.z);;

}

由于这会根据您所指向的cubePlane 上的距离计算拍摄的力量,因此当相机越远时,您将能够拍摄得更有力。

这可能不是您想要的行为,但如果相机始终与立方体保持相同的距离,那应该不是问题。

如果这不是一个可接受的限制,您可以按照将ShotForce 除以立方体和相机之间的距离并根据需要增加shootingPowerXshootingPowerY 的方法来做一些事情。如果您自己找不到好的解决方案,最好在单独的问题中提出。

【讨论】:

  • 我是否应该用您的代码替换我的所有代码,包括以下内容: Ray camRay = cam.ScreenPointToRay(Input.mousePosition); RaycastHit 命中; //RaycastHit2D hit = Physics2D.Raycast(cam.(Input.mousePosition), Vector2.zero);等等……
  • 我认为你的其余代码应该已经可以工作了,只需替换 Update 之后的所有内容,包括 cubePosition = Player.transform.position;
  • 我做到了,点现在根据鼠标自行定位,但在离开时不会移动立方体
  • @EngrUmair 我编辑了我的答案,希望能解决这个问题。尝试再次复制整个内容。
  • 非常感谢,它开始工作了。我需要问的最后一件事是我需要将点重置为投掷前的原始设置,并且它的位置将始终靠近立方体。
猜你喜欢
  • 2014-09-12
  • 1970-01-01
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
相关资源
最近更新 更多