[游戏开发-学习笔记]菜鸟慢慢飞(四)-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 ...
随机推荐
- web标准之道——笔记
字体设置 sans和sans-serif为通用字体,具体哪个字体被最终应用由浏览器决定,通用字体只有在其他字体都无效时才会被当作代替方案.通用字体应该放在最后面 sans衬线字体 容易阅读,一般使用在 ...
- Encountered an unexpected error when attempting to resolve tag helper directive '@addTagHelper' with value '"*, Microsoft.AspNet.Mvc.TagHelpers"'
project.json 配置: { "version": "1.0.0-*", "compilationOptions": { " ...
- spring mvc DispatcherServlet详解之前传---FrameworkServlet
做项目时碰到Controller不能使用aop进行拦截,从网上搜索得知:使用spring mvc 启动了两个context:applicationContext 和WebapplicationCont ...
- 打造android偷懒神器———ListView的万能适配器
如果你去做任何一个项目,我相信你都会跟我有一样的经历,最最普遍的就是列表显示ListView,当然,写N个自定义的适配器也是情理之中.虽说程序员本身就是搬砖,做这些枯燥无味的重复的事情也是理所当然,但 ...
- 用SignalR 2.0开发客服系统[系列5:使用SignalR的中文简体语言包和其他技术点]
前言 交流群:195866844 目录: 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 用SignalR 2.0开发客服系统[系列2:实现聊天室] 用SignalR 2.0开发客服系统 ...
- winform程序一启动抛出异常--调用目标发生异常
在本机测试没有问题,可一到别的电脑上就抛出异常,这是最麻烦的事,一时间还找不出什么原因,本机上还无法重现. 现在好了,终于找到一个完美解决的办法,在Program.cs类中加入如下代码 static ...
- Sqlserver调用api
虽然使用sqlserver去调用服务接口的情况比较少,但也可以去了解下对应的使用情况 一.首先要开启组件的配置 sp_configure ; GO RECONFIGURE; GO sp_configu ...
- ubuntu Chromium 安装 pepperflashplugin
sudo apt-get update sudo apt-get install chromium-browser sudo apt-get install pepperflashplugin-non ...
- 【无私分享:ASP.NET CORE 项目实战(第十四章)】图形验证码的实现
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 很长时间没有来更新博客了,一是,最近有些忙,二是,Core也是一直在摸索中,其实已经完成了一个框架了,并且正在准备在生产环境中 ...
- JavaWeb_day07_JSP
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day07 JSP 全称 :Java Server P ...