Unity C# 一些关于Camera的心得!

2 篇文章 0 订阅
2 篇文章 0 订阅

本文原创,转载请注明出处:http://www.cnblogs.com/AdvancePikachu/p/6856374.html

首先,总结了下最近工作中关于摄像机漫游的功能,

脚本如下:

Transform _Camera;
    public LayerMask mask;
     
    public float checkHeight = 500f;
    public float minHeight = 20f;
    public float maxHeight = 8000f;
    public float minClamp = 50f;
    public float maxClamp = 950f;

    public float sensitivityX = 5f;
    public float sensitivityY = 5f;
    private float rotationY = 0f;

    //上下最大Y视角
    public float minimumY = -90f;
    public float maximumY = 30f;

    public Vector3 PreMouseMPos;

    public float scrollSpeed = 200f;

    void Start () 
    {
        mask.value = 1;
        _Camera = Camera.main.transform;
    }
    
    // Update is called once per frame
    void Update ()
    {
        if(Input.GetKey(KeyCode.LeftAlt))
        {
            MouseScrollWheel ();
            CameraMove ();
            MoveEulerAngles ();
        }
    }

    /// <summary>
    /// Checks the height of the low.
    /// </summary>
    void CheckLowHeight()
    {
        if (_Camera.position.x < minClamp)
            _Camera.position = new Vector3 (minClamp, _Camera.position.y, _Camera.position.z);
        if (_Camera.position.x > maxClamp)
            _Camera.position = new Vector3 (maxClamp, _Camera.position.y, _Camera.position.z);
        if (_Camera.position.z < minClamp)
            _Camera.position = new Vector3 (_Camera.position.x, _Camera.position.y, minClamp);
        if (_Camera.position.z > maxClamp)
            _Camera.position = new Vector3 (_Camera.position.x, _Camera.position.y, maxClamp);

        RaycastHit hit;
        if(Physics.Raycast(_Camera.position+Vector3.up*checkHeight,Vector3.down,out hit ,checkHeight+minHeight,mask))
        {
            if(_Camera.position.y-hit.point.y<minClamp)
            {
                Vector3 lowPoint = hit.point + new Vector3 (0, minHeight, 0);
                _Camera.position = lowPoint;
            }
        }
    }

    /// <summary>
    /// Mouses the scroll wheel.
    /// </summary>
    private void MouseScrollWheel()
    {
        if(Input.GetAxis("Mouse ScrollWheel")!=0)
        {
            _Camera.Translate (new Vector3 (0, 0, Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime * scrollSpeed));
        }

        CheckLowHeight ();

        if (_Camera.position.y >= maxHeight)
            _Camera.position = new Vector3 (_Camera.position.x, maxHeight, _Camera.position.z);
    }

    /// <summary>
    /// Cameras the move.
    /// </summary>
    private void CameraMove()
    {
        if(Input.GetMouseButton(0))
        {
            if(PreMouseMPos.x<=0)
            {
                PreMouseMPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 0);
            }
            else
            {
                Vector3 CurMouseMPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 0);
                Vector3 offset = CurMouseMPos - PreMouseMPos;
                offset = -offset * 0.5f * 2;
                if((_Camera.position+offset).y>=minHeight
                    &&(_Camera.position+offset).y<=maxHeight)
                {
                    _Camera.Translate(offset);

                    CheckLowHeight();

                    PreMouseMPos = CurMouseMPos;
                }
            }                
        }
        else
            PreMouseMPos = Vector3.zero;
    }

    /// <summary>
    /// Moves the euler angles.
    /// </summary>
    private void MoveEulerAngles()
    {
        if(Input.GetMouseButton(1))
        {
            float rotationX = _Camera.localEulerAngles.y + Input.GetAxis ("Mouse X") * sensitivityX;

            rotationY += Input.GetAxis ("Mouse Y") * sensitivityY;

            rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);

            _Camera.localEulerAngles = new Vector3 (-rotationY, rotationX, 0);
        }
    }

第二个是关于摄像机的限制范围和遇到障碍物自动变换与target的距离的功能

代码如下:

public Transform target;

    public LayerMask mask = new LayerMask();

    public Vector2 targetOffset = new Vector2();
    public Vector2 originRotation = new Vector2();

    public float distance = 5;
    public float minDistance = 0;
    public float maxDistance = 10;

    public Vector2 sensitivity = new Vector2(3, 3);

    public float zoomSpeed = 1;
    public float zoomSmoothing = 16;

    public float minAngle = -90;
    public float maxAngle = 90;

    private float _zoom_in_timer = 0;
    private float _zoom_out_timer = 0;

    private float _wanted_distance;
    private Quaternion _rotation;
    private Vector2 _input_rotation;

    private Transform _t;

    void Start()
    {
        mask.value = 1;
        _t = transform;
        _wanted_distance = distance;
        _input_rotation = originRotation; 41     }

    void Update()
    {
        if (target) {

            if (Input.GetMouseButton (0) || Input.GetMouseButton (1)) {
                if (Input.GetAxis ("Mouse X") != 0 || Input.GetAxis ("Mouse Y") != 0) {
                    if (!Cursor.visible) {
                        Cursor.visible = false;
                        Cursor.lockState = CursorLockMode.Locked;
                    }
                }

                return;
            }
        }


        if (!Cursor.visible) {
            Cursor.visible = true;
            Cursor.lockState = CursorLockMode.None;
        }

    }
    void FixedUpdate()
    {
        if(target)
        {

            // Zoom control
            if(Input.GetAxis("Mouse ScrollWheel") < 0 )
            {
                _wanted_distance += zoomSpeed;
            }
            else if(Input.GetAxis("Mouse ScrollWheel") > 0 )
            {
                _wanted_distance -= zoomSpeed;
            }


            _wanted_distance = Mathf.Clamp(_wanted_distance, minDistance, maxDistance);


            if (Input.GetMouseButton (0) || Input.GetMouseButton (1)) {

                _input_rotation.x += Input.GetAxis ("Mouse X") * sensitivity.x;


                ClampRotation ();


                _input_rotation.y -= Input.GetAxis ("Mouse Y") * sensitivity.y;


                _input_rotation.y = Mathf.Clamp (_input_rotation.y, minAngle, maxAngle);

                _rotation = Quaternion.Euler (_input_rotation.y, _input_rotation.x, 0);

            }

            // Lerp from current distance to wanted distance
            distance = Mathf.Clamp(Mathf.Lerp(distance, _wanted_distance, Time.deltaTime * zoomSmoothing), minDistance, maxDistance);

            // Set wanted position based off rotation and distance
            Vector3 wanted_position = _rotation * new Vector3(targetOffset.x, 0, -_wanted_distance - 0.2f) + target.position + new Vector3(0, targetOffset.y, 0);
            Vector3 current_position = _rotation * new Vector3(targetOffset.x, 0, 0) + target.position + new Vector3(0, targetOffset.y, 0);


            // Linecast to test if there are objects between the camera and the target using collision layers
            RaycastHit hit;

            if(Physics.Linecast(current_position, wanted_position, out hit, mask))
            {
                distance = Vector3.Distance(current_position, hit.point) - 0.2f;
            }


            // Set the position and rotation of the camera
            _t.position = _rotation * new Vector3(targetOffset.x, 0.0f, -distance) + target.position + new Vector3(0, targetOffset.y, 0);
            _t.rotation = _rotation;
        }
    }

    private void ClampRotation()
    {
        if(originRotation.x < -180)
        {
            originRotation.x += 360;
        }
        else if(originRotation.x > 180)
        {
            originRotation.x -= 360;
        }

        if(_input_rotation.x - originRotation.x < -180)
        {
            _input_rotation.x += 360;
        }
        else if(_input_rotation.x - originRotation.x > 180)
        {
            _input_rotation.x -= 360;
        }
    }

你有什么资格不努力!——进击的皮卡丘

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值