最近在写关于相机跟随的逻辑,其实最早接触相机跟随是在Unity官网的一个叫Roll-a-ball tutorial上,其中简单的涉及了关于相机如何跟随物体的移动而移动,如下代码:

 using UnityEngine;
using System.Collections; public class CameraController : MonoBehaviour { public GameObject player; private Vector3 offset; void Start ()
{
offset = transform.position - player.transform.position;
} void LateUpdate ()
{
transform.position = player.transform.position + offset;
}
}

简单相机移动

  可以很容易的理解上述的代码: 在初始化时计算与对应物体的向量差值,然后在LateUpdate中对相机位置进行及时更新,至于为什么要放在LateUpdate,因为LateUpdate是等所有脚本的Update跑完之后

在更新自己的逻辑,这样相机得到物体的位置往往是最新的 。具体可以看 Unity关于脚本生命周期 中有提到。

  上述的代码 , 相机是实时跟踪的, 其实相机的跟踪可以变的跟平滑一点,可以利用Unity中的Mathf.Lerp,在每一帧做一个线性的差值,这样的话可以使相机跟随变的更平滑一点,如下优化的代码:

 using UnityEngine;
using System.Collections; public class FollowBehavior : MonoBehaviour { public Transform trackingTarget;
public float offsetX = 5.0f;
public float offsetY = 4.0f;
public float followSpeed = 1.0f; public bool isXLocked = false;
public bool isYLocked = false;
// Use this for initialization
void Start () {
//m_offset = transform.position - trackingTarget.position;
} // Update is called once per frame
void LateUpdate () {
//transform.position = trackingTarget.position + m_offset;
float newX = transform.position.x;
float targetX = trackingTarget.position.x + offsetX;
if (!isXLocked)
{
newX = Mathf.Lerp(newX, targetX, Time.deltaTime * followSpeed);
}
float newY = transform.position.y;
float targetY = trackingTarget.position.y + offsetY;
if (!isYLocked)
{
newY = Mathf.Lerp(newY, targetY, Time.deltaTime * followSpeed);
}
transform.position = new Vector3(newX , newY , transform.position.z);
}
}

平滑的跟踪

  上述代码能满足大多数情况,但是如果一个场景里有多个焦点呢? 比如现在要满足的业务条件是:    

  • 当鼠标对屏幕进行拖拽时,需要移动相机
  • 当有多个焦点时,如何更好的切换

  我们先来实现第一个需求,先讲讲现在具备哪些条件:

  • Input.GetMouseButtonDown(0) : 这个表示在某一帧按下鼠标左键,会返回true,如果你一直按着不放(返回的是false),直到你松开再按下(才会再次返回true) 可以参考文档
  • Input.GetMouseButton(0): 这个表示当前是鼠标左键按下,会返回true 可以参考文档

  通过上述接口,我们可以实现拖拽了,思路的话就不细说,看代码就行:

         void DragCamera()
{
Vector3 nowMousePos = Input.mousePosition;
Vector3 move = nowMousePos - m_originDragPos;
move = Camera.main.ScreenToViewportPoint(move) * DragSpeed * -;
//平移没有差值运算
transform.Translate(move);
float x = Mathf.Clamp(transform.position.x, minXAndY.x, maxXAndY.x);
float y = Mathf.Clamp(transform.position.y, minXAndY.y, maxXAndY.y);
Vector3 pos = new Vector3(x , y , transform.position.z);
transform.position = pos;
m_originDragPos = nowMousePos;
} // Update is called once per frame
void Update()
{
int mouse = (int)MouseType.LEFT;
//记录某一帧时按下的状态(之后的持续按下都返回false,知道下次释放在按下返回true)
if (Input.GetMouseButtonDown(mouse))
{
m_bIsDrag = true;
//屏幕坐标系
m_originDragPos = Input.mousePosition;
return;
}
//表示当前的释放
if (!Input.GetMouseButton(mouse))
{
m_bIsDrag = false;
return;
}
} void LateUpdate()
{
if (m_bIsDrag)
{
DragCamera();
}
}

拖拽代码

 这边提一下在DragCamera函数中如果OriginDragPos不及时更新,屏幕在鼠标移动时会一直移动,因为在计算是产生的move向量一直有值,所以会不断偏移,这边看需求吧。

  上述的代码已经可以实现相机的拖拽了,但是如果你的屏幕上有UI结构,按下UI结构时,点击UI结构 ,其实也会调用 Input.GetMouseButtonDown(0),就会调用拖拽函数,但是

往往这种情况下,是不需要将m_bIsDrag设为true,所以如何优化屏蔽呢? 看如下代码:

 // Update is called once per frame
void Update()
{
int mouse = (int)MouseType.LEFT;
//记录某一帧时按下的状态(之后的持续按下都返回false,知道下次释放在按下返回true)
if (Input.GetMouseButtonDown(mouse))
{
//不能是UI层
PointerEventData pointerData = new PointerEventData(EventSystem.current);
pointerData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerData, results); if (results.Count > )
{
if (results[].gameObject.layer == LayerMask.NameToLayer("UI"))
{
return;
}
}
m_bIsDrag = true;
//屏幕坐标系
m_originDragPos = Input.mousePosition;
return;
}
//表示当前的释放
if (!Input.GetMouseButton(mouse))
{
m_bIsDrag = false;
return;
}
}

屏蔽UI

  这边要提一下关于Unity5.X中GUI的事件系统 确定事件产生到接收 流程是 输入模块产生事件数据 PointerEventData ,通过投影模块(射线)确定具体UI , 最终到具体UI来接收数据,

由于这不是本篇的重点,可以看一下 关于事件系统的博文我们这里模仿了前两步骤,确定当前鼠标输入的点是否UI有就直接return.

  关于焦点确定,其实算是优化项吧 ,我这边采样的是委托/事件方式来发送对应的Tranform,当然也可以直接接口。

   相机移动的例子

Unity3d学习 相机的跟随的更多相关文章

  1. unity3d之相机跟随人物

    一.第三人称视角 _1 先设置好相机与玩家之间的角度 给相机添加代码 using UnityEngine; using System.Collections; namespace CompletePr ...

  2. unity3d学习笔记(一) 第一人称视角实现和倒计时实现

    unity3d学习笔记(一) 第一人称视角实现和倒计时实现 1. 第一人称视角 (1)让mainCamera和player(视角对象)同步在一起 因为我们的player是生成的,所以不能把mainCa ...

  3. Unity3D学习笔记12——渲染纹理

    目录 1. 概述 2. 详论 3. 问题 1. 概述 在文章<Unity3D学习笔记11--后处理>中论述了后处理是帧缓存(Framebuffer)技术实现之一:而另外一个帧缓存技术实现就 ...

  4. Unity3D学习笔记2——绘制一个带纹理的面

    目录 1. 概述 2. 详论 2.1. 网格(Mesh) 2.1.1. 顶点 2.1.2. 顶点索引 2.2. 材质(Material) 2.2.1. 创建材质 2.2.2. 使用材质 2.3. 光照 ...

  5. Unity3D学习笔记3——Unity Shader的初步使用

    目录 1. 概述 2. 详论 2.1. 创建材质 2.2. 着色器 2.2.1. 名称 2.2.2. 属性 2.2.3. SubShader 2.2.3.1. 标签(Tags) 2.2.3.2. 渲染 ...

  6. Unity3D学习笔记4——创建Mesh高级接口

    目录 1. 概述 2. 详论 3. 其他 4. 参考 1. 概述 在文章Unity3D学习笔记2--绘制一个带纹理的面中使用代码的方式创建了一个Mesh,不过这套接口在Unity中被称为简单接口.与其 ...

  7. Unity3D学习笔记6——GPU实例化(1)

    目录 1. 概述 2. 详论 3. 参考 1. 概述 在之前的文章中说到,一种材质对应一次绘制调用的指令.即使是这种情况,两个三维物体使用同一种材质,但它们使用的材质参数不一样,那么最终仍然会造成两次 ...

  8. Unity3D学习笔记7——GPU实例化(2)

    目录 1. 概述 2. 详论 2.1. 实现 2.2. 解析 3. 参考 1. 概述 在上一篇文章<Unity3D学习笔记6--GPU实例化(1)>详细介绍了Unity3d中GPU实例化的 ...

  9. Unity3D学习笔记8——GPU实例化(3)

    目录 1. 概述 2. 详论 2.1. 自动实例化 2.2. MaterialPropertyBlock 3. 参考 1. 概述 在前两篇文章<Unity3D学习笔记6--GPU实例化(1)&g ...

随机推荐

  1. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 5.安装Database软件 5. ...

  2. 本人提供微软系.NET技术顾问服务,欢迎企业咨询!

    背景: 1:目前微软系.NET技术高端人才缺少. 2:企业很难直接招到高端技术人才. 3:本人提供.NET技术顾问,保障你的产品或项目在正确的技术方向. 技术顾问服务 硬服务项: 1:提供技术.决策. ...

  3. C++ 应用程序性能优化

    C++ 应用程序性能优化 eryar@163.com 1. Introduction 对于几何造型内核OpenCASCADE,由于会涉及到大量的数值算法,如矩阵相关计算,微积分,Newton迭代法解方 ...

  4. HTML骨架结构

    前面的话   一个完整的HTML文档必须包含3个部分:文档声明.文档头部和文档主体.而正是它们构成了HTML的骨架结构.前面已经分别介绍过文档声明和文档头部,本文将详细介绍构成HTML骨架结构的基础元 ...

  5. 【开源】.net 分布式架构之监控平台

    开源地址:http://git.oschina.net/chejiangyi/Dyd.BaseService.Monitor .net 简单监控平台,用于集群的性能监控,应用耗时监控管理,统一日志管理 ...

  6. 算法与数据结构(十六) 快速排序(Swift 3.0版)

    上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...

  7. 阿里云服务器上配置并使用: PHP + Redis + Mysql 从配置到使用

    (原创出处为本博客,http://www.cnblogs.com/linguanh/) 目录: 一,下载 二,解压 三,配置与启动 四,测试 Redis 五,配置 phpRedis 扩展 六,综合测试 ...

  8. Oracle 数据库知识汇总篇

    Oracle 数据库知识汇总篇(更新中..) 1.安装部署篇 2.管理维护篇 3.数据迁移篇 4.故障处理篇 5.性能调优篇 6.SQL PL/SQL篇 7.考试认证篇 8.原理体系篇 9.架构设计篇 ...

  9. SMBus set up a 2-byte EEPROM address for read/write

    Sequencer Engine spec: http://www.analog.com/media/en/technical-documentation/data-sheets/ADM1260.pd ...

  10. Struts2.5需要的最少jar文件

    以Struts2.5.2为例 从官网上下载“struts-2.5.2-min-lib.zip”,里面有7个jar文件: commons-fileupload-1.3.2.jarcommons-io-2 ...