当前位置:网站首页>Unity3D摄像机,键盘控制前后左右上下移动,鼠标控制旋转、放缩
Unity3D摄像机,键盘控制前后左右上下移动,鼠标控制旋转、放缩
2022-07-06 09:18:00 【SQ刘】
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;// 返回目标点
}
}
边栏推荐
- [899]有序队列
- Basic operations of databases and tables ----- view data tables
- Flink late data processing (3)
- VSCode基础配置
- Fashion Gen: the general fashion dataset and challenge paper interpretation & dataset introduction
- (四)R语言的数据可视化——矩阵图、柱状图、饼图、散点图与线性回归、带状图
- [Nodejs] 20. Koa2 onion ring model ----- code demonstration
- Understanding of AMBA, AHB, APB and Axi
- Mp3mini playback module Arduino < dfrobotdfplayermini H> function explanation
- 基于Redis的分布式ID生成器
猜你喜欢
dosbox第一次使用
ES6语法总结--下篇(进阶篇 ES6~ES11)
VSCode基础配置
Esp8266 connect onenet (old mqtt mode)
Redis based distributed ID generator
MySQL時間、時區、自動填充0的問題
Single chip Bluetooth wireless burning
Latex learning
Remember an experience of ECS being blown up by passwords - closing a small black house, changing passwords, and changing ports
Postman 中级使用教程【环境变量、测试脚本、断言、接口文档等】
随机推荐
1081 rational sum (20 points) points add up to total points
Esp8266 connect onenet (old mqtt mode)
Minio file download problem - inputstream:closed
STM32 how to locate the code segment that causes hard fault
Use of lists
Arduino gets the length of the array
js 变量作用域和函数的学习笔记
Walk into WPF's drawing Bing Dwen Dwen
HCIP Day 12
JS variable types and common type conversions
Important methods of array and string
Arduino uno R3 register writing method (1) -- pin level state change
AMBA、AHB、APB、AXI的理解
MySQL时间、时区、自动填充0的问题
Arduino get random number
Servlet
單片機藍牙無線燒錄
Fashion Gen: the general fashion dataset and challenge paper interpretation & dataset introduction
Mysqldump error1066 error solution
(三)R语言的生物信息学入门——Function, data.frame, 简单DNA读取与分析