上一章,咱们建立了一个简单的2D游戏。此游戏中的精灵有3个状态:idle、left和right。这看起来确实很酷!可是仅有的3个状态却限制了精灵的能力,以及游戏逻辑的想象空间。看来有必要让精灵拥有更多的状态,而这就是本章要讲解的主要内容。函数
游戏里的精灵能够在游戏场景中任意移动,这没什么问题,但是这就致使了一个问题,就是精灵可能移动到咱们的视野以外,或者说游戏视图以外。为了解决这个问题,不少游戏都采用了“摄像头追踪”的方法,使得摄像头的位置会随着精灵的移动而移动。例如,《超级玛丽》中,精灵始终处于视图中心的位置,如图2-1所示。动画
图2-1 《超级玛丽》中,精灵始终位于游戏视图的中心spa
要为咱们开发的游戏添加“摄像头追踪”的功能,就须要使用脚本编写这样一种逻辑。在Project视图的Scripts文件夹里,新建一个C#脚本,命名为CameraController,为此脚本添加下面的代码:orm
01 using UnityEngine;对象
02 using System.Collections;教程
03 游戏
04 public class CameraController : MonoBehaviourip
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 Object:Player。表示摄像头要追踪的精灵对象;
q Camera Tracking Speed:1。此属性值范围是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人!