为什么我的 3D 对象夹不能统一工作?

发布于 2025-01-13 07:46:13 字数 3162 浏览 2 评论 0原文

摘要:我正在尝试统一的东西以更好地理解它。我创建了一个带有刚体的 3d 对象并冻结了 y 轴。我将相机放置在向下看 3D 对象的位置,该对象可以使用 x 轴和 z 轴向左、向右、向上、向下移动。

问题:问题是玩家超出了屏幕的边界。

这是我的代码,它是基于我自己的理解(在统一手册中)和其他有相同问题的人的代码。

private Vector3 transformPos;

void LateUpdate () 
{
    //Defined the boundaries of the screen by using ViewPortToWorldPoint. I tried ViewportToWorldPoint as well and it did not work
    float left = Camera.main.WorldToViewportPoint(Vector3.zero).x;
    float right = Camera.main.WorldToViewportPoint(Vector3.one).x;
    float top = Camera.main.WorldToViewportPoint(Vector3.zero).y;
    float bottom = Camera.main.WorldToViewportPoint(Vector3.one).y;

    //Brought the player transform from World units to screen unit. Where x is x, z from the 3d object acts as y, and y is z.
    transformPos = Camera.main.WorldToViewportPoint (transform.position);
    //This debug was to check if z is y in the ViewportPoint and it was
    Debug.Log(transformPos);

    float x = transformPos.x;
    //Calling it z because I dont wanna confuse myself when I convert it back
    float z = transformPos.y;
    
    //This is where I start the clamping using if statements
    if(transformPos.x <= left)
    {
        x = Mathf.Clamp(transformPos.x, 0.1f,0.9f);
    }
    else if(transformPos.x >= right)
    {
        x = Mathf.Clamp(transformPos.x, 0.1f,0.9f);
    }

    if(transformPos.y <= top)
    {
        z = Mathf.Clamp(transformPos.y, 0.1f,0.9f);
    }
    else if( transformPos.y >= bottom)
    {
        z = Mathf.Clamp(transformPos.y, 0.1f,0.9f);
    }

    //And then finally I convert it back to world unit where the values is just placed in. x is x, y of the 3d object remains the same, and z 
    transform.position = Camera.main.ViewportToWorldPoint(new Vector3(x,transform.position.y,z));
    
}

下图是我从这段代码中得到的结果:

在此处输入图像描述

正如您从我的主摄像头右下方看到的那样,它完全超出了我的屏幕范围,我无法移动它。所以我的代码显然有问题,但我不明白我错在哪里。

编辑 #1

图片中的立方体是我用作播放器的立方体

编辑 #2

下面的代码是我与上述脚本一起附加到播放器上的播放器移动脚本。我认为这并不冲突,但以防万一。移动也有一点问题(我正在尝试使用手机倾斜功能移动播放器),但我也在尝试修复它

  Rigidbody playerRigidbody;

public float speed = 10;
private Vector3 movement;
private Vector3 tilt ;


// Start is called before the first frame update
void Start()
{
    playerRigidbody = GetComponent<Rigidbody>();
}

// Update is called once per frame
void Update()
{
    tilt = Input.acceleration.normalized;
    tilt = Quaternion.Euler(90f, 0, 0) * tilt;
    //movement = new Vector3(Input.acceleration.normalized.x, 0.0f, 0.0f);
}

void FixedUpdate()
{

    //  horizontal movement code through device rotation
    //var movement = new Vector3(Input.acceleration.normalized.x, 0.0f, Input.acceleration.normalized.z);
    //playerRigidbody.velocity = movement * speed;
    MoveCharacter(tilt);

}

private void MoveCharacter(Vector3 direction)
{
    //playerRigidbody.velocity = movement * speed;
    playerRigidbody.MovePosition(transform.position + (direction * speed * Time.deltaTime));
}

Summary: I'm trying out stuff in unity to better understand it.I created a 3d object with a rigidbody and froze the y axis. I placed to camera to look downwards towards the 3d object where the object can move left, right and up,down using the x and z axis.

Problem: The problem is the player is going out of the boundaries of the screen.

This is my code which I have based from my own understanding (in the unity manuals) and from other peoples code that had the same problem.

private Vector3 transformPos;

void LateUpdate () 
{
    //Defined the boundaries of the screen by using ViewPortToWorldPoint. I tried ViewportToWorldPoint as well and it did not work
    float left = Camera.main.WorldToViewportPoint(Vector3.zero).x;
    float right = Camera.main.WorldToViewportPoint(Vector3.one).x;
    float top = Camera.main.WorldToViewportPoint(Vector3.zero).y;
    float bottom = Camera.main.WorldToViewportPoint(Vector3.one).y;

    //Brought the player transform from World units to screen unit. Where x is x, z from the 3d object acts as y, and y is z.
    transformPos = Camera.main.WorldToViewportPoint (transform.position);
    //This debug was to check if z is y in the ViewportPoint and it was
    Debug.Log(transformPos);

    float x = transformPos.x;
    //Calling it z because I dont wanna confuse myself when I convert it back
    float z = transformPos.y;
    
    //This is where I start the clamping using if statements
    if(transformPos.x <= left)
    {
        x = Mathf.Clamp(transformPos.x, 0.1f,0.9f);
    }
    else if(transformPos.x >= right)
    {
        x = Mathf.Clamp(transformPos.x, 0.1f,0.9f);
    }

    if(transformPos.y <= top)
    {
        z = Mathf.Clamp(transformPos.y, 0.1f,0.9f);
    }
    else if( transformPos.y >= bottom)
    {
        z = Mathf.Clamp(transformPos.y, 0.1f,0.9f);
    }

    //And then finally I convert it back to world unit where the values is just placed in. x is x, y of the 3d object remains the same, and z 
    transform.position = Camera.main.ViewportToWorldPoint(new Vector3(x,transform.position.y,z));
    
}

The picture below is what I got from this code:

enter image description here

As you can see from my main camera down right, it is completely outside the bounds of my screen and I cannot move it. So there is obviously something wrong with my code, but yet I don't understand where I am wrong.

Edit #1

The cube in the picture is the one I am using as my player

Edit #2

The code below is the player movement script I've attached on my player along with the above script. I don't think it is conflicting with it but just in case. The movement also has a bit of a problem (I'm trying to move the player using the phone tilt function), but I'm trying to fix it as well

  Rigidbody playerRigidbody;

public float speed = 10;
private Vector3 movement;
private Vector3 tilt ;


// Start is called before the first frame update
void Start()
{
    playerRigidbody = GetComponent<Rigidbody>();
}

// Update is called once per frame
void Update()
{
    tilt = Input.acceleration.normalized;
    tilt = Quaternion.Euler(90f, 0, 0) * tilt;
    //movement = new Vector3(Input.acceleration.normalized.x, 0.0f, 0.0f);
}

void FixedUpdate()
{

    //  horizontal movement code through device rotation
    //var movement = new Vector3(Input.acceleration.normalized.x, 0.0f, Input.acceleration.normalized.z);
    //playerRigidbody.velocity = movement * speed;
    MoveCharacter(tilt);

}

private void MoveCharacter(Vector3 direction)
{
    //playerRigidbody.velocity = movement * speed;
    playerRigidbody.MovePosition(transform.position + (direction * speed * Time.deltaTime));
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鲸落 2025-01-20 07:46:13
private Vector3 transformPos;

void LateUpdate()
{
    //Defined the boundaries of the screen by using ViewPortToWorldPoint. I tried ViewportToWorldPoint as well and it did not work
    float LeftBottom = 1;
    float RightBottom = 0;
    float LeftTop = 1;
    float RightTop = 0;
    Debug.Log(
quot;Left: {LeftBottom} \n Right: {RightBottom} \n Top: {LeftTop} \n Bottom: {RightTop}");
    //Brought the player transform from World units to screen unit. Where x is x, z from the 3d object acts as y, and y is z.
    transformPos = Camera.main.WorldToViewportPoint(transform.position);
    //This debug was to check if z is y in the ViewportPoint and it was
    Debug.Log(transformPos);

    float x = transformPos.x;
    //Calling it z because I dont wanna confuse myself when I convert it back
    float z = transformPos.y;

    //This is where I start the clamping using if statements
    if (transformPos.x <= LeftBottom)
    {
        x = Mathf.Clamp(transformPos.x, 0.1f, 0.9f);
        Debug.Log(x);
    }
    else if (transformPos.x >= RightBottom)
    {
        x = Mathf.Clamp(transformPos.x, 0.1f, 0.9f);
    }

    if (transformPos.y <= LeftTop)
    {
        z = Mathf.Clamp(transformPos.y, 0.1f, 0.9f);
    }
    else if (transformPos.y >= RightTop)
    {
        z = Mathf.Clamp(transformPos.y, 0.1f, 0.9f);
    }

    //And then finally I convert it back to world unit where the values is just placed in. x is x, y of the 3d object remains the same, and z 
    transform.position = Camera.main.ViewportToWorldPoint(new Vector3(x, z, 1));

}
private Vector3 transformPos;

void LateUpdate()
{
    //Defined the boundaries of the screen by using ViewPortToWorldPoint. I tried ViewportToWorldPoint as well and it did not work
    float LeftBottom = 1;
    float RightBottom = 0;
    float LeftTop = 1;
    float RightTop = 0;
    Debug.Log(
quot;Left: {LeftBottom} \n Right: {RightBottom} \n Top: {LeftTop} \n Bottom: {RightTop}");
    //Brought the player transform from World units to screen unit. Where x is x, z from the 3d object acts as y, and y is z.
    transformPos = Camera.main.WorldToViewportPoint(transform.position);
    //This debug was to check if z is y in the ViewportPoint and it was
    Debug.Log(transformPos);

    float x = transformPos.x;
    //Calling it z because I dont wanna confuse myself when I convert it back
    float z = transformPos.y;

    //This is where I start the clamping using if statements
    if (transformPos.x <= LeftBottom)
    {
        x = Mathf.Clamp(transformPos.x, 0.1f, 0.9f);
        Debug.Log(x);
    }
    else if (transformPos.x >= RightBottom)
    {
        x = Mathf.Clamp(transformPos.x, 0.1f, 0.9f);
    }

    if (transformPos.y <= LeftTop)
    {
        z = Mathf.Clamp(transformPos.y, 0.1f, 0.9f);
    }
    else if (transformPos.y >= RightTop)
    {
        z = Mathf.Clamp(transformPos.y, 0.1f, 0.9f);
    }

    //And then finally I convert it back to world unit where the values is just placed in. x is x, y of the 3d object remains the same, and z 
    transform.position = Camera.main.ViewportToWorldPoint(new Vector3(x, z, 1));

}
洒一地阳光 2025-01-20 07:46:13

上面的代码有效。谢谢@Ubaldo Vitiello。我在这里添加我自己的答案的原因也是为了解释为什么玩家会移动一点然后完全停止然后结巴。我花了一段时间,但我终于明白了原因。
这是因为“WorldToViewportPoint”与“rigidbody.MovePosition”不兼容。现在这只是我的理解,所以我可能是错的,但 MovePosition 是玩家的刚体移动到您指定的位置的位置。该位置仅出现在世界空间中。 “WorldToViewportPoint”将世界空间转换为视口空间。这就是为什么我的播放器在完全停止之前移动了一点,因为我附加到播放器的第二个脚本正在将其转换为视口空间。现在我的播放器会出现卡顿的原因是因为我当时正在将视口空间转换回世界空间。这两个代码只是彼此不兼容,仅此而已。
我如何解决它是使用rigidbody.velocity

The above code works. Thank you @Ubaldo Vitiello. The reason Im adding my own answer here as well is to explain why the player will move for a bit before coming to a complete stop and then stutter. Took me a while but I finally understood the reason.
This is because "WorldToViewportPoint" is incompatible with "rigidbody.MovePosition". Now this is just from my understanding so I could be wrong, but MovePosition is where the player's rigidbody is moved to the position that you specify. The position only occurs in World space. "WorldToViewportPoint" transforms world space into viewport space.This is why my player moved for a bit before completing to a dead stop because my second script attached to the player is converting it to viewport space. Now the reason why my player will then stutter is because I was then transforming the viewport space back to world space. These two codes are simply incompatible with each other, that is all.
How I resolved it was using rigidbody.velocity

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文