这是一个简单的恐怖FPS游戏,提供了可拾取的数款枪械并设计了射击和敌人系统,基于C#
语言和Unity3D Build-In
渲染管线制作。请点击这里观看宣传视频。
注意:项目仅供学习参考使用,可能缺乏一定娱乐性及趣味性,不用于商业用途。我们不对项目的稳定性和最终效果负有任何责任。
如果您只想对项目进行简单体验,可以查看第一部份和第二部份,无需了解其原理。如果您正在学习C#或Unity,我们建议阅读我们全部的文档,熟悉Nightmare的运作逻辑和机制,以便参考和借鉴。
第一部份 - 下载和使用
第二部份 - 操作方式
第三部份 - 枪械实现
第四部份 - 敌人实现
第五部份 - 场景实现
第六部份 - 存档系统
第七部份 - 素材使用
一般情况下,我们推荐用户直接前往Releases
界面下载与操纵版本对应的已打包的游戏程序,而不是在Code - DownloadZip
中直接下载源代码。
Nightmare 在不同在操作系统下有不同的安装方式,请您在下载对应架构的软件后执行下列操作:
如果您使用的是MacOS操作系统,您可以直接将下载下的软件移动至访达-边栏-应用程序
或Users/(您的用户名)/Application
。不出意外的话,您将在启动台中看到它,单击鼠标左键可以打开,点击游戏内Ese - 退出游戏
退出游戏。
如果您使用的是Windows操作系统,不出意外,您将获得一个文件夹。如果您想直接启动程序,可以进入文件夹并直接打开Nightmare.exe
。为了便于开启,可以将文件夹手动移动至默认下载文件夹或自定义路径,即C:\Program Files\
,并添加快捷方式至桌面。
如果您使用的是Linux操作系统,首先需要确保下载下来的Unity游戏文件夹包含了一个Linux平台的可执行文件。通常,这个文件不会有.exe扩展名,而是一个没有扩展名的可执行文件,您可能需要手动赋予其执行权限。下面是如何安装和启动游戏的步骤:
- 赋予执行权限:打开终端,使用cd命令导航到游戏文件夹的位置。然后,使用chmod命令赋予游戏主执行文件执行权限。假设游戏的主执行文件名为GameName,您可以使用以下命令:
chmod +x Nightmare.x86_64
- 启动游戏:一旦赋予了执行权限,您可以通过终端直接启动游戏,只需输入:
如果游戏位于您的
./Nightmare.x86_64
PATH
环境变量中的目录下,也可以直接输入游戏名来启动。
为了便于开启,您还可以创建一个桌面快捷方式或将游戏添加到您的应用启动器中,这样就可以不通过终端来启动游戏。不同的Linux发行版可能有不同的方法来创建快捷方式,通常需要创建一个.desktop
文件并填写相应的游戏启动命令和路径。
Nightmare 支持大部份键鼠和手柄。一般地来说,只要键鼠和手柄在系统内可以正常使用,游戏就可以自动识别到所有支持的输入设备。Nightmare 对输入设备有以下要求:
- 键盘:至少60键以上并且包含基本的功能和辅助按键
- 鼠标:至少包含左键和右键,以及一个可以用于滚动的滚轮。
- 手柄:建议使用 Xbox 或 PlayStation 手柄,其它布局未经测试,不保证可行性和可用性
*注:Nightmare可以同时连接多个手柄和键盘,并支持同时输入。在识别到连接手柄后,会自动调整输入灵敏度和开镜模式,因此,我们不建议在连接手柄的情况下使用键盘游玩。
Nightmare 使用了通用广泛且符合逻辑的输入键位,您通过以下按键来对玩家执行操作:
- 使用
[WASD]/[Left Stick]
键实现平面移动 - 按
[SPACE]/[Button West]
键实现跳跃 - 按
[Shift]/[Right Shoulder]
键实现奔跑以增加速度 - 按
[Control]/[Command]/[Left Shoulder]
键实现下蹲以降低移动声音并减小速度 - 按
[Tap]
键或[Left Shoulder]&[Right Shoulder]
键实现翻滚
Nightmare 的所有武器使用统一的操作逻辑。通过鼠标左键实现射击,对于全自动武器,按住鼠标左键可以连续射击。Nightmare 的瞄准可以通过单击或长按鼠标右键实现,您可以在设置中切换控制方式。通过以下按键操控武器:
- 按
[I]/[Button North]
键进行检视 - 按
[R]/[Button East]
键进行换弹 - 按
[C]/[D-Pad Left]
键可以开关安装在枪械上的手电筒 - 按
[Q]/[Button Sourth]
可以发动近战 - 按
[X]/[D-Pad Right]
键更换射击模式(仅对全自动武器有效)
Nightmare 中武器库通过鼠标滚轮或数字键盘来判定武器的更改武器。如果使用鼠标滚轮,您可以通过向下/向上滑动切换至下一把/上一把武器,如果已经是最后一把武器,下一次滑动将会切换到空手状态,再次滑动会切换到第一把武器。同理的,如果使用数字键盘,可以通过按下按键可以直接切换到对应编号的武器,若输入超限或为0,即输入的数字不为已有的任何一把武器的编号,将切换到空手状态。空手状态不能发动近战。
在 Nightmare 中,如果您想要拾取武器或者可交互物体,您需要将玩家移动到物体附近,并将视角移动到您想要拾取/交互物体上。如果该物体可以被交互,您会看到该物体的上方出现了一个半透明的圆形,此时即代表您可以进行拾取操作。对于枪械,如果您原先没有这把武器,拾取后会自动切换到对应武器,如果您已经拥有这把武器,那么再次进行拾取将会自动补满对应武器的备弹并切换到当前武器。如果您想要丢弃物体,您需要切换到希望丢弃的枪械并按下丢弃键,物体会自动生成在您的前方并自然下落。您可以通过以下按键对物体进行交互:
- 按
[F]/[D-Pad Up]
键拾取/交互物体 - 按
[T]/[D-Pad Down]
键丢弃物体
*注:武器库的拾取上限为3,即如果您已经拥有3把武器,您将不能够再拾取新的武器。
在 Nightmare 中,目前回复血量的唯一方法是食用食物。如果您想要通过食物来回复血量,您需要拾取食物(方法详见/操作方式 - 物体的丢弃和拾取/
),角色会在您拾取后自动食用食物。在食用食物的过程中,您将听到声音提示,血量会在食用过程中不断增加。目前 Nightmare 已支持多种食物,每种食物可以增加的血量和咀嚼的时间各不相同。
*注:同一时间只能吃一个食物。
Nightmare 中可以用武器和场景中的可交互物体对敌人进行攻击。使用枪械对敌人造成伤害的判定使用基于物理的Raycast,不同型号和种类的枪械对于敌人造成的伤害不同。同样的,场景中的大部分可交互物体,如油桶和气瓶,也可以对敌人造成伤害,使用子弹或近战可使其爆炸,不同种类的物体对敌人造成的伤害和伤害的范围各不相同。对于场景中的可交互物体,内容详见/场景实现 - 可交互物体/
。
*注:子弹命中头部可大幅提高伤害,并且子弹可以一定程度上击退敌人。
在 Nightmare 场景中,散布着许多迭代留下的纸条,它们或许可以为您在迷茫中指引前进的方向,也或许能让您一点点拼凑出过去的故事。为了查看纸条,您需要前往纸条旁并将其拾取(内容详见/操作方式 - 物体的丢弃和拾取/
)。拾取纸条后,一个用于查看纸条内容的界面会自动弹出,在这个界面中,鼠标将被自动释放,您可以通过鼠标的拖动或滚轮的转动来查看内容。若要关闭界面,您可以用鼠标点击位于屏幕右上角的X
键或按下键盘上的对应按键:
- 按
[F]/[D-Pad Up]
键查看纸条 - 按
[Enter]/[D-Pad Down]
键以关闭查看界面
*注:查看纸条时不能对角色和武器进行任何控制,而敌人可以正常移动。因此,在查看纸条前务必确保环境安全。
在 Nightmare 中,可以在游戏内按下按键的方式召唤出选项菜单,此时,鼠标将会解锁,玩家不能移动,您可以在这里进行操作。特别的,对于「游戏设置」选项,点击它将弹出一个新的设置菜单,您可以在这个菜单中编辑选项,关闭该设置菜单后设置将自动应用。您可以通过以下按键进行操作:
- 按
[Esc]
键唤取选项菜单 - 按
[Left Stick] & [Right Stick]
键唤取选项菜单
*注:您的更改将会被存储,在下次启动游戏后仍然会记住您的设置。
Nightmare 中的可交互UI分为两种,按钮和复选框。通常情况下,按钮会呈现灰色,复选框会根据当前状态呈现不同的颜色:
- 灰色:复选框没有选中/没有启用该选项
- 白色:复选框选中/启用了该选项
当鼠标指针进入范围时,按钮/复选框为变为白色并且播放提示音,点击按钮会直接执行相应的操作,而点击复选框会切换状态。
Nightmare 的存档系统是自动、快速、无需人工干预的,只要您通过正常的方式结束游戏,Nightmare 就会帮助您在退出时自动保存,下次开始游戏后会自动恢复到上一个存档点。若要删除存档,请点击 主页面 - 清除存档
或 Esc - 清除存档
,存档清楚后会自动返回主页面,在主页面点击 清除存档
没有反应是正常现象。
*注:在某些非正常的强制退出下,自动保存不起作用。
Nightmare 存在多个结局,游戏中的任何一个行为和选择都可能会影响最终结局。包含正常死亡的,Nightmare 存在4个普通结局和2个隐藏结局,我们期待着玩家自行探索这些结局。
Nightmare 中的所有枪械都与场景分开渲染,将 Gun Camera 渲染的 Player 层深度视图叠加到 Main Camera 上。因此,Nightmare 中的所有枪械不可能与场景中的物体发生穿模现象。
Nightmare 同时使用了两套系统进行判定,对于击中敌人和扣血的判定,使用从枪口发射的 Physics.Raycast(射线检测),而对于弹孔和场景中可交互物体(如油桶、气瓶)及弹孔的生成,使用了基于物理 Rigidbody 的真实子弹,对子弹施加初始速度,以基于几何节点的碰撞起判定碰撞。
对于所有的步枪、手枪和部份有弹夹的狙击枪换单子弹会在插入弹夹时被瞬间增加。对于所有的霰弹枪和部份狙击枪,换单时子弹的增加会依据动画状态机中动画的执行,即真实的子弹数会根据一颗一颗填入子弹的动画而自然地增加。
Nightmare 中所有狙击枪的镜内放大效果都使用了一个专门的低FOV像机将图像映射到空间中狙击镜的前部,已实现开镜效果。狙击镜在开镜和关镜状态下会前玻璃会呈现出不同的颜色以模拟真实的效果。
Nightmare 中为交互物体挂载了基于几何节点的 Trigger 碰撞箱,同时通过为玩家的摄像机加入带有特殊Tag的碰撞箱作为子物体,使交互物体可以判断玩家的视角是否朝向物体。如果玩家摄像机下的碰撞箱碰撞到交互物体,该物体会将隐藏的圆形2D图像启用。由于玩家和物体可能处于不同的旋转角度,UI图像会保持在离玩家最近的垂直方向,且始终朝向玩家。等待玩家按下对应按键并执行对应操作。丢弃武器时该项目采用直接生成的方式,用基于物理的 MeshCollider 及 RigidBody 使枪械物体受重力自然地落到地上。
Nightmare 中暂时只有两种敌人,「丧尸」和「变种人」。变种人无论是血量、速度、伤害等方面都远远强于丧失,因此理论上来说,丧失通常会在变种人的带领下扎堆活动。通常地来说,敌人应当在没有发现玩家时以行走速度执行巡逻,发现玩家后向玩家奔跑。当然,也不乏丧失或变种人单独出现活动甚至不巡逻的情况。
敌人只有在满足一定条件下才会发现玩家,具体情况如下:
// 伪代码
if(玩家进入敌人的可发现范围){
if(玩家不在下蹲&&玩家正在移动) 敌人发现玩家;
if(玩家使用了不带有消音器的枪械开枪) 敌人发现玩家;
if(玩家攻击了敌人&&敌人血量低于70%) 敌人发现玩家;
if(玩家达到了敌人的绝对发现阈值) 敌人发现玩家;
}else{
敌人不会发现玩家;
}
*注:不同敌人的可发现范围和绝对发现阈值不同。
Nightmare 中所有敌人的移动都基于A*
寻路算法优化的Navigation Mesh Agent
。在巡逻时,场景中的敌人会调用Navigation Mesh Agent
自动行进至分配的巡逻点,当敌人距离与巡逻目标点足够近时,目标移动位置会自动切换至下一个巡逻点,以此往复。当敌人发现玩家后,移动目标点会切换至玩家的实时位置,待玩家进入敌人的可攻击范围,即玩家与敌人足够近的时候,敌人停止移动并执行攻击逻辑。
敌人会在进入攻击范围后停止并执行攻击程序,不同种类的敌人的攻击伤害和CD不同。对于丧失,敌人会有较短的CD和较小的伤害;对于变种人,敌人会有较长的CD和极大的伤害,变种人攻击时有爆炸例子特效。玩家在敌人的攻击范围内并且敌人在执行CD冷却时会执行Idle动画。
在 Nightmare 中,子弹射击到敌人的头部和身体会产生不同的伤害。用于判定的,敌人身体上包含了一个间隔帧实时烘焙的Mesh Collider
,而在敌人的头部存在一个大于Mesh Collider
的Sphere Collider
,使得玩家枪械的射线检测可以在Mesh Collider
前优先检测到Sphere Collider
,以检测是否射击到敌人头部。
在 Nightmare 中,食物被拾取的原理与枪械类似,通过基于几何节点的 Trigger 碰撞箱判断与玩家手臂的碰撞。在玩家视角朝向食物的情况下,判断用户是否按下对应按键。如果玩家按下拾取按键,食物会在调用玩家音源播放拾取声音和回血协程后自我销毁。玩家的协程会在食物销毁后继续播放咀嚼音效并根据拾取食物的数据持续不同的咀嚼时间并恢复不同的血量。
在 Nightmare 中,所有纸条代码都继承自同一个基类,这个基类包含了场景中所有纸条的内容,而每个纸条只包含文本的ID。当基于几何节点的 Trigger 碰撞箱判断与玩家手臂的碰撞且检测到玩家按下了拾取按键,解锁光标并显示查看视图。纸条的查看视图由一个置顶的 X
按钮和一个隐藏滚动条的 Scroll View 组成,使得玩家可以自然地用鼠标滚落或鼠标拖动并查看界面。在查看纸条的过程中,玩家的一切移动将会被锁定并时刻监听玩家的输入,直到玩家按下 [Enter]/[D-Pad Down]
或点击 X
按钮,操作状态恢复。
Nightmare 场景中油桶和气瓶可以与子弹和玩家交互。油桶和气瓶可以被玩家推动,可交互物体的爆炸判定有物理发射的子弹执行。其中,当子弹碰撞到油桶时,油桶会瞬间爆炸并在大范围内释放出大量伤害;当子弹碰撞到气瓶时,气瓶会从顶部漏气,内部压力达到一个阈值时就会产生爆炸,在一个相对小的范围内释放出一定伤害。
*注:场景中的可交互物体的破坏不会影响地形。
Nightmare 中的一些特定场景会对玩家造成一定的影响。例如,水中玩家会被强行下蹲,不能跳跃并在移动的时候播放水中移动的音效。对于场景中所有通过玩家进入且此时天花板的高度小于玩家站立高度的情况,玩家会被强制下蹲,即使用户松开 [Control]/[Left Shoulder]
,离开该场景且用户没有按下 [Control]/[Left Shoulder]
的情况中,玩家会自动重新进入站立状态。
Nightmare 的存档系统采用了简洁高效的方法来保存和加载玩家的游戏进度。通过将玩家的位置、生命值、武器状态等信息序列化为 JSON 格式保存到文件中,从而实现了游戏的存档和读档功能。这不仅保证了数据的持久性,也方便了数据的管理和迁移。
为了关闭游戏,用户需要按下 Esc
按键或切换窗口焦点,Nightmare 会捕捉并监听这些信息,并在这些行为触发时自动触发存档过程,理论上来说覆盖了除强制退出外的所有可能情况。该过程涉及收集当前游戏状态的各种信息,包括但不限于玩家的位置、角色的朝向、当前的生命值、所拥有的武器及其状态(如当前弹药量)、敌人的状态以及其他可能影响游戏进度的因素。这些信息将被序列化并保存到本地文件中,以便之后可以重新加载这些状态。
当玩家开始游戏并且已经有存档被保存时,游戏将读取之前保存的存档文件,并反序列化存档中的信息,将游戏状态恢复到存档时的状态。这意味着玩家的位置、生命值、武器状态、敌人的位置和状态等都将被恢复,允许玩家从他们离开时的确切点继续游戏。
玩家在游戏中可能会希望重新开始,或者在某些情况下需要清除现有的存档。为此,我们提供了一个清除存档的功能,允许玩家删除当前的存档文件。您可以在 主界面 - 清除存档
或 Esc - 清除存档
中找到它。Nightmare 在操作之前会先确保存档文件存在,否则不予执行。
*注:通过 Esc - 清除存档
清除存档会自动返回主页面,以防止存档再次自动保存。
- Low Poly FPS Pack 素材包
- Flooded Grounds 地图模型
- Mixamo 敌人模型及动画
- Zombie Character Sounds 声音素材
- Legacy Particle Pack 粒子效果