【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 ...
随机推荐
- 深入探究ASP.NET Core异常处理中间件
前言 全局异常处理是我们编程过程中不可或缺的重要环节.有了全局异常处理机制给我们带来了很多便捷,首先我们不用满屏幕处理程序可能出现的异常,其次我们可以对异常进行统一的处理,比如收集异常信息或者 ...
- max depth exceeded when dereferencing c0-param0的问题
在做项目的时候,用到了dwr,有一次居然报错,错误是max depth exceeded when dereferencing c0-param0 上网查了一下,我居然传参数的时候传的是object类 ...
- int与bigdecimal的相互转换
int转bigdecimal BigDecimal number = new BigDecimal(0); int value=score; number=BigDecimal.valueOf((in ...
- Tornado的使用
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快.得利于其非阻塞的方式和对 epoll 的运用 基本操作 torn ...
- Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系
1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了 ...
- # Mysql常用函数总结(一)
Mysql常用函数总结(一) 博客已搬家,更多内容查看https://liangyongrui.github.io/ 遇到什么总结什么 DATE_SUB(date,INTERVAL expr type ...
- 3.第一个scrapy项目
第一个scrapy项目 1. 创建scrapy项目 1.1 创建项目三剑客 这里的三剑客指的是:创建项目以及运行项目的三条命令 1.1.1 创建项目 scrapy stratproject 项目名称 ...
- 二叉树的镜像(剑指offer-18)
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 解析 先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子节点, 当交换完所有的非叶子结点的左右子结点之后,就得到了树的镜像 ...
- 显示IP地址的命令
显示IP地址的命令 Centos7默认显示IP地址的命令 #获取所有网卡的IP地址 [root@clf ~]# ip a1: lo: <LOOPBACK,UP,LOWER_UP ...
- 16进制字符串转BCD码
15位IMEI字符串转8位BCD码 public static string SwapStr(string str) { return (str.Substring(1, 1) + str.Subst ...