当前位置:网站首页>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;// 返回目标点
}
}
边栏推荐
- Cannot change version of project facet Dynamic Web Module to 2.3.
- Detailed explanation of truncate usage
- Arduino gets the length of the array
- Pytorch four commonly used optimizer tests
- Redis 缓存更新策略,缓存穿透、雪崩、击穿问题
- PT OSC deadlock analysis
- Dead loop in FreeRTOS task function
- Mp3mini playback module Arduino < dfrobotdfplayermini H> function explanation
- Embedded startup process
- RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED
猜你喜欢
Générateur d'identification distribué basé sur redis
ES6 grammar summary -- Part I (basic)
(三)R语言的生物信息学入门——Function, data.frame, 简单DNA读取与分析
JS Title: input array, exchange the largest with the first element, exchange the smallest with the last element, and output array.
Missing value filling in data analysis (focus on multiple interpolation method, miseforest)
ORA-02030: can only select from fixed tables/views
Stm32f1+bc20+mqtt+freertos system is connected to Alibaba cloud to transmit temperature and humidity and control LED lights
MySQL takes up too much memory solution
数据库课程设计:高校教务管理系统(含代码)
Basic operations of databases and tables ----- classification of data
随机推荐
CUDA C programming authoritative guide Grossman Chapter 4 global memory
基于Redis的分布式ID生成器
ES6 grammar summary -- Part I (basic)
Fashion Gen: the general fashion dataset and challenge paper interpretation & dataset introduction
Working principle of genius telephone watch Z3
[leetcode15] sum of three numbers
ES6语法总结--上篇(基础篇)
Common DOS commands
How to add music playback function to Arduino project
JS 函数提升和var变量的声明提升
MySQL占用内存过大解决方案
[leetcode19] delete the penultimate node in the linked list
Use of lists
[Leetcode15]三数之和
What is the maximum length of MySQL varchar field
vim命令行笔记
JS数组常用方法的分类、理解和运用
JS正则表达式基础知识学习
@Autowired 和 @Resource 的区别
Rough analysis of map file