简体   繁体   English

相机旋转后滚动

[英]scrolling after camera rotation

I am writing a kind of RTS CameraController in Unity using C#. 我正在使用C#在Unity中编写一种RTS CameraController。 I already managed to implement the basic functions, but now I am facing a tricky problem. 我已经设法实现了基本功能,但是现在我面临着一个棘手的问题。 I managed to rotate my camera and afterwards move into the right direction, BUT my scrolling boundaries are not working anymore after rotating (of course because I am just checking for x on the horizontal scrolling, but after rotation I would need to check for y instead). 我设法旋转了相机,然后向正确的方向移动,但是旋转后,我的滚动边界不再起作用(当然,因为我只是在水平滚动中检查x,但是旋转后,我需要检查y) )。 With boundaries I mean the restriction to only scroll until a certain position is reached (x < 0). 对于边界,我的意思是只能滚动直到到达某个位置(x <0)的限制。

I am a bit stuck on how to solve my problem easily. 我对如何轻松解决问题有些困惑。 One way would seems to be using conditions and check the rotation before checking for the boundaries, but this doesn't seem like a good aproach for me, just fixing the problem, but not really taking care of the cause. 一种方法似乎是在检查边界之前使用条件并检查旋转,但这对我来说似乎不是一个好方法,只是解决了问题,但并未真正解决问题。 Now my question: Is there an easier or better way to achieve what I am doing? 现在,我的问题是:有没有更简便或更好的方法来实现自己的目标? Did I miss something completely? 我完全错过了什么吗?

This is how I want the camera to move in all 4 rotations. 这就是我希望相机在所有4个旋转中移动的方式。 The rectangles are my the world, the arrows define my bounds. 矩形是我的世界,箭头定义了我的界限。 The camera should always overshoot in backwards direction and stop before the bounds in forward direction.: 摄像机应始终向后超调,并在向前限制前停止。

预期的相机行为

Here is my update method (vertDist and horDist are just defining from when on the mousescroll should start): 这是我的更新方法(vertDist和horDist只是从鼠标滚动何时开始定义):

    void LateUpdate() {
    //LEFT
    if((Input.mousePosition.x < horDist || Input.GetAxis("Horizontal") < 0)
       && transform.position.x > 0)
        transform.Translate(-speed, 0, 0);
    //RIGHT
    if((Input.mousePosition.x > Screen.width - horDist || Input.GetAxis("Horizontal") > 0)
       && transform.position.x < world.worldX)
        transform.Translate(speed, 0, 0);
    //UP
    if((Input.mousePosition.y > Screen.height - vertDist || Input.GetAxis("Vertical") > 0)
       && transform.position.z < world.worldZ - 30) {
        Vector3 temp = transform.eulerAngles;
        transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
        transform.Translate(0, 0, speed);
        transform.eulerAngles = temp;
    }
    //DOWN
    if((Input.mousePosition.y < vertDist || Input.GetAxis("Vertical") < 0)
       && transform.position.z > -10) {
        Vector3 temp = transform.eulerAngles;
        transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
        transform.Translate(0, 0, -speed);
        transform.eulerAngles = temp;
    }

    //ZOOM
    //camera.fieldOfView -= Input.GetAxis("Mouse ScrollWheel");

    //ROTATE
    if(Input.GetButtonDown("Rotate")){
        Vector3 targetPosition = transform.position;
        targetPosition += transform.forward * 27;
        //transform.Rotate(new Vector3(0, Mathf.Sign(Input.GetAxis("Rotate")) * 90, 0), Space.World);
        transform.RotateAround(targetPosition, Vector3.up, Mathf.Sign(Input.GetAxis("Rotate")) * 90);
    }
}

Use 采用

transform.Translate(0, 0, -speed, Space.Self); // For all the Translate, use Space.Self

It will only move based on it's local position instead of world position. 它只会根据其本地位置而不是世界位置移动。 But you will get what you wanted. 但是您会得到想要的。 Hope it helps. 希望能帮助到你。

Finally I got a solution! 终于我找到了解决方案! I decided to define a Rect, depending on the current rotation and afterwards check if the camera-position is inside the Rect. 我决定根据当前旋转定义一个Rect,然后检查相机位置是否在Rect内部。 Thus I had to mess a bit around with the positions, because I don't know why Rect.Contains() only takes the x- and y- coordinate of a position. 因此,我不得不对位置进行一些修改,因为我不知道为什么Rect.Contains()仅采用位置的x和y坐标。 My camera just moves along the x- and z-axis, so I did this weird coordinate swapping there: 我的相机只是沿x轴和z轴移动,所以我在这里做了这个奇怪的坐标交换:

    void LateUpdate() {
    Rect bounds = DefineBounds();
    Vector3 pos = transform.position;

    //LEFT
    if((/*Input.mousePosition.x < horDist ||*/ Input.GetAxis("Horizontal") < 0)) {
        pos += transform.TransformDirection(-speed * Time.deltaTime, 0, 0);
        //reset pos if out of bounds
        if(!bounds.Contains(new Vector2(pos.x, pos.z)))
            pos -= transform.TransformDirection(-speed * Time.deltaTime, 0, 0);
    }
    //RIGHT
    if((/*Input.mousePosition.x > Screen.width - horDist ||*/ Input.GetAxis("Horizontal") > 0)) {
        pos += transform.TransformDirection(speed * Time.deltaTime, 0, 0);
        //reset pos if out of bounds
        if(!bounds.Contains(new Vector2(pos.x, pos.z)))
            pos -= transform.TransformDirection(speed * Time.deltaTime, 0, 0);
    }
    //UP
    if((/*Input.mousePosition.y > Screen.height - vertDist ||*/ Input.GetAxis("Vertical") > 0)) {
        //Set camera x-angle to 0
        Vector3 temp = transform.eulerAngles;
        transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);

        pos += transform.TransformDirection(0, 0, speed * Time.deltaTime);
        //reset pos if out of bounds
        if(!bounds.Contains(new Vector2(pos.x, pos.z)))
            pos -= transform.TransformDirection(0, 0, speed * Time.deltaTime);

        //Reset camera x-angle
        transform.eulerAngles = temp;
    }
    //DOWN
    if((/*Input.mousePosition.y < vertDist ||*/ Input.GetAxis("Vertical") < 0)) {
        //Set camera x-angle to 0
        Vector3 temp = transform.eulerAngles;
        transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);

        pos += transform.TransformDirection(0, 0, -speed * Time.deltaTime);
        //reset pos if out of bounds
        if(!bounds.Contains(new Vector2(pos.x, pos.z)))
            pos -= transform.TransformDirection(0, 0, -speed * Time.deltaTime);

        //Reset camera x-angle
        transform.eulerAngles = temp;
    }

    transform.position = pos;

    //ZOOM
    //camera.fieldOfView -= Input.GetAxis("Mouse ScrollWheel");
    transform.position = new Vector3(pos.x, pos.y - Input.GetAxis("Mouse ScrollWheel"), pos.z);

    //ROTATE
    if(Input.GetButtonDown("Rotate")){
        Vector3 targetPosition = transform.position;
        Vector2 posXZ;

        targetPosition += transform.forward * 27;
        transform.RotateAround(targetPosition, Vector3.up, Mathf.Sign(Input.GetAxis("Rotate")) * 90);
        bounds = DefineBounds();

        pos = transform.position;
        posXZ = new Vector2(pos.x, pos.z);

        while(!bounds.Contains(posXZ)) {
            posXZ = Vector2.MoveTowards(posXZ, bounds.center, 1);

            pos.x = posXZ.x;
            pos.z = posXZ.y;
        }
        transform.position = pos;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM