繁体   English   中英

Unity 3D运动和相机控制器

[英]Unity 3D movement and camera controller

现在,我有一个附有动作脚本的第一人称角色。 我使用刚体和角色控制器。 摄像机控制播放器对象(在这种情况下为胶囊)与父对象的转换。

播放器对象上具有移动脚本,而相机具有相机控制器,仅允许鼠标控制播放器对象的变换。

当我跳跃时,我的脚本会这样做,从而使播放器保持动量,并且不能停止空中,但是如果我转动相机,则播放器对象也会根据变换更改轨迹。 如果我看起来正确,则在空中时,我的跳跃也会跟随摄像机向右移动。 我希望空中跳动,以保持原始轨迹。 有人可以帮我添加该功能,但相机仍然可以环顾四周吗?

我的动作脚本:

void movement () {
        moveVector = Vector3.zero;
        moveVector.x = Input.GetAxisRaw("Horizontal");
        moveVector.z = Input.GetAxisRaw("Vertical");

        if (controller.isGrounded) {
            verticalVelocity = -1;

            if (Input.GetButtonDown("Jump")) {
                verticalVelocity = jumpforce;
            }

        } else {
            verticalVelocity -= gravity * Time.deltaTime;
            moveVector = lastMove;
        }

        moveVector.y = 0;
        moveVector.Normalize ();
        moveVector *= playerspeed;
        moveVector.y = verticalVelocity;

        worldMove = transform.TransformDirection (moveVector);
        controller.Move (worldMove * Time.deltaTime);

        //controller.Move (moveVector.z * transform.forward * Time.deltaTime);
        //controller.Move (moveVector.x * transform.right * Time.deltaTime);
        //controller.Move (moveVector.y * transform.up * Time.deltaTime);

        //controller.Move (moveVector * Time.deltaTime);
        lastMove = moveVector;
    }

其:

moveVector = lastMove;

这样我的播放器就不会停在半空中。

如果能够做到这一点,那也将是令人惊讶的,您不能在空中改变方向,但是可以稍微平滑地拖动轨迹,例如在《反恐精英:全球攻势》中。

更新:这是我的相机代码:

public class CameraController : MonoBehaviour {

    Vector2 mouseLook;
    Vector2 smoothV;
    public float sensitivity = 5.0f;
    public float smoothing = 2.0f;

    GameObject character;

    // Use this for initialization
    void Start () {
        character = this.transform.parent.gameObject;
    }

    // Update is called once per frame
    void Update () {
        var md = new Vector2 (Input.GetAxisRaw ("Mouse X"), Input.GetAxisRaw ("Mouse Y"));

        md = Vector2.Scale (md, new Vector2 (sensitivity * smoothing, sensitivity * smoothing));
        smoothV.x = Mathf.Lerp (smoothV.x, md.x, 1f / smoothing);
        smoothV.y = Mathf.Lerp (smoothV.y, md.y, 1f / smoothing);
        mouseLook += smoothV;

        //Låser kameraret så man ikke kan kigge længere ned eller op end 90 grader
        mouseLook.y = Mathf.Clamp (mouseLook.y, -90f, 90f);

        transform.localRotation = Quaternion.AngleAxis (-mouseLook.y, Vector3.right);
        character.transform.localRotation = Quaternion.AngleAxis (mouseLook.x, character.transform.up);
    }
}

您似乎将运动与摄像机的方向混淆了。 在《第一人称视角》中,“玩家”在与摄像机相同的方向上移动位置是很常见的,但是不必那样做。 鼠标控制了摄像机的方向,但是您正在使用摄像机的方向来设置行进方向。

您需要单独存储当前的方向向量,并根据某种算法(例如,双曲线)更改方向向量,并在玩家跳跃时忽略相机方向。 您可以使用“相机方向”来更改“视图矩阵”,但是在飞行中不要使用相机方向来更改相机位置。

这是我用于矿山项目的摄像机控制器代码的一部分,希望对您有所帮助。

void Update()
{
    CameraMovementValidation();
    CameraRotationValidation();
    Camerazoom();

    if (Input.GetKey(KeyCode.LeftShift))
    {
        doSlowMotion = true;
    }
    else if (Input.GetKeyUp(KeyCode.LeftShift))
    {
        doSlowMotion = false;
    }
}

public void FixedUpdate()
{
    CameraMovement();
    CameraRotation();
}

public void LateUpdate()
{
    Controller();
}

private void CameraMovementValidation()
{
    if (Input.GetKey(KeyCode.W))
    {
        doCameraUpDownMove = true;
        cameraUpDownMoveDirection = 1;
    }
    else if (Input.GetKey(KeyCode.S))
    {
        doCameraUpDownMove = true;
        cameraUpDownMoveDirection = -1;
    }
    else
    {
        doCameraUpDownMove = false;
    }

    if (Input.GetKey(KeyCode.A))
    {
        doCameraLeftRightMove = true;
        cameraLeftRightDirection = -1;
    }
    else if (Input.GetKey(KeyCode.D))
    {
        doCameraLeftRightMove = true;
        cameraLeftRightDirection = 1;
    }
    else
    {
        doCameraLeftRightMove = false;
    }

    if (Input.GetKey(KeyCode.Q))
    {
        doCameraForwardBackMove = true;
        cameraForwardBackDirection = 1;
    }
    else if (Input.GetKey(KeyCode.E))
    {
        doCameraForwardBackMove = true;
        cameraForwardBackDirection = -1;
    }
    else
    {
        doCameraForwardBackMove = false;
    }
}

private void CameraMovement()
{
    if (doCameraUpDownMove)
    {
        cameraPosition += transform.rotation * Vector3.up * moveCoefficent * cameraUpDownMoveDirection * camereSlowMotionMoveCoefficient;
    }

    if (doCameraLeftRightMove)
    {
        cameraPosition += transform.rotation * Vector3.right * moveCoefficent * cameraLeftRightDirection * camereSlowMotionMoveCoefficient;
    }

    if (doCameraForwardBackMove)
    {
        cameraPosition += transform.rotation * Vector3.forward * moveCoefficent * cameraForwardBackDirection * camereSlowMotionMoveCoefficient;
    }
}

private void CameraRotationValidation()
{
    if (Input.GetMouseButtonDown(1))
    {
        mouseXUpdateForRotation = Input.mousePosition.x;
        mouseYUpdateForRotation = Input.mousePosition.y;
    }

    if (Input.GetMouseButton(1))
    {
        doCameraRotation = true;
    }
    else
    {
        doCameraRotation = false;
    }
}

private void CameraRotation()
{
    if (doCameraRotation)
    {
        if (Input.mousePosition.x != mouseXUpdateForRotation)
        {
            cameraRotationX += (Input.mousePosition.x - mouseXUpdateForRotation) * rotationFactor;
            mouseXUpdateForRotation = Input.mousePosition.x;
        }

        if (Input.mousePosition.y != mouseYUpdateForRotation)
        {
            cameraRotationY += (Input.mousePosition.y - mouseYUpdateForRotation) * rotationFactor;
            mouseYUpdateForRotation = Input.mousePosition.y;
        }
    }
}

private void Camerazoom()
{
    mouseScrollCoefficient = Input.GetAxis("Mouse ScrollWheel");
    if (mouseScrollCoefficient > 0)
    {
        zoom += mouseScrollCoefficient * -cameraZoomCoefficent;
    }
    else if (mouseScrollCoefficient < 0)
    {
        zoom += mouseScrollCoefficient * -cameraZoomCoefficent;
    }
}

private void Controller()
{
    transform.position = Vector3.Lerp(transform.position, cameraPosition, moveSmoothlyCoefficient);
    transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(-cameraRotationY, cameraRotationX, 0), rotationSmoothlyCoefficient);
    camera.fieldOfView = Mathf.Lerp(camera.fieldOfView, zoom, zoomSmoothlyCoefficient);

    if (doFolowToPlayer && transform.position.x <= cameraPosition.x + 0.5 && transform.position.x > cameraPosition.x - 0.5 &&
        transform.position.y <= cameraPosition.y + 0.5 && transform.position.y > cameraPosition.y - 0.5 &&
        transform.position.z <= cameraPosition.z + 0.5 && transform.position.z > cameraPosition.z - 0.5)
    {
        cameraRotationY = -mainCamera.transform.localEulerAngles.x;
        cameraRotationX = mainCamera.transform.localEulerAngles.y;
        doRotationFolowToPlayer = true;
        doFolowToPlayer = false;
    }

    if (doRotationFolowToPlayer && transform.localEulerAngles.x <= -cameraRotationY + 0.5 && transform.localEulerAngles.x > -cameraRotationY - 0.5 &&
        transform.localEulerAngles.y <= cameraRotationX + 0.5 && transform.localEulerAngles.y > cameraRotationX - 0.5)
    {
        doRotationFolowToPlayer = false;
    }
}   

暂无
暂无

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

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