[游戏开发-学习笔记]菜鸟慢慢飞(四)-Camera
游戏开发中,主相机应该是最重要的GameObject之一,毕竟游戏呈现给玩家,就是通过它。
相机的使用,在不同的游戏中,有很大的不同。这里总结一下自己学到的一些相关知识。
固定位置-游戏过程中相机的Transform属性不改变。
- 调整好位置后就不要动了,一般使用正交相机,即Camera-Projection选择Orthographic。Unity Manual-Camera
适用:2D游戏。比如飞机大战,消消乐。 - 游戏开始后,相机追踪某一物体,然后固定不动。
游戏开始后,我们才能确定追踪物体的位置,先看代码:
- using UnityEngine;
- 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;
- }
- }
适用:固定视角的3D游戏。
3D视角-围绕一个中心随意旋转
先看代码:
- using UnityEngine;
- public class CameraContorller : MonoBehaviour
- {
- /// <summary>
- /// 追踪目标
- /// </summary>
- public Transform target;
- /// <summary>
- /// 旋转速度
- /// </summary>
- public float xSpeed = , ySpeed = ;
- /// <summary>
- /// 缩放速度
- /// </summary>
- public float mSpeed = ;
- /// <summary>
- /// 最小/最大限制角度
- /// </summary>
- public float yMinLimit = -, yMaxLimit = ;
- /// <summary>
- /// 是否使用插值运算
- /// </summary>
- public bool needDamping = true;
- /// <summary>
- /// 速度
- /// </summary>
- public float damping = 5.0f;
- /// <summary>
- /// 观察距离
- /// </summary>
- private float distance = ;
- /// <summary>
- /// 最小/最大观察距离
- /// </summary>
- private float minDistance = , maxDistance = ;
- /// <summary>
- /// 旋转角度
- /// </summary>
- private float x = 0.0f, y = 0.0f;
- void Start()
- {
- Vector3 angles = transform.eulerAngles;
- x = angles.y;
- y = angles.x;
- //根据相机的初始位置初始化距离,最大距离,最小距离;
- Vector3 offset = transform.position - target.position;
- distance = offset.magnitude;
- minDistance = distance / ;
- maxDistance = distance * ;
- }
- void LateUpdate()
- {
- if (target)
- {
- if (Input.GetMouseButton())//0-左键,1-右键,2-中键
- {
- x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
- y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
- y = ClampAngle(y, yMinLimit, yMaxLimit);
- }
- distance -= Input.GetAxis("Mouse ScrollWheel") * mSpeed;
- distance = Mathf.Clamp(distance, minDistance, maxDistance);
- Quaternion rotation = Quaternion.Euler(y, x, 0.0f);
- Vector3 disVector = new Vector3(0.0f, 0.0f, -distance);
- Vector3 position = rotation * disVector + target.position;
- if (needDamping)
- {
- transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * damping);
- Vector3 transformTemp = Vector3.Lerp(transform.position, position, Time.deltaTime * damping);
- if (transformTemp.y <= )//如果相机位置在“水平面”以下,强制设置到水平面。
- {
- transform.position = new Vector3(transformTemp.x, , transformTemp.z);
- }
- else
- {
- transform.position = transformTemp;
- }
- }
- else
- {
- transform.rotation = rotation;
- if (position.y <= )//如果相机位置在“水平面”以下,强制设置到水平面。
- {
- transform.position = new Vector3(position.x, , position.z);
- }
- else
- {
- transform.position = position;
- }
- }
- }
- }
- static float ClampAngle(float angle, float min, float max)
- {
- if (angle < -)
- angle += ;
- if (angle > )
- angle -= ;
- return Mathf.Clamp(angle, min, max);
- }
- }
大部分3D游戏中,我这样理解:主角看作球心,球半径玩家可以自己改变,相机的位置就在“地面”以上的半球球体上。
上面这段代码基本做到了这个要求,并在相机到“地面”的时候有抬头看的效果。
代码有点问题,开始游戏后相机会跳动两次,暂时放到自己的问题清单中。
其他用法
官方教程Tanks tutorial 中有个不常见的用法。
不管两个Tank如何移动,相机通过前后缩放,大小缩放保证两个Tank肯定在相机视野内。
主要代码:(官方代码写得好啊)
- private void Move ()
- {
- // Find the average position of the targets.
- FindAveragePosition ();
- // Smoothly transition to that position.
- transform.position = Vector3.SmoothDamp(transform.position, m_DesiredPosition, ref m_MoveVelocity, m_DampTime);
- }
- private void FindAveragePosition ()
- {
- Vector3 averagePos = new Vector3 ();
- int numTargets = ;
- // Go through all the targets and add their positions together.
- for (int i = ; i < m_Targets.Length; i++)
- {
- // If the target isn't active, go on to the next one.
- if (!m_Targets[i].gameObject.activeSelf)
- continue;
- // Add to the average and increment the number of targets in the average.
- averagePos += m_Targets[i].position;
- numTargets++;
- }
- // If there are targets divide the sum of the positions by the number of them to find the average.
- if (numTargets > )
- averagePos /= numTargets;
- // Keep the same y value.
- averagePos.y = transform.position.y;
- // The desired position is the average position;
- m_DesiredPosition = averagePos;
- }
- private void Zoom ()
- {
- // Find the required size based on the desired position and smoothly transition to that size.
- float requiredSize = FindRequiredSize();
- m_Camera.orthographicSize = Mathf.SmoothDamp (m_Camera.orthographicSize, requiredSize, ref m_ZoomSpeed, m_DampTime);
- }
- private float FindRequiredSize ()
- {
- // Find the position the camera rig is moving towards in its local space.
- Vector3 desiredLocalPos = transform.InverseTransformPoint(m_DesiredPosition);
- // Start the camera's size calculation at zero.
- float size = 0f;
- // Go through all the targets...
- for (int i = ; i < m_Targets.Length; i++)
- {
- // ... and if they aren't active continue on to the next target.
- if (!m_Targets[i].gameObject.activeSelf)
- continue;
- // Otherwise, find the position of the target in the camera's local space.
- Vector3 targetLocalPos = transform.InverseTransformPoint(m_Targets[i].position);
- // Find the position of the target from the desired position of the camera's local space.
- Vector3 desiredPosToTarget = targetLocalPos - desiredLocalPos;
- // Choose the largest out of the current size and the distance of the tank 'up' or 'down' from the camera.
- size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.y));
- // Choose the largest out of the current size and the calculated size based on the tank being to the left or right of the camera.
- size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.x) / m_Camera.aspect);
- }
- // Add the edge buffer to the size.
- size += m_ScreenEdgeBuffer;
- // Make sure the camera's size isn't below the minimum.
- size = Mathf.Max (size, m_MinSize);
- return size;
- }
暂时放下的内容
Unity的相机相关:
- Screen Space Ambient Obscurance
- Bloom
- TiltShift
- VignetteAndChromaticAberration
- Color Correction Curves
[游戏开发-学习笔记]菜鸟慢慢飞(四)-Camera的更多相关文章
- [游戏开发-学习笔记]菜鸟慢慢飞(九)- NGUI- UIPanel(官方说明翻译)
我自己笔记是做在OneNote上,直接复制粘贴过来变成图片了,效果好像还可以. 机器翻译,我自己看了一下,改了一部分.
- [游戏开发-学习笔记]菜鸟慢慢飞(九)- NGUI- UIWidget(官方说明翻译)
- 【整理】HTML5游戏开发学习笔记(5)- 猜谜游戏
距上次学习笔记已有一个多月过去了,期间由于新项目赶进度,以致该学习计划给打断,十分惭愧.书本中的第六章的例子相对比较简单.所以很快就完成. 1.预备知识html5中video标签的熟悉 2.实现思路对 ...
- 【整理】HTML5游戏开发学习笔记(1)- 骰子游戏
<HTML5游戏开发>,该书出版于2011年,似乎有些老,可对于我这样没有开发过游戏的人来说,却比较有吸引力,选择自己感兴趣的方向来学习html5,css3,相信会事半功倍.不过值得注意的 ...
- cocos2d-x 3.x游戏开发学习笔记(1)--mac下配置cocos2d-x 3.x开发环境
打开用户文件夹下.bash_profile文件,配置环境 vim ~/.bash_profile //按键i,进行插入编辑(假设输错d进行删除一行) 环境配置过程例如以下: 1.首先配置下androi ...
- Photon + Unity3D 线上游戏开发 学习笔记(四)
这一节 我们建立 photon Server 端的框架 一个最简单的Photon框架 就包括一个 Applocation 类 和 一个 peer 类,作用例如以下: * Application 类是 ...
- [Android游戏开发学习笔记]View和SurfaceView
本文为阅读http://blog.csdn.net/xiaominghimi/article/details/6089594的笔记. 在Android游戏中充当主要角色的,除了控制类就是显示类.而在A ...
- Photon + Unity3D 线上游戏开发 学习笔记(一)
大家好. 我也是学习Photon + unity3D 的新手 有什么说错的地方大家见谅哈. 我的开发环境是 unity3D 4.1.3 , Visual Studio 是2010 版本号的 p ...
- 【Android开发学习笔记】【第四课】基础控件的学习
通过一个简单的例子来学习下面几种控件: 1.TextView:简单的文本显示控件 2.EditText:可以编辑的文本框 3.Button:按钮 4.Menu:这里指的是系统的Menu 5.Toast ...
随机推荐
- 微软Ignite大会我的Session(SQL Server 2014 升级面面谈)PPT分享
我在首届微软技术大会的Session分享了一个关于SQL Server升级的主题,现在将PPT分享出来. 您可以点击这里下载PPT. 也非常感谢微软中国邀请我进行这次分享.
- leetcode--5. Longest Palindromic Substring
题目来自 https://leetcode.com/problems/longest-palindromic-substring/ 题目:Given a string S, find the long ...
- Android线程管理之ThreadPoolExecutor自定义线程池
前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...
- 如何在删除ibdata1和ib_logfile的情况下恢复MySQL数据库
昨天,有个朋友对公司内部使用的一个MySQL实例开启binlog,但是在启动的过程中失败了(他也没提,为何会失败),在启动失败后,他删除了ibdata1和ib_logfile,后来,能正常启动了,但所 ...
- Memcache缓存系统构建一
在如今这个高效率的社会中,怎样将这个高效率应用到自己的程序中,是一个值得追寻和值得探讨的问题.因为这个memcache能够很好的提高检索速度,提升用户体验,而且重要的是减少数据库的访问.这就大大的提高 ...
- ActiveMQ消息队列的使用及应用
这里就不说怎么安装了,直接解压出来就行了. 谢绝转载,作者保留所有权力 目录: 一:JMQ的两种消息模式 1.1:点对点的消息模式 1.2:订阅模式 二:点对点的实现代码 2.1:点对点的发送端 2 ...
- 利用Python进行数据分析(9) pandas基础: 汇总统计和计算
pandas 对象拥有一些常用的数学和统计方法. 例如,sum() 方法,进行列小计: sum() 方法传入 axis=1 指定为横向汇总,即行小计: idxmax() 获取最大值对应的索 ...
- 实例讲解react+react-router+redux
前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应 ...
- A chatroom for all! Part 1 - Introduction to Node.js(转发)
项目组用到了 Node.js,发现下面这篇文章不错.转发一下.原文地址:<原文>. ------------------------------------------- A chatro ...
- Ubuntu下的解压缩
一. 命令: .tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz ...