如何编写Unity游戏测试“金手指”系统
在游戏制作过程中,我们常常需要反复测试一个或多个游戏场景。同时,把控整个游戏过程的速度也至关重要,因为为了达到理想的效果,开发人员往往需要不断从头试玩游戏关卡。为了解决这一问题,我们可以实现一组灵活的作弊子系统,也就是游戏测试中的“金手指”系统。
游戏作弊系统概述
游戏作弊是许多市面上的游戏都采用过的老方法。作弊系统能够帮助开发和测试人员更高效地测试游戏,不过在游戏最终发布时,该系统肯定会被移除,因为它会改变游戏的数值平衡。然而,移除已经实现的作弊系统可能会破坏整个产品的稳定性,因为这需要对部分代码进行修改。此外,还有一些被称为作弊码的手段,甚至可以在某些网站上直接激活。
通常情况下,在游戏帮助文档中很难找到游戏内作弊的方法,因为游戏开发者并不希望玩家进行作弊。但玩家可以在杂志或互联网上找到相关的作弊码。
实现游戏作弊子系统
下面我们将详细讲解如何实现一个适用于PC和移动平台的简单作弊系统,该系统的主要需求是无需键盘即可使用。为了方便实现,我们将触摸和鼠标事件进行统一处理,并创建任意类型的GUI。这里我们会使用虽然有些过时但仍然可用的IMGUI。
激活作弊码列表
为了让激活作弊码列表的流程更加简洁,我们设计了一个简单的规则:玩家需要在2秒之内点击或触摸屏幕右上角5次,即可激活作弊码列表。
以下是实现该功能的代码:
using UnityEngine;
using System.Collections;
using System;
public class Cheats : MonoBehaviour
{
// 激活区域大小占屏幕宽度的百分比
public float ActivateAreaSize = 0.1f;
// 在作弊列表可见之前玩家需要点击的次数
public int ClicksCount = 5;
// 玩家必须在多少秒内完成点击/触摸屏幕
public float WaitTime = 2;
private float[] _clickTimes;
private int _clickTimesIndex;
private bool _active = false;
void Start()
{
// 创建点击时间数组,并将其初始化为float.MinValue
_clickTimes = new float[ClicksCount];
ResetClicks();
}
private void ResetClicks()
{
for (int i = 0; i < ClicksCount; i++)
{
_clickTimes[i] = float.MinValue;
}
}
void Update()
{
// 检查是否有点击或触摸事件,并进行记录
if (CheckClickOrTouch())
{
// 记录点击时间(自关卡加载以来的时间)
_clickTimes[_clickTimesIndex] = Time.timeSinceLevelLoad;
// 下一次点击将记录在下一个数组索引位置,如果溢出则回到0
_clickTimesIndex = (_clickTimesIndex + 1) % ClicksCount;
}
// 检查是否应该激活作弊列表
if (ShouldActivate())
{
_active = true;
ResetClicks();
}
}
// 检查是否应该激活作弊列表
private bool ShouldActivate()
{
// 检查所有点击/触摸是否在指定时间内完成
foreach (float clickTime in _clickTimes)
{
if (clickTime < Time.timeSinceLevelLoad - WaitTime)
{
// 如果有任何点击/触摸时间超出指定时间,则返回false
return false;
}
}
// 如果所有点击都在指定时间内完成,则应该激活作弊
return true;
}
// 如果在激活区域内有点击或触摸,则返回true
private bool CheckClickOrTouch()
{
// 将激活区域大小转换为像素
float sizeInPixels = ActivateAreaSize * Screen.width;
// 获取点击/触摸的位置
Vector2? position = ClickOrTouchPoint();
if (position.HasValue) // 如果有点击或触摸事件
{
// 检查点击/触摸位置是否在有效范围内
if (position.Value.x >= Screen.width - sizeInPixels && Screen.height - position.Value.y <= sizeInPixels)
{
return true;
}
}
return false;
}
// 检查是否有点击或触摸事件,并返回屏幕上的像素位置
private Vector2? ClickOrTouchPoint()
{
if (Input.GetMouseButtonDown(0)) // 左键鼠标点击
{
return Input.mousePosition;
}
else if (Input.touchCount > 0) // 有一个或多个触摸事件
{
// 只检查第一个触摸事件
Touch touch = Input.touches[0];
// 仅在触摸刚刚开始时做出反应
if (touch.phase == TouchPhase.Began)
{
return touch.position;
}
}
// 如果没有点击或触摸事件,则返回null
return null;
}
void OnGUI()
{
if (_active)
{
// 在这里显示作弊列表...
}
}
}
上述代码虽然较长,但只是一个基本实现,其主要功能包括:
- 监听所有点击和触摸事件。
- 检测点击或触摸是否在有效的屏幕范围内。
- 检测最后5次点击是否在指定时间内完成。
该系统还是可配置的,我们可以在OnGUI函数内加入绘制GUI以及激活作弊码的代码:
void OnGUI()
{
if (_active)
{
DisplayCheat("Close Cheat Menu", () => _active = false);
DisplayCheat("Test Cheat 1", () => Debug.Log("Test cheat Activated!"));
DisplayCheat("Inverse Gravity", () => Physics.gravity = -Physics.gravity);
}
}
private void DisplayCheat(string cheatName, Action clickedCallback)
{
if (GUILayout.Button("Cheat: " + cheatName))
{
clickedCallback();
}
}
整个实现过程其实非常简单。作弊列表会显示为一排可点击的按钮,点击按钮后会执行相应的回调函数。其中,第一个按钮用于关闭作弊列表。现在,玩家只需单击右上角5次,即可看到作弊列表显示在屏幕上。
查看效果
如果你想查看该系统的实际效果,欢迎下载工程文件,其中包含上述所有脚本和一个测试场景。该工程使用Unity 5.3.0制作,请确保使用Unity 5.3或更高版本。
来源:Unity官方社区