Unity相机的移动
由于项目中开发离不开相机视角的移动缩放等等,每次重新写比较麻烦,于是小编总结了一些移动效果较好一点的代码,分鼠标事件和触摸事件(EasyTouch)的2个版本。
鼠标版代码如下:
/** 1.通过鼠标的操作对相机的控制* * 2.操作方式: a.鼠标左键按下时拖动移动视角* b.滑轮滚动对应视角拉进或拉远* c.鼠标右键拖动进行视角的左右上下旋转* d.是否锁定相机* * 3.旋转相机时采用发射射线获取碰撞点并以其中心进行旋转的方式,* 当获取的碰撞点为NULL时,代表视角超出可视范围,此时停止相机的移动以及旋转;* * 4.与此脚本想关联的脚本: StaticFunction.cs* * 5.与此脚本相关联的插件: DoTween*/using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;public class CameraMove : MonoBehaviour {public static CameraMove Instance = null;public LayerMask m_layerMask;private Transform m_camera = null;private GameObject m_tempObj = null;//相机可拉进拉远的最远距离private float m_Max;//相机的可移动范围(判断条件时使用世界坐标)private float m_XMax = 0;private float m_XMin = 0;private float m_YMax = 0;private float m_YMin = 0;public Transform LeftTop = null;public Transform RightBottom = null;public Transform Center = null; //创建一个空物体使其在地图中心,并将其赋值private Vector2 m_ScreenCenterPoint = Vector2.zero;private void Awake(){if (Instance == null) Instance = this;else if (Instance != this) Destroy(this);}// Use this for initializationvoid Start () {m_camera = Camera.main.transform;m_tempObj = new GameObject("TempObj");m_tempObj.transform.parent = m_camera;m_tempObj.transform.localPosition = Vector3.zero;CorrectEulerAngles();m_ScreenCenterPoint = new Vector2(Screen.width / 2.0f, Screen.height / 2.0f);m_Max = m_camera.GetComponent<Camera>().fieldOfView + 20;m_XMin = LeftTop.position.x;m_XMax = RightBottom.position.x;m_YMin = RightBottom.position.z;m_YMax = LeftTop.position.z;}// Update is called once per framevoid FixedUpdate () {if (Config.CameraIsLocked) return;if (Input.GetMouseButton(0)){MoveCamera(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"), 1);}else if (Input.GetMouseButton(1)){CorrectEulerAngles();RotateCamera(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"), 5);}else if (Input.GetMouseButtonUp(1)){}PullInOrPullAway(Input.GetAxis("Mouse ScrollWheel"), 10);}private void RotateCamera(float _MouseX, float _MouseY, float _Speed) //旋转相机{Vector3 temp = GetScreenCenterHitPoint();m_camera.RotateAround(temp, Vector3.up, _MouseX * _Speed);float incremental = 10.0f; //弧度的增量///通过m_camera.eulerAngles.x的弧度来限制旋转角度//if (_MouseY * _Speed >= incremental) return; //控制旋转幅度//if (m_camera.eulerAngles.x >= incremental && m_camera.eulerAngles.x <= (90 - incremental))//{// m_camera.RotateAround(temp, m_camera.right, -_MouseY * _Speed);//}//else if (m_camera.eulerAngles.x < incremental)//{// if (_MouseY < 0) m_camera.RotateAround(temp, m_camera.right, -_MouseY * _Speed);//}//else if (m_camera.eulerAngles.x > (90 - incremental))//{// if (_MouseY > 0) m_camera.RotateAround(temp, m_camera.right, -_MouseY * _Speed);//}///end//通过通过m_camera.forward与m_tempObj.transform.forward向量的夹角限制相机的旋转角度if (_MouseY * _Speed >= incremental) return; //控制旋转幅度float angles = Vector3.Angle(m_camera.forward, m_tempObj.transform.forward);if (angles > incremental && angles < (90 - incremental)){m_camera.RotateAround(temp, m_camera.right, -_MouseY * _Speed);}else if (angles <= incremental){if (_MouseY < 0) m_camera.RotateAround(temp, m_camera.right, -_MouseY * _Speed);}else if (angles >= (90 - incremental)){if (_MouseY > 0) m_camera.RotateAround(temp, m_camera.right, -_MouseY * _Speed);}//end}private void MoveCamera(float _MouseX, float _MouseY, float _Speed) //移动相机{m_camera.Translate(Vector3.right * -_MouseX * _Speed, m_tempObj.transform);m_camera.Translate(Vector3.forward * -_MouseY * _Speed, m_tempObj.transform);///控制相机的移动范围//if (m_camera.position.x <= m_XMin)//{// m_camera.position = new Vector3(m_XMin, m_camera.position.y, m_camera.position.z);//}//else if (m_camera.position.x >= m_XMax)//{// m_camera.position = new Vector3(m_XMax, m_camera.position.y, m_camera.position.z);//}//if (m_camera.position.z <= m_YMin)//{// m_camera.position = new Vector3(m_camera.position.x, m_camera.position.y, m_YMin);//}//else if (m_camera.position.z >= m_YMax)//{// m_camera.position = new Vector3(m_camera.position.x, m_camera.position.y, m_YMax);//}///end}private void PullInOrPullAway(float _MouseScrollWheel, float _Speed) //拉进拉远相机{///通过改变相机的fieldOfView的值实现其效果//Camera temp = m_camera.GetComponent<Camera>();//if (_MouseScrollWheel > 0)//{// if (temp.fieldOfView >= 10 + _Speed)// {// temp.fieldOfView -= _Speed;// }//}//if (_MouseScrollWheel < 0)//{// if (temp.fieldOfView <= m_Max)// {// temp.fieldOfView += _Speed;// }//}///endm_camera.Translate(Vector3.forward * _MouseScrollWheel * _Speed, Space.Self);}private bool IsOutOfRange() //判断是否超出可视区域的范围,超出范围时停止相机的移动{Vector3 temp = GetScreenCenterHitPoint();if (temp != Vector3.zero){return false;}return true;}private void CorrectEulerAngles() //做相机以及TempObj游戏物体的轴方向的校正,便于相机的移动{m_tempObj.transform.eulerAngles = new Vector3(0, m_camera.eulerAngles.y, m_camera.eulerAngles.z);}private Vector3 GetScreenCenterHitPoint(){Vector3 temp = StaticFunction.GetClickedPoint(m_ScreenCenterPoint, m_layerMask);if (temp != Vector3.zero) return temp;return Vector3.zero;}public void SetEastPoint(){Vector3 point = new Vector3(LeftTop.position.x, m_camera.position.y, LeftTop.position.z - (LeftTop.position.z - RightBottom.position.z) / 2.0f);m_camera.position = point;m_camera.LookAt(Center);}public void SetSouthPoint(){Vector3 point = new Vector3(LeftTop.position.x + (RightBottom.position.x - LeftTop.position.x)/2.0f, m_camera.position.y, LeftTop.position.z);m_camera.position = point;m_camera.LookAt(Center);}public void SetWestPoint(){Vector3 point = new Vector3(RightBottom.position.x, m_camera.position.y, LeftTop.position.z - (LeftTop.position.z - RightBottom.position.z) / 2.0f);m_camera.position = point;m_camera.LookAt(Center);}public void SetNorthPoint(){Vector3 point = new Vector3(LeftTop.position.x + (RightBottom.position.x - LeftTop.position.x) / 2.0f, m_camera.position.y, RightBottom.position.z);m_camera.position = point;m_camera.LookAt(Center);}public void SetTopView() //顶视图{m_camera.eulerAngles = new Vector3(90.0f, m_camera.eulerAngles.y, m_camera.eulerAngles.z);m_camera.DOMove(new Vector3(Center.position.x, m_camera.position.y, Center.position.z), 0.5f);CorrectEulerAngles();}
}
触摸版(EasyTouch)代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;public class CameraMove : MonoBehaviour {private bool m_isRotate = false;public Transform m_gameObject = null;private bool m_isThreeViewDrawing = false; //是否开启三视图的功能private int m_speedControl = 40; //视角移动速度的控制private int m_distance = 50; //进行三视图观察时相机离游戏物体的距离private Vector3 m_replacePos = Vector3.zero; //记录相机的俯视视角的坐标点private void OnEnable(){EasyTouch.On_TouchStart += On_TouchStart;EasyTouch.On_TouchDown += On_TouchDown;EasyTouch.On_TouchUp += On_TouchUp;EasyTouch.On_DoubleTap += On_DoubleTap;EasyTouch.On_TouchStart2Fingers += On_TouchStart2Fingers;EasyTouch.On_Cancel2Fingers += On_Cancel2Fingers;EasyTouch.On_PinchIn += On_PinchIn;EasyTouch.On_PinchOut += On_PinchOut;EasyTouch.On_PinchEnd += On_PinchEnd;}// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {if (Config.IsRotate){m_isRotate = true;}else if (!Config.IsRotate){m_isRotate = false;}if (m_isThreeViewDrawing){ThreeViewDrawing(Config.state_ThreeViewDrawing);}}private void OnDisable(){UnsubscribeEvent();}private void OnDestroy(){UnsubscribeEvent();}private void UnsubscribeEvent(){EasyTouch.On_TouchStart -= On_TouchStart;EasyTouch.On_TouchDown -= On_TouchDown;EasyTouch.On_TouchUp -= On_TouchUp;EasyTouch.On_DoubleTap -= On_DoubleTap;EasyTouch.On_TouchStart2Fingers -= On_TouchStart2Fingers;EasyTouch.On_Cancel2Fingers -= On_Cancel2Fingers;EasyTouch.On_PinchIn -= On_PinchIn;EasyTouch.On_PinchOut -= On_PinchOut;EasyTouch.On_PinchEnd -= On_PinchEnd;}// At the touch beginning private void On_TouchStart(Gesture gesture){Debug.Log("Touching Start");}// During the touch is downprivate void On_TouchDown(Gesture gesture){Debug.Log("Touching Down");if (m_isRotate) //旋转视角{RotateCamera(gesture);}else if (!m_isRotate) //移动视角{MoveCamera(gesture);}}// At the touch endprivate void On_TouchUp(Gesture gesture){Debug.Log("Touching Up");}// Double tap private void On_DoubleTap(Gesture gesture){Debug.Log("Double Tap");Ray ray = Camera.main.ScreenPointToRay(gesture.position);//从摄像机发出到触摸点坐标的射线RaycastHit hitInfo;if (Physics.Raycast(ray, out hitInfo)){if (hitInfo.collider.gameObject.tag == "House"){Config.state_ThreeViewDrawing = Config.State_ThreeViewDrawing.Nothing;m_gameObject = hitInfo.collider.gameObject.transform;Debug.Log("Find House And Name is " + m_gameObject.name);FocusOn(m_gameObject);m_replacePos = this.transform.position;m_isThreeViewDrawing = true;}}}// At the 2 fingers touch beginningprivate void On_TouchStart2Fingers(Gesture gesture){Debug.Log("Touch Start 2Fingers");// Verification that the action on the object//if (gesture.pickedObject == gameObject)//{// // disable twist gesture recognize for a real pinch end// EasyTouch.SetEnableTwist(false);// EasyTouch.SetEnablePinch(true);//}}// At the pinch inprivate void On_PinchIn(Gesture gesture){Debug.Log("Pinch In");m_isThreeViewDrawing = false;Shrunk(gesture);// Verification that the action on the object//if (gesture.pickedObject == gameObject)//{// float zoom = Time.deltaTime * gesture.deltaPinch;// Vector3 scale = transform.localScale;// transform.localScale = new Vector3(scale.x - zoom, scale.y - zoom, scale.z - zoom);//}}// At the pinch outprivate void On_PinchOut(Gesture gesture){Debug.Log("Pinch Out");Enlarge(gesture);// Verification that the action on the object//if (gesture.pickedObject == gameObject)//{// float zoom = Time.deltaTime * gesture.deltaPinch;// Vector3 scale = transform.localScale;// transform.localScale = new Vector3(scale.x + zoom, scale.y + zoom, scale.z + zoom);//}}// At the pinch endprivate void On_PinchEnd(Gesture gesture){Debug.Log("Pinch End");//if (gesture.pickedObject == gameObject)//{// transform.localScale = new Vector3(2.5f, 2.5f, 2.5f);// EasyTouch.SetEnableTwist(true);//}}// If the two finger gesture is finishedprivate void On_Cancel2Fingers(Gesture gesture){Debug.Log("Cancel 2Fingers");//EasyTouch.SetEnablePinch(true);//transform.rotation = Quaternion.identity;}private void MoveCamera(Gesture _gesture) //相机的移动{transform.Translate(Vector3.left * _gesture.deltaPosition.x / Screen.width * m_speedControl * 2);transform.Translate(Vector3.forward * -_gesture.deltaPosition.y / Screen.height * m_speedControl * 2, Space.World);}private void RotateCamera(Gesture _gesture) //旋转相机{if (_gesture.position.x - _gesture.startPosition.x < 0){transform.RotateAround(m_gameObject.position, Vector3.up, _gesture.deltaTime * m_speedControl);}else if (_gesture.position.x - _gesture.startPosition.x > 0){transform.RotateAround(m_gameObject.position, Vector3.up, -_gesture.deltaTime * m_speedControl);}}private void Enlarge(Gesture _gesture) //放大{//Camera.main.fieldOfView -= _gesture.deltaPinch * Time.deltaTime * m_speedControl * 0.5f;transform.Translate(Vector3.forward * _gesture.deltaPinch * Time.deltaTime * m_speedControl * 0.5f, Space.Self);}private void Shrunk(Gesture _gesture) //缩小{//Camera.main.fieldOfView += _gesture.deltaPinch * Time.deltaTime * m_speedControl * 0.5f;transform.Translate(Vector3.forward * -_gesture.deltaPinch * Time.deltaTime * m_speedControl * 0.5f, Space.Self);}private void FocusOn(Transform _gameObject) //把指定游戏物体作为中心的观察视角{Vector3 vec = _gameObject.transform.position;//vec.y += m_distance - 10;//vec.z -= m_distance - 10;//Sequence mySequence = DOTween.Sequence();//mySequence.Append(this.transform.DOMove(vec, 0.25f));//mySequence.Append(this.transform.DOLookAt(_gameObject.position, 0.01f));//mySequence.Play();this.transform.position = vec;this.transform.position -= this.transform.forward * m_distance;}private void ThreeViewDrawing(Config.State_ThreeViewDrawing _state) //三视图视角的切换{Debug.Log("Enter ThreeViewDrawing");switch (_state){case Config.State_ThreeViewDrawing.Left:this.transform.position = new Vector3(m_gameObject.position.x - m_distance, m_gameObject.position.y, m_gameObject.position.z);this.transform.DOLookAt(m_gameObject.position, 0.5f);Config.state_ThreeViewDrawing = Config.State_ThreeViewDrawing.Nothing;break;case Config.State_ThreeViewDrawing.Right:this.transform.position = new Vector3(m_gameObject.position.x + m_distance, m_gameObject.position.y, m_gameObject.position.z);this.transform.DOLookAt(m_gameObject.position, 0.5f);Config.state_ThreeViewDrawing = Config.State_ThreeViewDrawing.Nothing;break;case Config.State_ThreeViewDrawing.Front:this.transform.position = new Vector3(m_gameObject.position.x, m_gameObject.position.y, m_gameObject.position.z + m_distance);this.transform.DOLookAt(m_gameObject.position, 0.5f);Config.state_ThreeViewDrawing = Config.State_ThreeViewDrawing.Nothing;break;case Config.State_ThreeViewDrawing.Behind:this.transform.position = new Vector3(m_gameObject.position.x, m_gameObject.position.y, m_gameObject.position.z - m_distance);this.transform.DOLookAt(m_gameObject.position, 0.5f);Config.state_ThreeViewDrawing = Config.State_ThreeViewDrawing.Nothing;break;case Config.State_ThreeViewDrawing.Top:this.transform.position = new Vector3(m_gameObject.position.x, m_gameObject.position.y + m_distance, m_gameObject.position.z);this.transform.DOLookAt(m_gameObject.position, 0.5f);Config.state_ThreeViewDrawing = Config.State_ThreeViewDrawing.Nothing;break;case Config.State_ThreeViewDrawing.Replace:this.transform.position = m_replacePos;this.transform.DOLookAt(m_gameObject.position, 0.5f);Config.state_ThreeViewDrawing = Config.State_ThreeViewDrawing.Nothing;break;//case default:// break;}}private void Border() //相机移动的边界判断{}private void OcclusionCulling() //相机的遮挡剔除{}
}
Unity相机的移动相关推荐
- unity相机围绕模型转_围绕我们的业务模型和风险进行安全测试
unity相机围绕模型转 When we create an environment and consider our security testing from development to pro ...
- Unity 相机固定角度平移至指定物体
前言:这个也是我得一个朋友怎么做,朋友跟我说的方法,然后我就想记录下来,当个学习. 需求:相机固定视角(相机的高是15.x轴选转30.y轴旋转15),地图上有很多物体,点击后相机移动到指定物体(物体居 ...
- Unity 相机围绕目标旋转、缩放功能实现
Unity 相机围绕目标旋转.缩放功能实现 //************************************************相机围绕物体旋转.相机缩放*************** ...
- Unity相机漫游脚本FreeCamera.CS
Unity相机漫游脚本FreeCamera.CS
- unity, 相机空间 与 相机gameObject的局部空间
在unity里 相机空间 与 相机gameObject的局部空间 不重合. Camera.worldToCameraMatrix的文档中有这样一句话: Note that camera space m ...
- Unity相机漫游脚本
分享一个Unity中控制相机漫游的脚本,应用于智慧城市.数字孪生等场景操作. 直接上代码 using UnityEngine;[RequireComponent(typeof(Camera))] pu ...
- Unity 相机 2D视角 与3D 视角 自由动态 切换
在游戏运行的时候,往往需要 在 正交Orthographic (无消失点投影) 与正交Orthographic (无消失点投影) 两个视角中来回转化. 以达到 不同的 2D 与 3D 视角. So! ...
- Unity相机跟随以及子弹发射笔记
相机移动 现在还有一个问题是:主角SpaceMarine移动的时候,会走出玩家的视线,所以这里让相机跟随着SpaceMarine移动. 步骤1. 创建和设置CameraMount 在层级(Hierar ...
- Unity 相机参数详解:多相机混合、小地图实现
前言 在Unity中,相机是必不可少的一个对象,我们创建一个项目,无论是2D项目还是3D项目,都会默认创建一个MainCamera对象,这就说明了其重要性,本片博客不从参数讲起,而从功能性上来理解Un ...
- Unity学习笔记 关于Unity相机的FOV以及水平FOV和垂直FOV之间的转换
前言 关于FOV FOV 是在任何给定时间通过人眼.相机取景器或在显示屏上可见的可观察世界的范围.它指的是整个区域的覆盖范围,而不是单个固定焦点.FOV 还描述了一个人可以看到可见世界的角度. FOV ...
最新文章
- Debugging Ruby in VS Code
- c# 获取客户端IP地址方法
- 管道、重定向、vim文本编辑器
- 用户信息检索另一台服务器,客户机上一用户访问另一台机器上的informix数据库...
- SQL Server 2008基于策略的管理
- Eclipse Tomcat的一些基本配置
- android发送json格式,Android---创建Json格式数据
- react中使用构建缓存_完整的React课程:如何使用React构建聊天室应用
- QCostomPlot 示例注解 2
- HDOJ(HDU) 2123 An easy problem(简单题...)
- 基于layui的省市区三级联动(数据交互)
- prototype的理解
- jpl数据下载_火星上的AI:喷气推进实验室(JPL)的Tom Soderstrom访谈
- Java进行音视频转码
- Redis 入门指南(五)管理
- 涂鸦赞助的500个开发套件,先到先得
- Python 静态方法 类方法
- 收藏的有用博客及源码地址
- 浙大160位学者入选2020“中国高被引学者” 榜单!
- 【北邮果园微处理器设计】gpio.c 应用解读(附gpio.c源码)
热门文章
- 创业黑马|泰瑞数创:坚持数字孪生的硬核之路 不刻意追逐元宇宙风口
- ansible剧本批量安装nginx
- CentOS 7 minimal安装与使用(cpp-py) opencv静态编译
- 实验型喷雾干燥机粒径分布测量方法
- python:[[0 for i in range(L+1)]for j in range(K)]解析
- 众泰T500尊享破解安装软件包下载
- 【Python从零到壹】转义字符与原字符
- bim 二次开发c语言,BIM百科 | Revit二次开发入门--创建一个简单的程序①
- c# XAMARIN TableLayout 创建表格
- springboot整合jwt与vue的后端管理系统1