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

本节将通过实现小地图案例展示相机的应用。
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
().rect; - FullViewport = new Rect(0, 0, 1, 1);
- }
-
- private void Update() {
- if (Input.GetMouseButtonDown(0) && IsClickMinimap()) {
- if (isFullscreen) {
- GetComponent
().rect = minViewport; - } else {
- GetComponent
().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
(); - 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
().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
().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
().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
().material.color = bulletInfo.color; - float lifeTime = bulletInfo.fireRange / bulletInfo.speed; // 存活时间
- Destroy(gameObject, lifeTime);
- }
-
- private void Update () {
- transform.GetComponent
().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)运行效果
