今天又来搞(zuo)事(you)情(xi)了,今天做什么呢?今天来做一个镜头控制器,用来控制镜头操作。

镜头控制器(摄像机控制器)

所谓镜头,就是我们玩游戏的时候,显示的画面,统称为镜头(也就是摄像机拍到的画面),这里又分为2d,3d,2.5d(又分为伪3d和固定视角),什么叫伪3d呢,就是3d的贴图,其实是2d方法显示,这样减少了很多运算量,固定视角的话,视角是固定的,因游戏或开发要求,而采取的3d画面但是固定视角(其实可以归到3d中去)。

功能

首先,我们要依次制作的以下功能

  1. 简单移动(这里指直接移动,类似瞬移,没有过程)
  2. 匀速运动
  3. 变速运动
  4. 简单旋转(这里指直接旋转,没有过程)
  5. 匀速旋转
  6. 变速旋转
  7. 跟随目标
  8. 根据路径来移动
  9. 以及相应的触发事件
移动

首先我们要获取摄像机对象(Camera)

using UnityEngine;
using System.Collections;[RequireComponent(typeof(Camera))]
public class CameraControl : MonoBehaviour {protected Camera camera;void Awake() {camera = this.GetComponent<Camera>();}void Update () {}
}

接着就来做移动。

using UnityEngine;
using System.Collections;[RequireComponent(typeof(Camera))]
public class CameraControl : MonoBehaviour {protected Camera camera;// 最大最小宽度public float minX = 100.0f;public float maxX = -100.0f;// 最大最小高度public float minY = 10.0f;public float maxY = 50.0f;// 最大最小深度public float minZ = 100.0f;public float maxZ = -100.0f;// 当前速度Vector3 nowSpeed;// 加速度Vector3 addSpeed;void Awake() {camera = this.GetComponent<Camera>();addSpeed = Vector3.zero;nowSpeed = Vector3.zero;}// 简单移动(瞬移)public virtual void simpleMove(float x, float y, float z) {camera.transform.position = check(x, y, z);simpleMoveEvent(camera, new Vector3(x, y, z));}public virtual void simpleMove(Vector3 pos) {camera.transform.position = check(pos);simpleMoveEvent(camera, pos);}protected virtual void simpleMoveEvent(Camera cam, Vector3 pos) {}// 匀速移动public virtual void constantMove(float x, float y, float z) {nowSpeed.x = x;nowSpeed.y = y;nowSpeed.z = z;constantMoveEvent(camera, new Vector3(x, y, z));}public virtual void constantMove(Vector3 speed) {nowSpeed = speed;constantMoveEvent(camera, speed);}protected virtual void constantMoveEvent(Camera cam, Vector3 speed) {}// 变速移动public virtual void changeMove(float x, float y, float z) {addSpeed.x = x;addSpeed.y = y;addSpeed.z = z;changeMoveEvent(camera, new Vector3(x, y, z));}public virtual void changeMove(Vector3 speed) {addSpeed = speed;changeMoveEvent(camera, speed);}protected virtual void changeMoveEvent(Camera cam, Vector3 speed) {}void Update () {Vector3 pos = camera.transform.position;pos += nowSpeed * Time.deltaTime;nowSpeed += addSpeed * Time.deltaTime;camera.transform.position = check(pos);}/* **************** 工具类函数* 范围:public(公共)* * ***************/// 检测坐标是否超出范围,并强制移动到范围内public Vector3 check(Vector3 p) {Vector3 pos = new Vector3(p.x, p.y, p.z);pos.x = Mathf.Max(pos.x, minX);pos.x = Mathf.Min(pos.x, maxX);pos.y = Mathf.Max(pos.y, minY);pos.y = Mathf.Min(pos.y, maxY);pos.z = Mathf.Max(pos.z, minZ);pos.z = Mathf.Min(pos.z, maxZ);return pos;}public Vector3 check(float x, float y, float z) {x = Mathf.Max(x, minX);x = Mathf.Min(x, maxX);y = Mathf.Max(y, minY);y = Mathf.Min(y, maxY);z = Mathf.Max(z, minZ);z = Mathf.Min(z, maxZ);return new Vector3(x, y, z);}
}

旋转

using UnityEngine;
using System.Collections;[RequireComponent(typeof(Camera))]
public class CameraControl : MonoBehaviour {protected Camera camera;// 当前旋转速度Vector3 nowRotationSpeed;// 旋转加速度Vector3 addRotationSpeed;void Awake() {camera = this.GetComponent<Camera>();addRotationSpeed = Vector3.zero;nowRotationSpeed = Vector3.zero;}// 简单旋转(瞬间)public virtual void simpleRotation(float x, float y, float z) {camera.transform.rotation = Quaternion.Euler(x, y, z);simpleRotationEvent(camera, new Vector3(x, y, z));}public virtual void simpleRotation(Vector3 pos) {camera.transform.rotation = Quaternion.Euler(pos);simpleRotationEvent(camera, pos);}protected virtual void simpleRotationEvent(Camera cam, Vector3 pos) {}// 匀速旋转public virtual void constantRotation(float x, float y, float z) {nowRotationSpeed.x = x;nowRotationSpeed.y = y;nowRotationSpeed.z = z;constantRotationEvent(camera, new Vector3(x, y, z));}public virtual void constantRotation(Vector3 speed) {nowRotationSpeed = speed;constantRotationEvent(camera, speed);}protected virtual void constantRotationEvent(Camera cam, Vector3 speed) {}// 变速旋转public virtual void changeRotation(float x, float y, float z) {addRotationSpeed.x = x;addRotationSpeed.y = y;addRotationSpeed.z = z;changeRotationEvent(camera, new Vector3(x, y, z));}public virtual void changeRotation(Vector3 speed) {addSpeed = speed;changeRotationEvent(camera, speed);}protected virtual void changeRotationEvent(Camera cam, Vector3 speed) {}void Update () {camera.transform.rotation = Quaternion.Slerp(camera.transform.rotation, Quaternion.Euler(nowRotationSpeed + camera.transform.eulerAngles), Time.deltaTime);nowRotationSpeed += addRotationSpeed * Time.deltaTime;}

跟随目标

只需要每帧的时候,跟踪这个目标即可。

using UnityEngine;
using System.Collections;/* ********************************************************** 跟踪目标时,无法进行独立的移动,需要先取消跟踪(endFlowTra)* * * *********************************************************/
[RequireComponent(typeof(Camera))]
public class CameraControl : MonoBehaviour {protected Camera camera;Transform tra; // 跟踪目标Vector3 traPos; // 距离跟踪目标的距离void Awake() {camera = this.GetComponent<Camera>();tra = null;traPos = Vector3.zero;}// 开始跟踪目标public virtual void startFlowTra(Transform t, Vector3 pos) {tra = t;traPos = pos;startFlowTraEvent(camera, t, pos);}protected virtual void startFlowTraEvent(Camera cam, Transform t, Vector3 pos) {}// 结束跟踪目标public virtual void endFlowTra() {endFlowTraEvent(camera, tra, traPos);tra = null;traPos = Vector3.zero;}protected virtual void endFlowTraEvent(Camera cam, Transform t, Vector3 pos) {}void Update () {if (tra != null) {camera.transform.position = check(tra.position + traPos);}}

根据路径进行移动

我们只需要创建路径队列即可进行移动。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;/* ********************************************************** 跟踪目标时,无法进行独立的移动,需要先取消跟踪(endFlowTra)* * * *********************************************************/
[RequireComponent(typeof(Camera))]
public class CameraControl : MonoBehaviour {protected Camera camera;// 路径队列Queue<Vector3> path;float pathTime; // 每个点所需时间Vector3 nowPathPos;void Awake() {camera = this.GetComponent<Camera>();path = new Queue<Vector3>();}// 开始根据路径移动(传入一系列的点)public virtual void startFlowPath(float time, params Vector3[] pos) {this.nowSpeed = Vector3.zero;this.addSpeed = Vector3.zero;pathTime = time;path = new Queue<Vector3>(pos);path.Enqueue(pos[pos.Length - 1]);nowPathPos = path.Dequeue(); // 将终点加入二次,作为终点标记}// 结束根据路径移动public virtual void endFlowPath() {this.nowSpeed = Vector3.zero;this.addSpeed = Vector3.zero;path = new Queue<Vector3>();}void Update () {if (path.Count != 0) {float dis = Vector3.Distance(nowPathPos, camera.transform.position);if (dis <= 0.1f) { // 已经接近camera.transform.position = nowPathPos;nowPathPos = path.Dequeue();if (path.Count == 0) { // 如果是最后一个点,则将速度变为0nowSpeed = Vector3.zero;addSpeed = Vector3.zero;}} else {// 进行平滑移动camera.transform.position = Vector3.SmoothDamp(camera.transform.position, nowPathPos, ref nowSpeed, pathTime);}}}

总结

可以使用这个进行一系列的镜头操作,比如拉伸,移动,追随,镜头剧情等,还可以根据自己的需求进行扩展

using UnityEngine;
using System.Collections;
using System.Collections.Generic;/* ********************************************************** 跟踪目标时,无法进行独立的移动,需要先取消跟踪(endFlowTra)* 一般只需要继承protected函数即可,不推荐继承public函数* 这里将protected函定为二级函数,public函定义为一级函数(一级调用二级)* *********************************************************/
[RequireComponent(typeof(Camera))]
public class CameraControl : MonoBehaviour {protected Camera camera;// 最大最小宽度public float minX = -100.0f;public float maxX = 100.0f;// 最大最小高度public float minY = -50.0f;public float maxY = 50.0f;// 最大最小深度public float minZ = -100.0f;public float maxZ = 100.0f;// 当前速度Vector3 nowSpeed;// 加速度Vector3 addSpeed;// 当前旋转速度Vector3 nowRotationSpeed;// 旋转加速度Vector3 addRotationSpeed;Transform tra; // 跟踪目标Vector3 traPos; // 距离跟踪目标的距离// 路径队列Queue<Vector3> path;float pathTime; // 每个点所需时间Vector3 nowPathPos;void Awake() {camera = this.GetComponent<Camera>();addSpeed = Vector3.zero;nowSpeed = Vector3.zero;addRotationSpeed = Vector3.zero;nowRotationSpeed = Vector3.zero;tra = null;traPos = Vector3.zero;path = new Queue<Vector3>();nowPathPos = Vector3.zero;}void Start() {startFlowPath(1.0f, new Vector3(1, 1, 1), new Vector3(-1, -1, -1));}// 简单移动(瞬移)public virtual void simpleMove(float x, float y, float z) {camera.transform.position = check(x, y, z);simpleMoveEvent(camera, new Vector3(x, y, z));}public virtual void simpleMove(Vector3 pos) {camera.transform.position = check(pos);simpleMoveEvent(camera, pos);}protected virtual void simpleMoveEvent(Camera cam, Vector3 pos) {}// 匀速移动public virtual void constantMove(float x, float y, float z) {nowSpeed.x = x;nowSpeed.y = y;nowSpeed.z = z;constantMoveEvent(camera, new Vector3(x, y, z));}public virtual void constantMove(Vector3 speed) {nowSpeed = speed;constantMoveEvent(camera, speed);}protected virtual void constantMoveEvent(Camera cam, Vector3 speed) {}// 变速移动public virtual void changeMove(float x, float y, float z) {addSpeed.x = x;addSpeed.y = y;addSpeed.z = z;changeMoveEvent(camera, new Vector3(x, y, z));}public virtual void changeMove(Vector3 speed) {addSpeed = speed;changeMoveEvent(camera, speed);}protected virtual void changeMoveEvent(Camera cam, Vector3 speed) {}// 简单旋转(瞬间)public virtual void simpleRotation(float x, float y, float z) {camera.transform.rotation = Quaternion.Euler(x, y, z);simpleRotationEvent(camera, new Vector3(x, y, z));}public virtual void simpleRotation(Vector3 pos) {camera.transform.rotation = Quaternion.Euler(pos);simpleRotationEvent(camera, pos);}protected virtual void simpleRotationEvent(Camera cam, Vector3 pos) {}// 匀速旋转public virtual void constantRotation(float x, float y, float z) {nowRotationSpeed.x = x;nowRotationSpeed.y = y;nowRotationSpeed.z = z;constantRotationEvent(camera, new Vector3(x, y, z));}public virtual void constantRotation(Vector3 speed) {nowRotationSpeed = speed;constantRotationEvent(camera, speed);}protected virtual void constantRotationEvent(Camera cam, Vector3 speed) {}// 变速旋转public virtual void changeRotation(float x, float y, float z) {addRotationSpeed.x = x;addRotationSpeed.y = y;addRotationSpeed.z = z;changeRotationEvent(camera, new Vector3(x, y, z));}public virtual void changeRotation(Vector3 speed) {addSpeed = speed;changeRotationEvent(camera, speed);}protected virtual void changeRotationEvent(Camera cam, Vector3 speed) {}// 开始跟踪目标public virtual void startFlowTra(Transform t, Vector3 pos) {tra = t;traPos = pos;startFlowTraEvent(camera, t, pos);}protected virtual void startFlowTraEvent(Camera cam, Transform t, Vector3 pos) {}// 结束跟踪目标public virtual void endFlowTra() {endFlowTraEvent(camera, tra, traPos);tra = null;traPos = Vector3.zero;}protected virtual void endFlowTraEvent(Camera cam, Transform t, Vector3 pos) {}// 开始根据路径移动(传入一系列的点)public virtual void startFlowPath(float time, params Vector3[] pos) {this.nowSpeed = Vector3.zero;this.addSpeed = Vector3.zero;pathTime = time;path = new Queue<Vector3>(pos);path.Enqueue(pos[pos.Length - 1]);nowPathPos = path.Dequeue(); // 将终点加入二次,作为终点标记}// 结束根据路径移动public virtual void endFlowPath() {this.nowSpeed = Vector3.zero;this.addSpeed = Vector3.zero;path = new Queue<Vector3>();}void Update () {if (tra != null){camera.transform.position = check(tra.position + traPos);} else if (path.Count != 0) {float dis = Vector3.Distance(nowPathPos, camera.transform.position);if (dis <= 0.1f) { // 已经接近camera.transform.position = nowPathPos;nowPathPos = path.Dequeue();if (path.Count == 0) { // 如果是最后一个点,则将速度变为0nowSpeed = Vector3.zero;addSpeed = Vector3.zero;}} else {// 进行平滑移动camera.transform.position = Vector3.SmoothDamp(camera.transform.position, nowPathPos, ref nowSpeed, pathTime);}} else {Vector3 pos = camera.transform.position;pos += nowSpeed * Time.deltaTime;nowSpeed += addSpeed * Time.deltaTime;camera.transform.position = check(pos);camera.transform.rotation = Quaternion.Slerp(camera.transform.rotation, Quaternion.Euler(nowRotationSpeed + camera.transform.eulerAngles), Time.deltaTime);nowRotationSpeed += addRotationSpeed * Time.deltaTime;}}/* **************** 工具类函数* 范围:public(公共)* * ***************/// 检测坐标是否超出范围,并强制移动到范围内public Vector3 check(Vector3 p) {Vector3 pos = new Vector3(p.x, p.y, p.z);pos.x = Mathf.Max(pos.x, minX);pos.x = Mathf.Min(pos.x, maxX);pos.y = Mathf.Max(pos.y, minY);pos.y = Mathf.Min(pos.y, maxY);pos.z = Mathf.Max(pos.z, minZ);pos.z = Mathf.Min(pos.z, maxZ);return pos;}public Vector3 check(float x, float y, float z) {x = Mathf.Max(x, minX);x = Mathf.Min(x, maxX);y = Mathf.Max(y, minY);y = Mathf.Min(y, maxY);z = Mathf.Max(z, minZ);z = Mathf.Min(z, maxZ);return new Vector3(x, y, z);}
}

今天写得快,人形大宝宝可能看不到直播了- -

Unity手游制作记-制作通用镜头控制器相关推荐

  1. 基于cocos2dx的2D手游美术资源制作技术选型(1)(2)

     基于cocos2dx的2D手游美术资源制作技术选型(1)--UI.纹理格式.动画制作 - 宏波.王 一.在屏幕尺寸和分辨率变化不一的情况下,UI如何做机型适配? UI是应用的门户,相对来说IOS ...

  2. 【游戏开发实战】Unity手游第一人称视角,双摇杆控制,FPS射击游戏Demo(教程 | 含Demo工程源码)

    文章目录 一.前言 二.实现方案 1.无主之地,第一人称视角 2.我之前做的摇杆控制 3.第一人称视角 + 摇杆控制 三.开始实战 1.资源获取:Unity AssetStore 2.Low Poly ...

  3. Unity手游iOS内存分析和测试

    内存是Unity手游的硬伤,如果没有做好内存的相关管理和详细的测试,游戏极有可能出现卡顿.闪退等影响用户体验的现象.在此,笔者为我们介绍了一些Unity手游内存分析和测试过程中比较实用的测试场景案例. ...

  4. UWA发布 | Unity手游体检蓝皮书

    作为游戏行业的服务商,UWA不仅为游戏开发者提供高效的性能优化工具,也致力于为行业提供更全面.更具体的信息和服务.为此,UWA今天发布2017-2018年度手游蓝皮书,从总体性能数据.引擎各模块开销. ...

  5. 知物由学|游戏开发者如何从容应对Unity手游风险?

    本文由 网易云 发布 "知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会 ...

  6. Unity手游之路十自动寻路Navmesh之跳跃,攀爬,斜坡

    转载 Unity手游之路<十>自动寻路Navmesh之跳跃,攀爬,斜坡 分类: unity2013-12-27 00:50 6545人阅读 评论(5) 收藏 举报 unity3dNavme ...

  7. MMORPG的一份Unity手游性能蓝皮书

    https://mp.weixin.qq.com/s/iEs-1O3wTntaTrrCnOBn-A 这可能是针对MMORPG最全的一份Unity手游性能蓝皮书 2017-07-21 侑虎科技 游戏葡萄 ...

  8. Unity手游性能测评报告——MOBA篇

    MOBA移动游戏性能分析报告:渲染.UI和逻辑代码是性能头号杀手! UWA曾经发布过MMORPG 和 ARPG 的Unity手游性能测评报告,延续该系列,最近UWA对提交测试(登陆 www.uwa4d ...

  9. unity手游之聊天SDK集成与使用二

    unity手游之聊天SDK集成与使用二 集成思路 如果是自己的小游戏的话,可以把好友等信息直接保存在亲加服务器上,通过调用api来操作. 我们游戏只使用sdk的通信功能,好友等信息保存在自己的服务器上 ...

  10. unity手游之聊天SDK集成与使用一

    unity手游之聊天SDK集成与使用一 手游中都有聊天功能,比如公会,私聊,世界聊天,那么找一个好用,功能强大的SDK的可以节省很多精力,帮助我们提高开发速度与游戏质量. 写本篇博文是为了方便使用这个 ...

最新文章

  1. 普元王葱权:数字化时代需要新一代的大数据应用平台架构
  2. java dicom cmove_关于dcm4che DICOM Toolkit:C-Move与C-Get
  3. jboss 7 as1 日志配置
  4. 专访格灵深瞳CTO赵勇:为 计算机视觉 赋予智慧的光芒
  5. Netweaver的端口号和Spring boot内嵌的Tomcat端口
  6. html5 控制鼠标移动,HTML5 Canvas随鼠标移动的引力粒子群
  7. linux 一行代码,一行代码终结你的Linux~
  8. 一个分布式 JVM 监控工具,非常实用!
  9. 线性插值 多项式插值 样条插值 牛顿插值总结
  10. win10怎么更改照片分辨率和大小?图片dpi修改方法
  11. JAVA中关于if结构的相关的练习题
  12. 新浪新闻发布Z世代洞察报告:Z世代偏爱深入“吃瓜” 对元宇宙兴趣强烈
  13. 监听拼音输入法确定输入 ,compositionstart 、 compositionend 、 input都存在时的解决办法
  14. 自旋玻璃(spin glass)、自旋冰(spin ice)和量子自旋液体(quantum spin liquid)(之二)
  15. List,Set,Map集合总结
  16. torchtext常用函数整理
  17. 利用C语言实现文件的读写操作
  18. 计算机排序操作步骤,win7电脑更改磁盘卷标排列顺序的操作步骤-电脑自学网
  19. 网易游戏游戏开发工程师笔试试题
  20. c语言模板类,C++类模板(Class Template)

热门文章

  1. Redux的工作流程
  2. 软件架构-nginx详解上
  3. java经典题丨有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总对数为多少?
  4. 汉语计算机语言,从计算机编程语言说汉语的比较优势
  5. 使用python获取win10锁屏照片
  6. 基于 Python 的全国空气质量监测与可视化分析平台
  7. ps:消除锯齿和羽化
  8. 什么是长尾关键词?长尾关键词优化方法和技巧
  9. H5 编辑器 Tinymce之解决图片上传/粘贴
  10. 论文笔记:Deep Object Co-Segmentation(ACCV2018)