当前位置:网站首页>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;// 返回目标点
}
}
边栏推荐
- MySQL time, time zone, auto fill 0
- VIM command line notes
- Problèmes avec MySQL time, fuseau horaire, remplissage automatique 0
- Expected value (EV)
- Kaggle competition two Sigma connect: rental listing inquiries (xgboost)
- vim命令行笔记
- JS regular expression basic knowledge learning
- RuntimeError: cuDNN error: CUDNN_ STATUS_ NOT_ INITIALIZED
- Servlet
- Working principle of genius telephone watch Z3
猜你喜欢
JS Title: input array, exchange the largest with the first element, exchange the smallest with the last element, and output array.
单片机蓝牙无线烧录
History object
Basic operations of databases and tables ----- creating data tables
ES6语法总结--上篇(基础篇)
Basic operations of databases and tables ----- modifying data tables
(3) Introduction to bioinformatics of R language - function, data Frame, simple DNA reading and analysis
Vscode basic configuration
Latex learning
JS 函数提升和var变量的声明提升
随机推荐
Imgcat usage experience
Mysqldump error1066 error solution
Gateway fails to route according to the service name, and reports an error service unavailable, status=503
Esp8266 connects to onenet cloud platform (mqtt) through Arduino IDE
JUC forkjoin and completable future
Knowledge summary of request
ES6 grammar summary -- Part I (basic)
[offer29] sorted circular linked list
1081 rational sum (20 points) points add up to total points
[leetcode622]设计循环队列
JS variable types and common type conversions
Mp3mini playback module Arduino < dfrobotdfplayermini H> function explanation
Rough analysis of map file
Fashion Gen: the general fashion dataset and challenge paper interpretation & dataset introduction
JS regular expression basic knowledge learning
2021.11.10汇编考试
Embedded startup process
Esp8266 connects to bafayun (TCP maker cloud) through Arduino IED
Whistle+switchyomega configure web proxy
Redis cache update strategy, cache penetration, avalanche, breakdown problems