|
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 组件参数
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) |
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 游戏对象添加了刚体组件。
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 而来。
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】相机 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|