Unity 2D游戏开发教程之摄像头追踪功能

冷暖自知 提交于 2019-12-10 07:27:45

Unity 2D游戏开发教程之摄像头追踪功能

上一章,我们创建了一个简单的2D游戏。此游戏中的精灵有3个状态:idleleftright。这看起来确实很酷!但是仅有的3个状态却限制了精灵的能力,以及游戏逻辑的想象空间。看来有必要让精灵拥有更多的状态,而这就是本章要讲解的主要内容。

摄像头追踪功能

游戏里的精灵可以在游戏场景中任意移动,这没什么问题,可是这就导致了一个问题,就是精灵可能移动到我们的视野之外,或者说游戏视图之外。为了解决这个问题,很多游戏都采用了“摄像头追踪”的方法,使得摄像头的位置会随着精灵的移动而移动。例如,《超级玛丽》中,精灵始终处于视图中心的位置,如图2-1所示。

2-1  《超级玛丽》中,精灵始终位于游戏视图的中心

要为我们开发的游戏添加“摄像头追踪”的功能,就需要使用脚本编写这样一种逻辑。在Project视图的Scripts文件夹里,新建一个C#脚本,命名为CameraController,为此脚本添加下面的代码:

  • 01     using UnityEngine;

  • 02     using System.Collections;

  • 03    

  • 04     public class CameraController : MonoBehaviour

  • 05     {

  • 06              //公有属性

  • 07              //表示精灵当前的动画状态

  • 08              public PlayerStateController.playerStates currentPlayerState = PlayerStateController.playerStates.idle;

  • 09              public GameObject playerObject = null;                                //表示精灵对象

  • 10              public float cameraTrackingSpeed = 1f;                               //表示摄像机的追踪速度

  • 11              //私有属性

  • 12              private Vector3 lastTargetPosition = Vector3.zero;             //上一目标位置

  • 13              private Vector3 currTargetPosition = Vector3.zero;             //下一目标位置

  • 14              private float currLerpDistance = 0.0f;

  • 15              //方法

  • 16              void Start()

  • 17              {

  • 18                       Vector3 playerPos = playerObject.transform.position;                //记录精灵的位置

  • 19                       Vector3 cameraPos = transform.position;                                               //记录摄像机的位置

  • 20                       Vector3 startTargPos = playerPos;

  • 21                       lastTargetPosition = startTargPos;

  • 22                       currTargetPosition = startTargPos;

  • 23              }

  • 24              //加入订阅者列表

  • 25              void OnEnable()

  • 26              {

  • 27                       PlayerStateController.onStateChange += onPlayerStateChange;

  • 28              }

  • 29              //从订阅者列表中退出

  • 30              void OnDisable()

  • 31              {

  • 32                       PlayerStateController.onStateChange -= onPlayerStateChange;

  • 33              }

  • 34              //实时记录游戏精灵当前的动画状态

  • 35              void onPlayerStateChange(PlayerStateController.playerStates newState)

  • 36              {

  • 37                       currentPlayerState = newState;

  • 38              }

  • 39              void LateUpdate()

  • 40              {

  • 41                       //依据当前精灵的动画状态,实时更新

  • 42                       onStateCycle();

  • 43                       //将摄像头移动到目标位置

  • 44                       currLerpDistance += cameraTrackingSpeed;

  • 45                       transform.position = Vector3.Lerp(lastTargetPosition, currTargetPosition, currLerpDistance);

  • 46              }

  • 47              void onStateCycle()

  • 48              {

  • 49                       switch(currentPlayerState)

  • 50                       {

  • 51                                 case PlayerStateController.playerStates.idle:

  • 52                                          trackPlayer();

  • 53                                break;

  • 54                                 case PlayerStateController.playerStates.left:

  • 55                                          trackPlayer();

  • 56                                 break;

  • 57                                 case PlayerStateController.playerStates.right:

  • 58                                          trackPlayer();

  • 59                                 break;

  • 60                       }

  • 61              }

  • 62              void trackPlayer()

  • 63              {

  • 64                       //获取并保存摄像机和精灵在世界坐标系的坐标

  • 65                        Vector3 currCamPos = transform.position;       

  • 66                       Vector3 currPlayerPos = playerObject.transform.position;

  • 67                       lastTargetPosition = currCamPos;

  • 68                       currTargetPosition = currPlayerPos;

  • 69                       currTargetPosition.z = currCamPos.z;                          //保证摄像头z轴方向上的值不变

  • 70              }

  • 71     }

将此脚本赋予Hierarchy视图里的Main Camera对象,选中后者,然后在Inspector视图里设置此脚本组件的下列属性,如图2-2所示。

  • q   Player ObjectPlayer。表示摄像头要追踪的精灵对象;

  • q   Camera Tracking Speed1。此属性值范围是0~1,若为0时,摄像头不会追踪精灵,若为1时,摄像头可以在瞬间追踪到精灵对象;

2-2  Main Camera对象的脚本组件上各属性的设置

对于此脚本有以下几点需要说明:

  • q   脚本69行的代码使得摄像头与精灵对象不至于重合。要让摄像头实时追踪游戏精灵,只要实时更新摄像头的位置即可。就是要让它的位置与精灵的位置一致,但是它们在Z轴方向上的值不能相同,如图2-3所示。否则摄像头与精灵会发生重合,使得游戏视图里精灵对象消失,如图2-4所示。

2-3  摄像头与精灵在Z方向上的值不同

2-4  摄像头与精灵在Z方向上的值相同

  • q   脚本45行的Vector3.Lerp()函数,是完成摄像头实时追踪功能的主要函数。这个函数会将一个对象,以一定的速度从一个位置移动到另一个位置;

运行游戏,然后使用键盘上的方向键控制精灵左右移动,你会发现游戏视图会和精灵一同移动,甚至是精灵因为脱离地面发生坠落时,也不例外,如图2-5所示。

2-5  摄像头追踪功能,精灵始终位于游戏视图的中心

本文选自:Unity 2D游戏开发快速入门大学霸内部资料,转载请注明出处,尊重技术尊重IT人!


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!