Unity3D摄像机,键盘控制前后左右上下移动,鼠标控制旋转、放缩

Unity3D中运行场景时,实现摄像机的前、后、左、右、上、下,以及鼠标滚轮的放缩,鼠标右键的旋转操作。亲测有效,可供参考。
按键功能介绍:W——前;S——后;A——左;D——右;Q——下降;E——上升;鼠标右键——旋转;鼠标滚轮——放缩。
Tourcamera脚本需要挂在摄像机组件上。
在摄像机组件中还需要添加“Physics Raycaster”组件。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Tourcamera : MonoBehaviour
{
    public Transform tourCamera;
    #region 相机移动参数
    public float moveSpeed = 1.0f;
    public float rotateSpeed = 90.0f;
    public float shiftRate = 2.0f;// 按住Shift加速
    public float minDistance = 0.5f;// 相机离不可穿过的表面的最小距离(小于等于0时可穿透任何表面)
    #endregion

    #region 运动速度和其每个方向的速度分量
    private Vector3 direction = Vector3.zero;
    private Vector3 speedForward;
    private Vector3 speedBack;
    private Vector3 speedLeft;
    private Vector3 speedRight;
    private Vector3 speedUp;
    private Vector3 speedDown;
    #endregion
    void Start()
    {
        if (tourCamera == null) tourCamera = gameObject.transform;
        // 防止相机边缘穿透
        //if (tourCamera.GetComponent<Camera>().nearClipPlane > minDistance / 3)
        //{
        //    tourCamera.GetComponent<Camera>().nearClipPlane /= 3;
        //}
    }
    void Update()
    {
        GetDirection();
        // 检测是否离不可穿透表面过近
        RaycastHit hit;
        while (Physics.Raycast(tourCamera.position, direction, out hit, minDistance))
        {
            // 消去垂直于不可穿透表面的运动速度分量
            float angel = Vector3.Angle(direction, hit.normal);
            float magnitude = Vector3.Magnitude(direction) * Mathf.Cos(Mathf.Deg2Rad * (180 - angel));
            direction += hit.normal * magnitude;
        }
        tourCamera.Translate(direction * moveSpeed * Time.deltaTime, Space.World);
    }
    private void GetDirection()
    {
        #region 加速移动
        if (Input.GetKeyDown(KeyCode.LeftShift)) moveSpeed *= shiftRate;
        if (Input.GetKeyUp(KeyCode.LeftShift)) moveSpeed /= shiftRate;
        #endregion

        #region 键盘移动
        // 复位
        speedForward = Vector3.zero;
        speedBack = Vector3.zero;
        speedLeft = Vector3.zero;
        speedRight = Vector3.zero;
        speedUp = Vector3.zero;
        speedDown = Vector3.zero;
        // 获取按键输入
        if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W)) speedForward = tourCamera.forward;
        if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S)) speedBack = -tourCamera.forward;
        if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A)) speedLeft = -tourCamera.right;
        if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D)) speedRight = tourCamera.right;
        if (Input.GetKey(KeyCode.E)) speedUp = Vector3.up;
        if (Input.GetKey(KeyCode.Q)) speedDown = Vector3.down;
        direction = speedForward + speedBack + speedLeft + speedRight + speedUp + speedDown;
        #endregion

        #region 鼠标旋转
        if (Input.GetMouseButton(1))
        {
            // 转相机朝向
            tourCamera.RotateAround(tourCamera.position, Vector3.up, Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime);
            tourCamera.RotateAround(tourCamera.position, tourCamera.right, -Input.GetAxis("Mouse Y") * rotateSpeed * Time.deltaTime);
            // 转运动速度方向
            direction = V3RotateAround(direction, Vector3.up, Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime);
            direction = V3RotateAround(direction, tourCamera.right, -Input.GetAxis("Mouse Y") * rotateSpeed * Time.deltaTime);
        }
        #endregion

        #region 鼠标滚轮效果
        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        {
            if (Camera.main.fieldOfView <= 100)
                Camera.main.fieldOfView += 2;
            if (Camera.main.orthographicSize <= 20)
                Camera.main.orthographicSize += 0.5F;
        }
        //Zoom in
        if (Input.GetAxis("Mouse ScrollWheel") > 0)
        {
            if (Camera.main.fieldOfView > 2)
                Camera.main.fieldOfView -= 2;
            if (Camera.main.orthographicSize >= 1)
                Camera.main.orthographicSize -= 0.5F;
        }
        #endregion
    }

    public Vector3 V3RotateAround(Vector3 source, Vector3 axis, float angle)
    {
        Quaternion q = Quaternion.AngleAxis(angle, axis);// 旋转系数
        return q * source;// 返回目标点
    }
}


  • 29
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
实现导入图片鼠标滑轮放缩和左键按住移动,可以使用QGraphicsView和QGraphicsScene来实现,具体步骤如下: 1. 创建一个QGraphicsView对象和QGraphicsScene对象,并将QGraphicsScene设置为QGraphicsView的场景。 2. 使用QGraphicsPixmapItem将图片添加到QGraphicsScene。 3. 重写QGraphicsView的wheelEvent()方法,实现鼠标滑轮放缩图片的功能。 4. 重写QGraphicsView的mousePressEvent()、mouseMoveEvent()和mouseReleaseEvent()方法,实现鼠标左键按住移动图片的功能。 下面是一个简单的代码示例: ```python from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsPixmapItem from PyQt5.QtGui import QPixmap from PyQt5.QtCore import Qt class ImageViewer(QGraphicsView): def __init__(self, parent=None): super().__init__(parent) # 创建QGraphicsScene对象 self.scene = QGraphicsScene(self) self.setScene(self.scene) # 添加图片 self.image = QGraphicsPixmapItem() self.scene.addItem(self.image) # 设置滚动条策略 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setRenderHint(QPainter.Antialiasing, True) # 设置鼠标追踪 self.setMouseTracking(True) # 设置缩放比例 self.scaleFactor = 1.0 def loadImage(self, filename): # 加载图片 pixmap = QPixmap(filename) self.image.setPixmap(pixmap) self.setSceneRect(pixmap.rect()) def wheelEvent(self, event): # 放缩图片 if event.angleDelta().y() > 0: self.scaleFactor *= 1.1 else: self.scaleFactor /= 1.1 self.scale(self.scaleFactor, self.scaleFactor) def mousePressEvent(self, event): # 记录鼠标按下的位置 if event.button() == Qt.LeftButton: self.lastPos = event.pos() def mouseMoveEvent(self, event): # 移动图片 if event.buttons() & Qt.LeftButton: delta = event.pos() - self.lastPos self.lastPos = event.pos() self.translate(delta.x(), delta.y()) def mouseReleaseEvent(self, event): pass ``` 在上面的代码,loadImage()方法用于加载图片,wheelEvent()方法用于放缩图片,mousePressEvent()、mouseMoveEvent()和mouseReleaseEvent()方法用于移动图片。注意,在mousePressEvent()方法要记录鼠标按下的位置,在mouseMoveEvent()方法要计算鼠标移动的距离,并将场景平移相应的距离。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值