【Unity3D】简单常用的功能实现2——视角的跟随、旋转、缩放
【视角的跟随、旋转、缩放实现】
首先,在实现这些功能之前,我们给Hierarchy面板中的主摄像机额外包装几层Empty Object,形成一个新的摄像机结构,如下图(当然这些空物体的命名大家按自己方便就是了):
然后调整一下CameraUpAndDown、CameraZoomContainer的几个参数(注意,调参这个步骤一定不要漏掉,调参是为了使主摄像机在旋转拉伸时能始终对准物体):
如图:
CameraUpAndDown物体rotateZ轴90°。(旋转CameraUpAndDown的Z轴是为了使主摄像机视角在旋转、拉伸时始终对准物体,)
CameraZoomContainer物体RotateY轴-90°。(旋转CameraZoomContainer的Y轴是为了使编辑器状态下视角在旋转、拉伸时始终对准物体,但不修改的话并不会影响运行时的视角)
CameraZoomContainer物体Position.X改为一个正数,(不一定是4,只要能使你的主摄像机观察到物体就行,0的话会使主摄像机距离物体太近。)
第二步,在CameraFollowAndRotate的Inspector面板下添加一个脚本(这里我把这个脚本命名为CameraCtrl),代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class CameraCtrl : MonoBehaviour
{
public static CameraCtrl Instance; /// <summary>
/// 摄像机结构下的几个子物体, m_CameraUpAndDown控制垂直观察角度,m_CameraZoomContainer控制镜头对准方向, m_CameraContainer控制物体与镜头间距离
/// </summary>
[SerializeField]
private Transform m_CameraUpAndDown;
[SerializeField]
private Transform m_CameraZoomContainer;
[SerializeField]
private Transform m_CameraContainer; private void Awake()
{
Instance = this;
} //初始化函数
public void Init()
{
//如果Camera垂直观察角度的初始值、Camera与物体距离的初始值在限定范围外,进行矫正
m_CameraUpAndDown.Rotate(, , 45f);
m_CameraUpAndDown.localEulerAngles = new Vector3(, , Mathf.Clamp(m_CameraUpAndDown.localEulerAngles.z, 1f, 90f));
m_CameraContainer.localPosition = new Vector3(, , Mathf.Clamp(m_CameraContainer.localPosition.z, -5f, ));
} //实时看向主角物体
public void AutoLookAt(Vector3 position)
{
m_CameraZoomContainer.LookAt(position);
} /// <summary>
/// 控制Camera水平旋转 左=0 右=1
/// </summary>
/// <param name="type"></param>
public void SetCameraRotate(int type)
{
transform.Rotate(, * Time.deltaTime * (type == ? : -), );
} /// <summary>
/// 控制Camera垂直旋转 上=0 下=1
/// </summary>
/// <param name="type"></param>
public void SetCameraUpAndDown(int type)
{
m_CameraUpAndDown.Rotate(, , * Time.deltaTime * (type == ? : -));
//锁定Camera垂直观察角度的范围1°至90°
m_CameraUpAndDown.localEulerAngles = new Vector3(, , Mathf.Clamp(m_CameraUpAndDown.localEulerAngles.z, 1f, 90f));
} /// <summary>
/// 控制Camera和物体的距离 拉近=0 拉远1
/// </summary>
/// <param name="type"></param>
public void SetCameraZoom(int type)
{ //注意,虽然方法名有Zoom,但是控制镜头与物体距离的是m_CameraContainer,所以这里修改m_CameraContainer的position的Z轴
m_CameraContainer.Translate(Vector3.forward * * Time.deltaTime * (type == ? : -));
m_CameraContainer.localPosition = new Vector3(, , Mathf.Clamp(m_CameraContainer.localPosition.z, -5f, ));
}
}
注意! 13、15、17三个序列化字段的赋值要在CameraFollowAndRotate的Inspector面板中进行,使这些变量指向对应的组件,如下图:
第三步,在 视角要跟随的Object 的脚本中 实现对CameraCtrl脚本方法的调用,这里就简单举例了:
//该方法在要跟随的Object的脚本的Update()中调用即可实现视角的旋转、缩放以及视角的实时跟随
private void cameraAutoFollow()
{
if (CameraCtrl.Instance == null) { return; }
//Camera实时同步主角物体的位置并使镜头对准主角物体
CameraCtrl.Instance.transform.position = gameObject.transform.position;
CameraCtrl.Instance.AutoLookAt(gameObject.transform.position); //依照按键调整镜头视角,以按Q键实现顺时针水平旋转为例子
if (Input.GetKey(KeyCode.Q))
{
CameraCtrl.Instance.SetCameraRotate(); //参数为1 则为逆时针水平旋转
//CameraCtrl.Instance.SetCameraUpAndDown(0); //视角垂直旋转
//CameraCtrl.Instance.SetCameraZoom(0); //视角缩放
}
}
最后,对这个摄像机结构再总结一下:
CameraFollowAndRotate:通过修改该Object的Position,我们可以实现视角对移动物体的跟随、RotateY轴则可以实现视角对物体的水平旋转观察。
CameraUpAndDown:通过Rotate该Object的Z轴,我们可以实现视角对移动物体的垂直旋转观察。Z轴旋转要初始为90°
CameraZoomContainer:运行的时候Lookat方法会实时Rotate各个轴使摄像机镜头对准物体。Y轴旋转要初始为-90°以方便编辑器视窗下对Camera的调试,X轴设置为一个合适的正数就可以。
CameraContainer:通过修改该Object的Position.Z属性来拉近或拉远主摄像机与物体的距离,实现缩放。
【Unity3D】简单常用的功能实现2——视角的跟随、旋转、缩放的更多相关文章
- 【Unity3D】简单常用的功能实现1——鼠标点击实现移动
[鼠标点击实现移动] 第一步,在要移动的GameObject的Inspector面板中添加角色控制器组件并调整参数. 参数的调整可以依照Scene面板,如下图的绿色线框(角色控制器组件是一种胶囊形状的 ...
- Unity3D事件顺序与功能
Unity3D中所有控制脚本的基类MonoBehaviour有一些虚函数用于绘制中事件的回调,也可以直接理解为事件函数,例如大家都很清楚的Start,Update等函数,以下做个总结. Awake 当 ...
- iOS常用小功能
CHENYILONG Blog 常用小功能 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong ...
- iOS 常用小功能 总结
常用小功能 iOS中的很多小功能都是非常简单的,几行代码就搞定了,比如打电话.打开网址.发邮件.发短信等 打电话 方法一(不被采用): 拨号之前会弹框询问用户是否拨号,拨完后能自动回到原应用 NSUR ...
- Pandas常用基本功能
Series 和 DataFrame还未构建完成的朋友可以参考我的上一篇博文:https://www.cnblogs.com/zry-yt/p/11794941.html 当我们构建好了 Series ...
- Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(上)
<Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(上)> <Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(下)> 目的:指导项 ...
- Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(下)
<Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(上)> <Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(下)> 目的:指导项 ...
- WPF绘制简单常用的Path
写代码出身的我们经常需要使用一些简单 但是不是规则图形的Path 但限于美工功底有限 不知道怎么去画 下面我告诉大家一些简单的小技巧 用代码来画Path 个人还是比较喜欢用代码 因为数值控制的更精细 ...
- ASP.NET MVC 学习4、Controller中添加SearchIndex页面,实现简单的查询功能
参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-method ...
随机推荐
- TCP端口扫描类型-隐蔽扫描和僵尸扫描
TCP扫描有三种类型:全连接扫描,隐蔽扫描,僵尸扫描.全连接扫描无须赘述. 隐蔽扫描:发送完SYN数据包以及收到SYN/ACK数据包后不再发送SCK数据包,由于没有建立完整的TCP连接,所以在目标主机 ...
- Windows Server 2019 container容器化-Docker安装
一.启用服务器Hyper-V,Containers特性 Install-WindowsFeature -Name Hyper-V,Containers -IncludeAllSubFeature -I ...
- cf # 420 div.2
说说题吧前两道暴力 a直接枚举每个位置然后枚举所在行和列 b直接枚举所有的x的banana 的数量.计算方式等差数列求和小学生难度.记得long long.int转longlong c记下remove ...
- 弹性盒模型中flex-grow 和flex的区别
在flex弹性盒模型体系中,flex-grow和flex都有对子元素进行放大的作用,但是这两个属性在放大时的计算方法不同,在使用时候要注意,使用正确的放大属性,从而达到自己想要的效果. 先来看下两个属 ...
- dart快速入门教程 (7.4)
7.12.多态 多态字面上理解就是多种状态,通俗的说,多态表现为父类定义一个方法不去实现,子类继承这个方法后实现父类的方法,这个方法有多种表现 // import 'person.dart'; voi ...
- matplotlib中文显示乱码解决方法
在学习<机器学习实战>这本书的决策树一章时,要用matplotlib画出决策树,然而在显示中文时出现了乱码 import matplotlib.pyplot as plt #定义文本框和箭 ...
- 服务消费者(Ribbon)
上一篇文章,简单概述了服务注册与发现,在微服务架构中,业务都会被拆分成一个独立的服务,服务之间的通讯是基于http restful的,Ribbon可以很好地控制HTTP和TCP客户端的行为,Sprin ...
- 如何将less编译成css文件__less自动编译成css的方法总结
作为css的预处理less,拥有着比css更快捷方便,扩展了css的变量.Mixin.函数等特性,使 CSS 更易维护和扩展. 如何你已经回使用css,那么less就很容易上手了.如果不使用less ...
- C# 爬取猫眼电影数据
最近做了一个新项目,因为项目需要大量电影数据,猫眼电影又恰好有足够的数据,就上猫眼爬数据了. 1.先分析一下网页地址,发现电影都是被排好序号了,这就很简单了. 2.在分析页面,这次主要爬取黄色框中的内 ...
- Vue---day05
目录 2. 客户端项目搭建 2.1 创建项目目录 2.2 初始化项目 2.3 安装路由vue-router 2.3.1 下载安装路由组件 2.3.2 配置路由 2.3.2.1 初始化路由对象 2.3. ...