相机旋转后滚动

时间:2015-02-01 20:35:13

标签: c# unity3d camera rotation

我正在使用C#在Unity中编写一种RTS CameraController。我已经设法实现了基本功能,但现在我遇到了一个棘手的问题。我设法旋转我的相机然后向右移动,但我的滚动边界在旋转后不再工作(当然因为我只是检查水平滚动的x,但是在旋转后我需要检查y而不是)。对于边界,我的意思是限制仅滚动直到达到某个位置(x <0)。

我对如何轻松解决问题感到困惑。一种方法似乎是在检查边界之前使用条件并检查旋转,但这对我来说似乎不是一个好的方法,只是解决问题,但没有真正照顾原因。现在我的问题是:有更简单或更好的方法来实现我的目标吗?我完全错过了什么吗?

这就是我希望相机在所有4个旋转中移动的方式。矩形是我的世界,箭头定义了我的界限。摄像机应始终向后方向过冲,并在向前方向前停止。:

intended camera behaviour

这是我的更新方法(vertDist和horDist只是从mousescroll开始时开始定义):

    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);
    }
}

2 个答案:

答案 0 :(得分:0)

使用

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

它只会根据它的本地位置而不是世界位置而移动。但是你会得到你想要的。 希望它有所帮助。

答案 1 :(得分:0)

最后我得到了解决方案!我决定定义一个Rect,取决于当前的旋转,然后检查相机位置是否在Rect内。因此,我不得不在位置上乱七八糟,因为我不知道为什么Rect.Contains()只取位置的x坐标和y坐标。我的相机只是沿着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;
    }
}