CameraController 相机控制

本篇文章主要是创建一个相机控制器

功能介绍:
  1. 为策略游戏构建一个摄像机系统
  2. 保持相机集中在一点
  3. 增加平滑的移动、旋转、缩放
场景搭建:
  1. 便于观察,场景的元素很简单,一个平面,一个Cube即可
    在这里插入图片描述
  2. 新建一个空对象作为相机的父物体CrameraRig,设置一个初始位置,将相机拖入这个空物体中,设置相机的Transform
    在这里插入图片描述
    3.整个场景的Hierachy的结构如下
    在这里插入图片描述
    下面开始代码部分了
代码部分(这里做了两种控制方式 ):
一、 键盘控制
  1. 变量声明
	// 单例
	public static CameraController instance;
	// 当前相机
    public Transform cameraTransfrom;
    // 移动速度
    public float movementSpeed = 2.0f;
    // 移动时间
    public float movementTime = 5.0f;
    // 旋转速率
    public float rotationAmount = 2.0f;
    // 缩放速率
    public Vector3 zoomAmount = Vector2.one * 2;
    // 移动后的位置、旋转、缩放值
    private Vector3 newPosition;
    private Quaternion newRotation;
    private Vector3 newZoom;
  1. 初始化
    void Start()
    {
        instance = this;
        newPosition = transform.position;
        newRotation = transform.rotation;
        newZoom = cameraTransfrom.localPosition;
    }
  1. 键盘控制
   void HanldeMovementInput()
    {
        //上
        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
        {
            newPosition += (transform.forward * movementSpeed);
        }
        //下
        if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
        {
            newPosition += (transform.forward * -movementSpeed);
        }
        //左
        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
        {
            newPosition += (transform.right * -movementSpeed);
        }
        //右
        if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
        {
            newPosition += (transform.right * movementSpeed);
        }

        //左旋转
        if (Input.GetKey(KeyCode.Q))
        {
            newRotation *= Quaternion.Euler(Vector3.up * rotationAmount);
        }

        //右旋转
        if (Input.GetKey(KeyCode.E))
        {
            newRotation *= Quaternion.Euler(Vector3.up * -rotationAmount);
        }

        if (Input.GetKey(KeyCode.R))
        {
            newZoom += zoomAmount;
        }
        if (Input.GetKey(KeyCode.F))
        {
            newZoom -= zoomAmount;
        }
        transform.rotation = Quaternion.Lerp(transform.rotation, newRotation, Time.deltaTime * movementTime);
        transform.position = Vector3.Lerp(transform.position, newPosition, Time.deltaTime * movementTime);
        cameraTransfrom.localPosition = Vector3.Lerp(cameraTransfrom.localPosition, newZoom, Time.deltaTime * movementSpeed);
    }
  1. Update函数监听键盘输入事件
   void Update()
    {
        HanldeMovementInput();
    }

演示效果

键盘控制演示效果


二、 鼠标控制

在鼠标控制部分增加了一些可控制的功能,如

  • 移动范围的限制(防止跑出地图边界)
  • 旋转角度限制(防止相机翻转)
  • 相机远近距离的限制
  • 控制相机XZ平面的角度
  1. 变量声明
  // 单例
    public static CameraController instance;
    // 相机
    public Transform cameraTransfrom;
    // 欧拉角的值
    private float x;
    private float y;
    // 移动速度
    public float movementSpeed = 2.0f;
    // 时间
    public float movementTime = 5.0f;

    //缩放速率
    public Vector3 zoomAmount = Vector3.one * 2;

    private Vector3 newPosition;
    private Quaternion newRotation;
    private Vector3 newZoom;
    private Vector3 dragStartPosition;
    private Vector3 dragCurrentPosition;

    // 缩放距离
    public float minDistance;
    public float maxDistance;
    // 旋转角度
    public float xMinLimit;
    public float xMaxLimit;
    public float yMinLimit;
    public float yMaxLimit;

    // 移动距离
    public float posXminLimit;
    public float posXmaxLimit;
    public float posZminLimit;
    public float posZmaxLimit;
  1. Start初始化变量值
  		instance = this;
        newPosition = transform.position;
        newRotation = transform.rotation;
        newZoom = cameraTransfrom.localPosition;
        x = transform.eulerAngles.y;
        y = transform.eulerAngles.x;
  1. 鼠标控制
      void HandleMouseInput()
    {
        // 缩放
        if (Input.mouseScrollDelta.y != 0)
        {
            newZoom -= Input.mouseScrollDelta.y * zoomAmount;
        }
        // 移动
        if (Input.GetMouseButtonDown(0))
        {
            Plane plane = new Plane(Vector3.up, Vector3.zero);
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float entry;
            if (plane.Raycast(ray, out entry))
            {
                dragStartPosition = ray.GetPoint(entry);
            }
        }
        if (Input.GetMouseButton(0))
        {
            Plane plane = new Plane(Vector3.up, Vector3.zero);
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float entry;
            if (plane.Raycast(ray, out entry))
            {
                dragCurrentPosition = ray.GetPoint(entry);
                Vector3 tmp = transform.position + dragStartPosition - dragCurrentPosition;
                //newPosition = transform.position + dragStartPosition - dragCurrentPosition; 
                newPosition = new Vector3(Mathf.Clamp(tmp.x, posXminLimit, posXmaxLimit), tmp.y, Mathf.Clamp(tmp.z, posZminLimit, posZmaxLimit));
            }
        }
  
        if (Input.GetMouseButton(1))
        {
            x += Input.GetAxis("Mouse X") * movementSpeed;
            y -= Input.GetAxis("Mouse Y") * movementSpeed;
            x = ClampX(x, xMinLimit, xMaxLimit);
            y = ClampAngle(y, yMinLimit, yMaxLimit);
        

    }
  1. 移动范围、旋转角度、缩放的限制
  static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -90)
            angle += 90;
        if (angle > 45)
            angle -= 45;
        return Mathf.Clamp(angle, min, max);
    }
    static float ClampX(float x, float min, float max)
    {
        if (x < 0)
            x = 360;
        if (x > 360)
            x = 0;
        return Mathf.Clamp(x, min, max);
    }
	///缩放距离的限制
    static Vector3 ClampDistance(float distance,float minDistance,float maxDistance)
    {
        distance = Mathf.Clamp(distance, minDistance, maxDistance);
        return new Vector3(0, distance, -distance);
    }
     
  1. Update 监听鼠标控制以及更新变量值
    void Update()
    {
    	//有UI系统时可以利用这个方法避免在UI上也控制场景的旋转
        //if (!EventSystem.current.IsPointerOverGameObject())
        //{
        //    HandleMouseInput();
        //}
        HandleMouseInput();

        newRotation = Quaternion.Euler(y, x, 0.0f);
        newZoom = ClampDistance(newZoom.y, minDistance, maxDistance);
        transform.rotation = Quaternion.Lerp(transform.rotation, newRotation, Time.deltaTime * movementTime);
        transform.position = Vector3.Lerp(transform.position, newPosition, Time.deltaTime * movementTime);
        cameraTransfrom.localPosition = Vector3.Lerp(cameraTransfrom.localPosition, newZoom, Time.deltaTime * movementSpeed);
    }

演示效果

鼠标控制演示效果


相机移动的控制代码基本完成,比较简单就没过多的去写注释了,这篇文章也是自己记录工具库的一个内容,方便以后使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值