예제 #1
0
    /// <summary>
    /// 根据重力更新摄像机变换参考系
    /// </summary>
    void UpdateGravityAlignment()
    {
        // 1. 计算当前相机在当前重力下的旋转
        Vector3 fromUp = m_gravityAlignment * Vector3.up;              // 由当前重力纵轴确定
        Vector3 toUp   = CustomGravity.GetUpAxis(m_focusPoint);        // 由注视点的重力确定
        // 2. 得到旋转的角度值
        float dot   = Mathf.Clamp(Vector3.Dot(fromUp, toUp), -1f, 1f); // 精度问题可能会超出有效范围,造成非预期后果所以clamp之
        float angle = Mathf.Acos(dot) * Mathf.Rad2Deg;
        // 3. 计算当前帧最大旋转速度
        float maxAngle = m_upAlignmentSpeed * Time.deltaTime;

        // 4。由两个纵轴插值和起始旋转求得目标旋转
        Quaternion newAlignment = Quaternion.FromToRotation(fromUp, toUp) * m_gravityAlignment;

        // 5. 如果所需旋转角不大于旋转速度,则不进行旋转
        if (angle <= maxAngle)
        {
            m_gravityAlignment = newAlignment;
        }
        // 6. 如果所需旋转角大于旋转速度,则进行旋转
        else
        {
            m_gravityAlignment = Quaternion.SlerpUnclamped(m_gravityAlignment, newAlignment, maxAngle / angle); // 由于插值比例保证合理,所以“Unclamped”
        }
    }
예제 #2
0
    void UpdateGravityAlignment()
    {
        Vector3 fromUp   = gravityAlignment * Vector3.up;
        Vector3 toUp     = CustomGravity.GetUpAxis(focusPoint);
        float   dot      = Mathf.Clamp(Vector3.Dot(fromUp, toUp), -1f, 1f);
        float   angle    = Mathf.Acos(dot) * Mathf.Rad2Deg;
        float   maxAngle = upAlignmentSpeed * Time.deltaTime;

        Quaternion newAlignment = Quaternion.FromToRotation(fromUp, toUp) * gravityAlignment;

        if (angle <= maxAngle)
        {
            gravityAlignment = newAlignment;
        }
        else
        {
            gravityAlignment = Quaternion.SlerpUnclamped(gravityAlignment, newAlignment, maxAngle / angle);
        }
    }
예제 #3
0
    void LateUpdate()
    {
        gravityAlignment =
            Quaternion.FromToRotation(
                gravityAlignment * Vector3.up,
                CustomGravity.GetUpAxis(focusPoint)
                ) * gravityAlignment;

        UpdateFocusPoint();
        if (ManualRotation() || AutomaticRotation())
        {
            ConstrainAngles();
            orbitRotation = Quaternion.Euler(orbitAngles);
        }
        Quaternion lookRotation = gravityAlignment * orbitRotation;

        Vector3 lookDirection = lookRotation * Vector3.forward;
        Vector3 lookPosition  = focusPoint - lookDirection * distance;

        Vector3 rectOffset    = lookDirection * regularCamera.nearClipPlane;
        Vector3 rectPosition  = lookPosition + rectOffset;
        Vector3 castFrom      = focus.position;
        Vector3 castLine      = rectPosition - castFrom;
        float   castDistance  = castLine.magnitude;
        Vector3 castDirection = castLine / castDistance;

        if (Physics.BoxCast(
                castFrom, CameraHalfExtends, castDirection, out RaycastHit hit,
                lookRotation, castDistance, obstructionMask
                ))
        {
            rectPosition = castFrom + castDirection * hit.distance;
            lookPosition = rectPosition - rectOffset;
        }

        transform.SetPositionAndRotation(lookPosition, lookRotation);
    }
예제 #4
0
    private void LateUpdate()
    {
        ////5.1.4 自定义重力下对齐轨道摄像机
        //gravityAlignment = Quaternion.FromToRotation(gravityAlignment * Vector3.up, -Physics.gravity.normalized) * gravityAlignment;
        //5.2.2 应用自定义重力
        gravityAlignment = Quaternion.FromToRotation(gravityAlignment * Vector3.up, CustomGravity.GetUpAxis(focusPoint)) * gravityAlignment;

        ////2.2 控制轨道
        ////Vector3 focusPoint = focus.position;
        //UpdateFocusPoint();
        //ManualRotation();
        //Quaternion lookRotation = Quaternion.Euler(orbitAngles);
        ////Vector3 lookDirection = transform.forward;
        //Vector3 lookDirection = lookRotation * Vector3.forward;
        ////transform.localPosition = focusPoint - lookDirection * distance;
        //Vector3 lookPosition = focusPoint - lookDirection * distance;
        //transform.SetPositionAndRotation(lookPosition, lookRotation);

        //2.3 约束角度
        UpdateFocusPoint();
        //Quaternion lookRotation;
        if (ManualRotation() || AutomaticRotation())
        {
            ConstrainAngles();
            orbitRotation = Quaternion.Euler(orbitAngles);
        }
        //else
        //{
        //    lookRotation = transform.localRotation;
        //}

        Quaternion lookRotation  = gravityAlignment * orbitRotation;
        Vector3    lookDirection = lookRotation * Vector3.forward;
        Vector3    lookPosition  = focusPoint - lookDirection * distance;

        ////4.1减少外观距离
        //if (Physics.Raycast(focusPoint, -lookDirection, out RaycastHit hit, distance))
        //{
        //    lookPosition = focusPoint - lookDirection * hit.distance;
        //}

        ////4.2保持近平面清晰 采用盒子投射
        //if (Physics.BoxCast(focusPoint, CameraHalfExtends, -lookDirection, out RaycastHit hit, lookRotation, distance - regularCamera.nearClipPlane))
        //{
        //    lookPosition = focusPoint - lookDirection * (hit.distance + regularCamera.nearClipPlane);
        //}

        //4.3聚焦半径
        Vector3 rectOffset    = lookDirection * regularCamera.nearClipPlane;
        Vector3 rectPosition  = lookPosition + rectOffset;
        Vector3 castFrom      = focus.position;
        Vector3 castLine      = rectPosition - castFrom;
        float   castDistance  = castLine.magnitude;
        Vector3 castDirection = castLine / castDistance;

        if (Physics.BoxCast(castFrom, CameraHalfExtends, castDirection, out RaycastHit hit, lookRotation, castDistance, obstructionMask))
        {
            //lookPosition = focusPoint - lookDirection * (hit.distance + regularCamera.nearClipPlane);
            rectPosition = castFrom + castDirection * hit.distance;
            lookPosition = rectPosition - rectOffset;
        }


        transform.SetPositionAndRotation(lookPosition, lookRotation);
    }