1 简介

​ 相机用于渲染游戏对象,每个场景中可以有多个相机,每个相机独立成像,每个成像都是一个图层,最后渲染的图层在最前面显示。

​ 相机的属性面板如下:

  • Clear Flags:设置清屏颜色,Skybox(天空盒)、Solid Color(纯色)、Depth Only(仅深度,画中画效果)、Don't Clear(不渲染);
  • Background:清屏颜色,当 Clear Flags 为 Skybox 或 Solid Color 时,才有 Background;
  • Culling Mask:剔除遮蔽,选择相机需要绘制的对象层;
  • Projection:投影方式,Perspective(透视投影)、Orthographic(正交投影);
  • Field of View:相机视野范围,默认 60°,视野范围越大,能看到的物体越多,看到的物体越小;
  • Clipping Planes:裁剪平面,视锥体中近平面和远平面的位置;
  • Viewport Rect:视口在屏幕中的位置和大小(相对值),以屏幕左下角为原点;
  • Depth:渲染图层深度,用于设置相机渲染图层的显示顺序;
  • Rendering Path:渲染路径,用于调整渲染性能(可以在 Stats 里查看性能)
  • Target Texture:将相机画面存储到一个纹理图片(RenderTexture)中。

​ 补充:基于 Target Texture 属性,可以使用 RawImage 显示次相机渲染的 RenderTexture,实现带主题边框的小地图、八倍镜等效果。

2 应用

​ 本节将通过实现小地图案例展示相机的应用。

1)游戏界面

2)游戏对象层级结构

3)Transform 组件参数

​ 1. 相机 Transform 组件参数

Name Type Position Rotation Scale Viewport Rect
Main Camera Camera (0, 4, -5) (38, 0, 0) (1, 1, 1) (0, 0, 1, 1)
MinimapCamera Camera (0, 12, 0) (90, 0, 0) (1, 1, 1) (0.8, 0.7, 0.2, 0.3)

​ 2. 玩家 Transform 组件参数

Name Type Position Rotation Scale Color/Texture
Player Empty (0, 0.25, -5) (0, 0, 0) (1, 1, 1) #228439FF
Botton Cube (0, 0, 0) (0, 0, 0) (2, 0.5, 2) #228439FF
Top Cube (0, 0.5, 0) (0, 0, 0) (1, 0.5, 1) #228439FF
Gun Cylinder (0, 0, 1.5) (90, 0, 0) (0.2, 1, 0.4) #228439FF
FirePoint Empty (0, 1.15, 0) (0, 0, 0) (1, 1, 1) ——

​ 补充:Player 游戏对象添加了刚体组件。

​ 3. 敌人 Transform 组件参数

Name Type Position Rotation Scale Color/Texture
Enemy1 Empty (7, 0.25, 1) (0, 120, 0) (1, 1, 1) #F83333FF
Enemy2 Enemy (-1, 0.25, 5) (0, 60, 0) (1, 1, 1) #EA9132FF
Enemy3 Enemy (-5, 0.25, -1) (0, -40, 0) (1, 1, 1) #5DC2F4FF

​ 说明:Enemy1~Enemy3 都是由 Player copy 而来。

​ 4. 地面和炮弹 Transform 组件参数

Name Type Position Rotation Scale Color/Texture
Plane Plane (0, 0, 0) (0, 0, 0) (10, 10, 10) GrassRockyAlbedo
Bullet Sphere (0, 0.5, -5) (0, 0, 0) (0.3, 0.3, 0.3) #228439FF

​ 补充:炮弹作为预设体拖拽到 Assets/Resources/Prefabs 目录下,并且添加了刚体组件。

4)脚本组件

​ MainCameraController.cs

using UnityEngine;

public class MainCameraController : MonoBehaviour {
private Transform player; // 玩家
private Vector3 relaPlayerPos; // 相机在玩家坐标系中的位置
private float targetDistance = 15f; // 相机看向玩家前方的位置 private void Start() {
relaPlayerPos = new Vector3(0, 4, -8);
player = GameObject.Find("Player/Top").transform;
} private void LateUpdate() {
CompCameraPos();
} private void CompCameraPos() { // 计算相机坐标
Vector3 target = player.position + player.forward * targetDistance;
transform.position = transformVecter(relaPlayerPos, player.position, player.right, player.up, player.forward);
transform.rotation = Quaternion.LookRotation(target - transform.position);
} // 求以origin为原点, locX, locY, locZ 为坐标轴的本地坐标系中的向量 vec 在世界坐标系中对应的向量
private Vector3 transformVecter(Vector3 vec, Vector3 origin, Vector3 locX, Vector3 locY, Vector3 locZ) {
return vec.x * locX + vec.y * locY + vec.z * locZ + origin;
}
}

​ 说明: CameraController 脚本组件挂在 MainCamera 游戏对象上。

​ MinmapCameraController.cs

using UnityEngine;

public class MinimapController : MonoBehaviour {
private Transform player; // 玩家
private float height = 12; // 相机离地面的高度
private bool isFullscreen = false; // 小地图相机是否全屏
private Rect minViewport; // 小地图视口位置和大小(相对值)
private Rect FullViewport; // 全屏时视口位置和大小(相对值) private void Start() {
player = GameObject.Find("Player/Top").transform;
minViewport = GetComponent<Camera>().rect;
FullViewport = new Rect(0, 0, 1, 1);
} private void Update() {
if (Input.GetMouseButtonDown(0) && IsClickMinimap()) {
if (isFullscreen) {
GetComponent<Camera>().rect = minViewport;
} else {
GetComponent<Camera>().rect = FullViewport;
}
isFullscreen = !isFullscreen;
}
} private void LateUpdate() {
Vector3 pos = player.position;
transform.position = new Vector3(pos.x, height, pos.z);
} public bool IsClickMinimap() { // 是否单击到小地图区域
Vector3 pos = Input.mousePosition;
if (isFullscreen) {
return true;
}
if (pos.x / Screen.width > minViewport.xMin && pos.y / Screen.height > minViewport.yMin) {
return true;
}
return false;
}
}

​ 说明: MinimapController 脚本组件挂在 MinimapCamera 游戏对象上。

​ PlayerController.cs

using UnityEngine;

public class PlayerController : MonoBehaviour {
private MinimapController minimapController; // 小地图控制器
private Transform firePoint; // 开火点
private GameObject bulletPrefab; // 炮弹预设体
private float tankMoveSpeed = 4f; // 坦克移动速度
private float tankRotateSpeed = 2f; // 坦克转向速度
private Vector3 predownMousePoint; // 鼠标按下时的位置
private Vector3 currMousePoint; // 当前鼠标位置
private float fireWaitTime = float.MaxValue; // 距离上次开火已等待的时间
private float bulletCoolTime = 0.15f; // 炮弹冷却时间 private void Start() {
minimapController = GameObject.Find("MinimapCamera").GetComponent<MinimapController>();
firePoint = transform.Find("Top/Gun/FirePoint");
bulletPrefab = (GameObject) Resources.Load("Prefabs/Bullet");
} private void Update() {
Move();
Rotate();
Fire();
} private void Move() { // 坦克移动
float hor = Input.GetAxis("Horizontal");
float ver = Input.GetAxis("Vertical");
if (Mathf.Abs(hor) > float.Epsilon || Mathf.Abs(ver) > float.Epsilon) {
Vector3 vec = transform.forward * ver + transform.right * hor;
GetComponent<Rigidbody>().velocity = vec * tankMoveSpeed;
Vector3 dire = new Vector3(hor, ver, 0);
dire = dire.normalized * Mathf.Min(dire.magnitude, 1);
}
} private void Rotate() { // 坦克旋转
if (Input.GetMouseButtonDown(1)) {
predownMousePoint = Input.mousePosition;
} else if (Input.GetMouseButton(1)) {
currMousePoint = Input.mousePosition;
Vector3 vec = currMousePoint - predownMousePoint;
GetComponent<Rigidbody>().angularVelocity = Vector3.up * tankRotateSpeed * vec.x;
predownMousePoint = currMousePoint;
}
} private void Fire() { // 坦克开炮
fireWaitTime += Time.deltaTime;
if (Input.GetMouseButtonDown(0) && !minimapController.IsClickMinimap() || Input.GetKeyDown(KeyCode.Space)) {
if (fireWaitTime > bulletCoolTime) {
BulletInfo bulletInfo = new BulletInfo("PlayerBullet", Color.red, transform.forward, 10f, 15f);
GameObject bullet = Instantiate(bulletPrefab, firePoint.position, Quaternion.identity);
bullet.AddComponent<BulletController>().SetBulletInfo(bulletInfo);
fireWaitTime = 0f;
}
}
}
}

​ 说明: PlayerController 脚本组件挂在 Player 游戏对象上。

​ BulletController.cs

using UnityEngine;
using UnityEngine.UI; public class BulletController : MonoBehaviour {
private BulletInfo bulletInfo; // 炮弹信息 private void Start () {
gameObject.name = bulletInfo.name;
GetComponent<MeshRenderer>().material.color = bulletInfo.color;
float lifeTime = bulletInfo.fireRange / bulletInfo.speed; // 存活时间
Destroy(gameObject, lifeTime);
} private void Update () {
transform.GetComponent<Rigidbody>().velocity = bulletInfo.flyDir * bulletInfo.speed;
} public void SetBulletInfo(BulletInfo bulletInfo) {
this.bulletInfo = bulletInfo;
}
}

​ 说明:BulletController 脚本组件挂在 Bullet 游戏对象上(代码里动态添加)。

​ BulletInfo.cs

using UnityEngine;

public class BulletInfo {
public string name; // 炮弹名
public Color color; // 炮弹颜色
public Vector3 flyDir; // 炮弹飞出方向
public float speed; // 炮弹飞行速度
public float fireRange; // 炮弹射程 public BulletInfo(string name, Color color, Vector3 flyDir, float speed, float fireRange) {
this.name = name;
this.color = color;
this.flyDir = flyDir;
this.speed = speed;
this.fireRange = fireRange;
}
}

5)运行效果

​ 声明:本文转自【Unity3D】相机

【Unity3D】相机的更多相关文章

  1. Unity3D 相机跟随主角移动

    这里给主相机绑定一个脚本. 脚本写为: using UnityEngine; using System.Collections; public class camerafollow : MonoBeh ...

  2. Unity3D相机震动效果

    在一些格斗.射击以及动作类游戏中 相机震动效果是十分重要的 一个平凡的镜头 在关键时刻加入相机震动后 便可以展现出碰撞.危险.打斗以及激动人心的效果 相机震动的实现方式有很多 但都会涉及摄像机位置的变 ...

  3. Unity3D——相机跟随物体移动

    public Transform target; public float moveSmooth=5f; Vector3 offset; void Start () { offset = transf ...

  4. [原]unity3D 相机跟随

    using UnityEngine;using System.Collections; public class CameraFollow : MonoBehaviour {            p ...

  5. [Unity3D]Unity资料大全免费分享

     都是网上找的连七八糟的资料了,整理好分享的,有学习资料,视频,源码,插件……等等 东西比较多,不是所有的都是你需要的,可以按  ctrl+F 来搜索你要的东西,如果有广告,不用理会,关掉就可以了,如 ...

  6. 分享一个大神自己的blog

    std::sort() 详解 http://feihu.me/blog/ C++11 新特性 http://blog.guoyb.com/2016/09/19/cpp11-all/ unity3d 相 ...

  7. Unity3d学习 相机的跟随

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

  8. [Unity3D]深度相机 Depth Camera

    作为3D世界里最重要的窗口,摄像机的应用就显得很重要,毕竟在屏幕上看到的一切都得用摄像机矩阵变换得来的嘛.论坛上看到了一篇帖子讲非天空盒的背景做法,让我想起其实很多界面合成画面可以用摄像机之间的交互来 ...

  9. unity3d 第三人称视角的人物移动以及相机控制

    何谓第三人称?就像这样: 用wasd控制人物移动,同时保持在相机的中心.用鼠标右键与滚轮控制相机的角度和距离. 先说一下人物的移动: 首先给作为主角的单位加上 Charactor Controller ...

  10. unity3d设置3D模型显示在2D背景之前(多个相机分层显示)(转)

    解决步骤: 1.添加一个摄像机,命名为BackgroundCamera,然后在Layer添加一个background层.并且将plane拖放到改相机节点下. 然后将BackgroundCamera和P ...

随机推荐

  1. Linux性能分析——TOP命令详解

    Linux性能分析--TOP命令详解 1.Top命令介绍 Linux系统中,Top命令主要用于实时运行系统的监控,包括Linux内核管理的进程或者线程的资源占用情况. 这个命令对所有正在运行的进程和系 ...

  2. [转帖]shell编程之条件语句

    目录 一.条件测试 test命令 文件测试与整数测试 文件测试 整数值比较 字符串测试与逻辑测试 字符串比较 逻辑测试 二.if语句 if单分支语句 单分支结构 if双分支语句 双分支结构 if多分支 ...

  3. [转帖]Linux搭建Nexus仓库+高可用方案

    https://www.cnblogs.com/yangjianan/p/9090348.html Linux搭建nexus仓库 1.安装jdk 1.1 获取安装包,解压到指定目录: 1 tar xf ...

  4. [转帖] JVM诊断命令jcmd介绍

    https://www.cnblogs.com/codelogs/p/16535451.html 简介# 从JDK7开始,jdk提供了一个方便扩展的诊断命令jcmd,用来取代之前比较分散的jdk基础命 ...

  5. 【转帖】Linux 调优篇:虚拟化调优(hugepage 大页内存)* 叁

    一. 大页(HugePages)概念Hugepage的引入二. hugepages相关概念三.Regular Pages 与 HugePagesa.Regular Pagesb.Huge Pages四 ...

  6. [转帖]如何通过shell脚本对一个文件中的所有数值相加并求和

    https://developer.aliyun.com/article/886170?spm=a2c6h.24874632.expert-profile.255.7c46cfe9h5DxWK 1.背 ...

  7. echarts饼图中央自定义文字

    var option = { tooltip: { trigger: 'item' }, legend: { top: '5%', left: 'center' }, //中央自定义文字 title: ...

  8. uni-app 计算属性 computed

    功能:=>大于1000用kg表示 小于1000,用g表示 计算属性 计算属性必须是有一个返回值的哦 在html写被计算的值 在computed中去直接调用哈 <view> <t ...

  9. 玩一玩 golang 1.21 的 pgo 编译优化

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 1.下载镜像 暂时不想替换本机的 golang 版本,于是 ...

  10. String 中的Trim

    Trim 切除首尾指定字符 var newStr=""; char[] trimChars={'@','#','$',' '}; string strC="@Hello# ...