相机移动时使用Camera.main.ScreenToWorldPoint

时间:2018-12-11 15:16:38

标签: c# unity3d

想制作一个有2D球移动到光标位置的游戏。为了获得光标的位置,我使用以下代码:

Vector2 PixelPos = Input.mousePosition;

然后将屏幕位置转换为世界位置,我使用以下代码:

Vector2 Pos = Camera.main.ScreenToWorldPoint(PixelPos);

问题在于主摄像机向上移动,因此如果强制播放器移动。但是当它移动时,我的球会有一些奇怪的运动。(因为相机在向上移动,所以它总是在移动球)

还有其他方法可以使这项工作吗?

或更简单地说,我可以替换这段代码:

Vector2 Pos = Camera.main.ScreenToWorldPoint(PixelPos);

还有其他一些不需要相机将屏幕位置转换为世界位置的东西吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

由于您希望光标仅由播放器移动并且相对于世界空间而不是屏幕空间进行更新,因此您需要实现一个存在于世界空间中的虚拟光标。

首先,将虚拟光标创建为GameObject。在Update上,您可以使用

更新其位置
float sensitivity = 1f;
transform.position += sensitivity * new Vector2( 
        Input.GetAxis("Mouse X"), 
        Input.GetAxis("Mouse Y")
);

Then, instead of using the camera to find the cursor position, you just check the `transform.position` of that virtual cursor `GameObject`.

第二,您需要锁定内置光标。您可以使用

Cursor.lockState = CursorLockMode.Locked;

如果您需要撤消该操作(例如,如果您调出菜单,并且需要使用常规光标而不移动虚拟光标),则可以使用:

Cursor.lockState = CursorLockMode.None; 

或者,如果您需要将光标留在窗口中:

Cursor.lockState = CursorLockMode.Confined;

如果您只想将球移动到单击/触摸的最后一个位置,那么这是一个更简单的解决方案。

跟踪球的目标位置,以及是否设置了目标:

private Vector2 moveGoalPos;
private bool moveGoalSet= false;

仅在单击鼠标/触摸屏幕的帧上更改moveGoalPos

bool isTouched;
if (isMouseEnable) {
    isTouched = Input.GetMouseButtonDown(0);
    PixelPos = Input.mousePosition;
} else {
    isTouched = Input.touchCount > 0;
    Touch touch = Input.GetTouch(0);
    PixelPos = touch.position;
}

if (isTouched) {
    moveGoalPos= Camera.main.ScreenToWorldPoint(PixelPos);
    moveGoalSet= true;
}

但是,在每一帧上,您都希望将球移到世界moveGoalPos(仅在已设定目标的情况下):

if (moveGoalSet) {
    Vector2 OffsetPos = moveGoalPos + CursorOffSet; 

    GCursor.transform.position = OffsetPos; 
    print(OffsetPos);   
    Vector2 LerpPos = Vector2.Lerp(rb.transform.position, OffsetPos, 0.05f);

    rb.MovePosition(LerpPos);
}

当您需要使球停止移动到最后一次触摸/单击的位置时(例如,如果您更改或重置级别),则需要重置moveGoalSet

moveGoalSet = false;