【视角的跟随、旋转、缩放实现】

首先,在实现这些功能之前,我们给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——视角的跟随、旋转、缩放的更多相关文章

  1. 【Unity3D】简单常用的功能实现1——鼠标点击实现移动

    [鼠标点击实现移动] 第一步,在要移动的GameObject的Inspector面板中添加角色控制器组件并调整参数. 参数的调整可以依照Scene面板,如下图的绿色线框(角色控制器组件是一种胶囊形状的 ...

  2. Unity3D事件顺序与功能

    Unity3D中所有控制脚本的基类MonoBehaviour有一些虚函数用于绘制中事件的回调,也可以直接理解为事件函数,例如大家都很清楚的Start,Update等函数,以下做个总结. Awake 当 ...

  3. iOS常用小功能

    CHENYILONG Blog 常用小功能 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong  ...

  4. iOS 常用小功能 总结

    常用小功能 iOS中的很多小功能都是非常简单的,几行代码就搞定了,比如打电话.打开网址.发邮件.发短信等 打电话 方法一(不被采用): 拨号之前会弹框询问用户是否拨号,拨完后能自动回到原应用 NSUR ...

  5. Pandas常用基本功能

    Series 和 DataFrame还未构建完成的朋友可以参考我的上一篇博文:https://www.cnblogs.com/zry-yt/p/11794941.html 当我们构建好了 Series ...

  6. Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(上)

    <Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(上)> <Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(下)> 目的:指导项 ...

  7. Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(下)

    <Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(上)> <Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(下)> 目的:指导项 ...

  8. WPF绘制简单常用的Path

    写代码出身的我们经常需要使用一些简单 但是不是规则图形的Path 但限于美工功底有限 不知道怎么去画 下面我告诉大家一些简单的小技巧 用代码来画Path 个人还是比较喜欢用代码 因为数值控制的更精细 ...

  9. ASP.NET MVC 学习4、Controller中添加SearchIndex页面,实现简单的查询功能

    参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-method ...

随机推荐

  1. 深入探究ASP.NET Core异常处理中间件

    前言     全局异常处理是我们编程过程中不可或缺的重要环节.有了全局异常处理机制给我们带来了很多便捷,首先我们不用满屏幕处理程序可能出现的异常,其次我们可以对异常进行统一的处理,比如收集异常信息或者 ...

  2. max depth exceeded when dereferencing c0-param0的问题

    在做项目的时候,用到了dwr,有一次居然报错,错误是max depth exceeded when dereferencing c0-param0 上网查了一下,我居然传参数的时候传的是object类 ...

  3. int与bigdecimal的相互转换

    int转bigdecimal BigDecimal number = new BigDecimal(0); int value=score; number=BigDecimal.valueOf((in ...

  4. Tornado的使用

    Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快.得利于其非阻塞的方式和对 epoll 的运用 基本操作 torn ...

  5. Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系

    1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了 ...

  6. # Mysql常用函数总结(一)

    Mysql常用函数总结(一) 博客已搬家,更多内容查看https://liangyongrui.github.io/ 遇到什么总结什么 DATE_SUB(date,INTERVAL expr type ...

  7. 3.第一个scrapy项目

    第一个scrapy项目 1. 创建scrapy项目 1.1 创建项目三剑客 这里的三剑客指的是:创建项目以及运行项目的三条命令 1.1.1 创建项目 scrapy stratproject 项目名称 ...

  8. 二叉树的镜像(剑指offer-18)

    题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 解析 先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子节点, 当交换完所有的非叶子结点的左右子结点之后,就得到了树的镜像 ...

  9. 显示IP地址的命令

    显示IP地址的命令   Centos7默认显示IP地址的命令       #获取所有网卡的IP地址 [root@clf ~]# ip  a1: lo: <LOOPBACK,UP,LOWER_UP ...

  10. 16进制字符串转BCD码

    15位IMEI字符串转8位BCD码 public static string SwapStr(string str) { return (str.Substring(1, 1) + str.Subst ...