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: WPF相机控制器是一种用于在WPF应用程序中控制摄像头的技术。通过使用WPF相机控制器,我们可以在应用程序中访问和控制计算机上连接的摄像头。 WPF相机控制器提供了许多功能,使我们能够灵活地操作摄像头。首先,它提供了获取和显示摄像头的实时图像的功能。我们可以通过调用相应的API来捕捉来自摄像头的实时图像,并将其显示在WPF应用程序的界面中。 除了实时图像,WPF相机控制器还可以通过访问摄像头的属性和方法来控制摄像头的各种设置。例如,我们可以调整摄像头的亮度、对比度、饱和度等参数,以获取所需的图像效果。此外,我们还可以使用WPF相机控制器来控制摄像头的焦距、白平衡、曝光等设置,以满足不同拍摄条件下的需求。 另一个重要的功能是WPF相机控制器提供了摄像头的录制和回放功能。我们可以使用相应的API来开始录制摄像头的实时图像,并将其保存为视频文件。然后,我们可以使用WPF相机控制器来回放这些视频文件,以便在应用程序中进行视频播放和编辑。 总而言之,WPF相机控制器是一种非常有用的技术,它提供了在WPF应用程序中访问和控制摄像头的功能。通过使用WPF相机控制器,我们可以灵活地操作摄像头,捕捉实时图像,调整摄像头的各种设置,以及录制和回放摄像头的视频。这对于那些需要在WPF应用程序中使用摄像头的开发人员来说是非常有价值的。 ### 回答2: WPF(Windows Presentation Foundation)是微软开发的一种用户界面创建框架,用于构建Windows应用程序的图形用户界面。在WPF中,CameraController是用于控制3D场景中相机Camera)的类。 CameraController类提供了一系列方法和属性,可以用于控制相机在3D场景中的位置、方向、缩放等参数。通过CameraController,开发人员可以实现相机的移动、旋转、缩放等操作,以便更好地展示和操控3D场景。 在使用CameraController之前,需要先创建一个Camera对象,并将其设置为场景的主相机。然后,通过CameraController可以实现对主相机控制。例如,可以使用CameraController的Move方法来实现相机在场景中的移动,使用Rotate方法来实现相机的旋转,使用Zoom方法来实现相机的缩放。 CameraController还提供了一些额外的功能,例如设置相机的最小/最大缩放值、设置相机的灵敏度等。这些功能可以通过CameraController的属性进行设置。 总之,WPF的CameraController是用于控制3D场景中相机的类,它提供了一系列方法和属性,可以实现相机在场景中的移动、旋转、缩放等操作,以便更好地展示和操控3D场景。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值