How to make a DOOM CLONE in Unity || E1M4 Player Health and Armor

SpawnCampGames
11 Jan 202109:21

Summary

TLDR在这个视频教程中,Spawn Camp继续开发一个游戏项目,专注于为玩家角色添加健康和装甲系统。首先,他创建了一个'Player Health'脚本来设置最大生命值和装甲值,并在Unity编辑器中通过脚本控制玩家的生命值。接着,他实现了一个'damage player'函数来模拟玩家受到伤害,包括装甲吸收伤害的逻辑。最后,他添加了当玩家生命值降至零时重置场景的功能,使用Unity的Scene Management。视频以对下一集内容的预告结束,承诺将介绍基本的库存系统和触发器。

Takeaways

  • 📂 开始前清理项目窗口,将脚本放入脚本文件夹。
  • 🕹️ 为玩家添加一个名为'Player Health'的新脚本组件。
  • 🔢 在脚本中定义公共变量'maxHealth'和私有变量'health',使用整数类型。
  • 🖊️ 在Unity的检查器中设置'maxHealth'的值为100。
  • 🛡️ 为玩家添加护甲系统,定义'maxArmor'和'armor'变量。
  • 🛑 在'DamagePlayer'函数中添加逻辑,先扣除护甲再扣健康值。
  • 🔧 测试时使用键盘右键Shift键来模拟玩家受到伤害。
  • 💥 当玩家健康值降到0或以下时,通过Debug.Log输出玩家死亡信息。
  • 🔄 玩家死亡后,使用场景管理器重置当前场景。
  • 🎮 视频教程接下来将设置基本的库存系统和触发器,包括健康和护甲的拾取以及对玩家造成伤害的环境。
  • 📢 视频结束时提醒观众如果喜欢这个系列,请点赞和订阅。

Q & A

  • 视频教程中提到的'spawn camp'是什么意思?

    -在视频教程中,'spawn camp'可能是指开发者在游戏开发过程中的一个阶段,即创建敌人并设置它们在游戏世界中生成(spawn)并停留在特定地点(camp)的行为。

  • 为什么要在视频中暂停一段时间?

    -视频中的制作者提到因为假期而暂停了一段时间,这表明制作者可能需要休息或处理个人事务,这是很常见的情况。

  • 视频中提到'doom guy wannabe'是什么意思?

    -'doom guy wannabe'在这里指的是玩家控制的角色,类似于经典游戏《毁灭战士》(Doom)中的主角。

  • 为什么在Unity中添加脚本组件后,脚本会出现在根资产文件夹而不是脚本文件夹?

    -这是因为Unity的默认行为是通过'添加组件'按钮添加新组件时,Unity会将脚本文件放在根资产文件夹中。如果想要脚本出现在特定的文件夹,需要手动将其拖放到该文件夹中。

  • 在Unity脚本中,为什么使用'public int maxHealth'而不是直接使用'public int health'?

    -使用'public int maxHealth'是为了区分最大生命值和当前生命值。这样可以在不改变最大生命值的情况下,通过脚本或游戏逻辑来修改当前生命值。

  • 为什么在脚本中将'health'变量设置为私有(private)?

    -将'health'变量设置为私有是为了封装,防止外部直接修改这个变量,确保只有脚本内部可以修改它,从而维护数据的一致性和安全性。

  • 在Unity中,如何测试玩家受到伤害的功能?

    -在Unity中,可以通过在Update函数中添加测试代码来模拟玩家受到伤害。例如,使用Input.GetKeyDown检测特定按键(如右Shift)被按下,并调用damagePlayer函数来模拟伤害。

  • 为什么在处理玩家受到伤害时要考虑装甲(armor)?

    -考虑装甲是为了增加游戏的复杂性和策略性。装甲可以在玩家受到伤害时吸收一部分伤害,保护玩家的生命值,使游戏玩法更加丰富。

  • 如何在游戏中实现装甲的逻辑,使其在受到伤害时先于生命值被消耗?

    -在damagePlayer函数中,首先检查玩家是否拥有装甲。如果有,根据装甲的值和受到的伤害来决定是消耗装甲还是将剩余的伤害转移到生命值上。如果装甲值大于或等于伤害,则只消耗装甲;如果装甲值小于伤害,则装甲被完全消耗,剩余的伤害转移到生命值上。

  • 在Unity中,如何实现玩家死亡后重置场景的功能?

    -在Unity中,可以通过SceneManagement命名空间中的SceneManager类来加载当前场景。在玩家生命值降到零时,使用SceneManager.LoadScene方法加载当前场景的索引,从而实现场景重置。

Outlines

00:00

🔧 玩家健康系统设置

视频脚本介绍了如何在游戏开发中为玩家角色设置健康系统。首先,开发者在Unity项目中为玩家角色添加了一个新的脚本组件,命名为'Player Health'。在脚本中定义了最大生命值(max health)和当前生命值(health),其中最大生命值在Unity的Inspector面板中设置,而当前生命值在脚本中初始化为最大生命值。接着,脚本中添加了一个'damage player'函数,用于减少玩家的生命值。通过在Update函数中使用Input.GetKeyDown来测试伤害,每当按下右Shift键时,玩家将受到固定的伤害,并在控制台中打印出伤害信息。此外,还提到了Doom游戏中的装甲系统,并计划在接下来的开发中实现。

05:02

🛡️ 玩家装甲与伤害处理逻辑

在玩家健康系统的脚本中,开发者进一步增加了装甲系统,并实现了伤害处理逻辑。首先,定义了最大装甲值(max armor)和当前装甲值(armor),并在游戏开始时将装甲值设置为最大装甲值。然后,开发者在'damage player'函数中加入了判断逻辑,以确定伤害是先作用于装甲还是直接作用于玩家的生命值。具体逻辑为:如果装甲值大于伤害值,则只减少装甲;如果装甲值小于伤害值,则装甲被完全消耗,剩余的伤害再作用于玩家的生命值。通过这种方式,玩家的装甲可以吸收部分伤害,保护玩家的生命值。最后,脚本中还添加了当玩家生命值降至零或以下时的死亡逻辑,通过Debug.Log输出玩家死亡信息,并使用SceneManager重置当前场景,以模拟玩家死亡后的场景重载。

Mindmap

Keywords

💡敌人检测

敌人检测是指在视频游戏中,敌人角色能够感知到玩家角色的存在。在视频中,这是游戏开发过程中的一个关键环节,它允许敌人角色根据玩家的位置进行移动和攻击。例如,脚本中提到'我们离开了这个系列,只是没有建立这些敌人,它们可以检测到玩家并有临时代码向玩家移动',这表明敌人检测是游戏互动性和挑战性的重要组成部分。

💡玩家健康

玩家健康通常指的是视频游戏中玩家角色的生命值或生存能力。在视频脚本中,开发者通过创建一个名为'Player Health'的脚本来实现玩家健康系统,这允许玩家承受伤害并在健康值降至零时死亡。例如,'...我们将会添加一个新的组件,它只是一个基本的脚本,我们将命名为Player Health',这显示了玩家健康是游戏设计中的一个核心概念。

💡装甲

装甲在游戏中通常指玩家角色的防御机制,可以吸收伤害以保护玩家的健康值。在脚本中,装甲被设计为能够减少玩家受到的伤害,并且有最大值限制。例如,'...所以让我们也做基本装甲,所以回到我们的玩家健康脚本...',这表明装甲是玩家生存策略中的一个关键元素。

💡Unity

Unity是一个广泛使用的游戏开发平台,它提供了一套工具和环境,让开发者能够创建和测试游戏。在视频中,Unity被用作开发环境,开发者在其中创建脚本、设置对象和测试游戏机制。例如,'...然后我们可以回到Unity并在检查器中查看...',说明Unity是实现游戏设计和开发的主要工具。

💡脚本组件

脚本组件是Unity中用于添加自定义功能到游戏对象的一种方式。开发者可以通过编写脚本来控制游戏对象的行为。在视频中,'Player Health'脚本就是一个脚本组件,它被添加到玩家对象上以管理其健康和装甲。例如,'...我们将点击玩家根游戏对象,然后我们将在这些脚本下添加一个新的组件...',说明了脚本组件在游戏中的重要性。

💡伤害

伤害在游戏中通常指对玩家角色或敌人角色造成的生命值减少。在脚本中,伤害是通过一个公共函数`damagePlayer`来实现的,该函数接收一个整数参数来表示伤害值。例如,'...我们将要说public void damagePlayer并且...我们将要说health -= damage...',这表明伤害是游戏中影响玩家健康状态的一个关键因素。

💡Debug模式

Debug模式是一个用于开发和测试游戏的功能,它允许开发者查看和修改游戏运行时的变量和状态。在视频中,开发者通过设置检查器为Debug模式来查看私有变量和测试游戏逻辑。例如,'...我们可以在这里检查这些三个点...我们可以改变这个为Debug模式...',说明了Debug模式在游戏开发中用于问题诊断和功能验证的作用。

💡场景管理

场景管理是指在Unity中控制游戏场景的加载、切换和卸载的过程。在视频中,当玩家角色死亡时,开发者使用场景管理来重置游戏。例如,'...然后我们将要说sceneManager.loadScene(this.currentScene.buildIndex);',这显示了场景管理在处理游戏流程和状态转换中的重要性。

💡测试

测试是游戏开发过程中的一个重要环节,它帮助开发者验证游戏机制是否按预期工作。在视频中,测试是通过在`Update`函数中添加一个条件来模拟玩家受到伤害的情况。例如,'...我们将要制作一个测试函数...如果我们按下右Shift键,它将调用damagePlayer函数...',这表明测试是确保游戏玩法正确实现的关键步骤。

💡玩家死亡

玩家死亡是游戏中的一个事件,当玩家角色的健康值降至零或以下时触发。在视频中,开发者通过在`damagePlayer`函数中添加一个检查来实现玩家死亡的逻辑。例如,'...然后我们将会检查如果健康小于或等于零,那么玩家就死了...',这表明玩家死亡是游戏设计中用于结束游戏循环和提供玩家挑战的一个机制。

Highlights

视频作者在假期后回归,希望观众新年伊始过得好。

之前的系列视频已经建立了能够检测玩家并朝玩家移动的敌人。

接下来的步骤是优化代码,让敌人能够实际攻击玩家。

视频将暂时从敌人设置中抽离,开始为玩家设置健康值。

通过Unity编辑器为玩家添加名为'Player Health'的新脚本组件。

脚本通过两种方式添加:直接添加组件或拖拽脚本到玩家对象。

使用Visual Studio编辑脚本,设置最大生命值和当前生命值。

在Unity检查器中设置最大生命值为100。

通过Debug模式在检查器中查看私有的健康变量。

创建'damage player'函数来模拟玩家受到伤害。

使用Input.GetKeyDown在测试中模拟伤害。

实现基本的装甲系统,类似于Doom游戏中的装甲。

在'damage player'函数中添加逻辑以优先消耗装甲。

如果装甲足以吸收全部伤害,则不会影响玩家生命值。

如果装甲不足以吸收全部伤害,则剩余伤害会转移到玩家生命值。

在玩家生命值降至零或以下时,重置场景并显示玩家已死亡。

使用SceneManager加载当前场景以重置游戏。

视频结束时,预告下一集将设置基本的库存系统和触发器。

Transcripts

play00:01

hey spawn camp here sorry for the hiatus

play00:03

but i took a break for the holidays

play00:04

i hope you all had a great holiday and

play00:06

hopefully started 2021 off well

play00:08

we left off this series just haven't

play00:10

built these enemies they can detect the

play00:12

player and has temporary code to move

play00:13

toward the player

play00:14

our next step is to refine this code and

play00:16

have them actually be able to attack the

play00:18

player

play00:18

but first in this video we're gonna step

play00:20

back from the enemy for a second and

play00:21

we're gonna set up our doom guy wannabe

play00:23

aka player to have some health so we can

play00:25

actually damage him

play00:30

like always we'll start by opening our

play00:31

project and for the first thing i'll

play00:33

clean up this project window since i

play00:35

forgot to last video

play00:36

and i'll put my scripts in the script

play00:38

folder

play00:39

now we can work on our players so we'll

play00:41

click on the player root game object

play00:43

and we'll go under these scripts and

play00:45

we'll add a new component

play00:46

and it's just going to be a basic script

play00:48

that will name player health

play00:50

as you can see here the script was added

play00:52

into the root asset folder

play00:54

this is the result of adding a component

play00:56

through this add component button here

play00:58

alternatively you can go into the

play00:59

scripts folder and create a new c

play01:01

sharp file and name it player health and

play01:04

then you can just drag this script onto

play01:06

the player object

play01:07

and the results are basically the same

play01:09

this way doesn't require you to tidy up

play01:11

your projects so often

play01:12

but the ad component is my go-to so it's

play01:16

up to you how you do this

play01:17

but anywho let's double click here to

play01:19

bring up our script inside our editor

play01:21

i was using writer but you'll see now

play01:22

that i'm back on visual studio

play01:24

but they work practically the same all

play01:26

right let's jump right into it

play01:28

at the top here above our start function

play01:30

we're going to say

play01:31

public int max health

play01:36

and we're going to use private int

play01:41

for our health and these are ants

play01:44

because we're only going to use whole

play01:45

numbers

play01:46

and the max health is public because

play01:48

we're going to set it in the inspector

play01:49

our health is a private variable because

play01:52

it'll get modified

play01:53

in the script like here in the start

play01:55

function we're just going to say our

play01:57

health

play01:57

equals our max health so we're going to

play01:59

control s to save and then if we go back

play02:01

into unity and check out our inspector

play02:03

you'll see that we have a max health

play02:05

variable now

play02:06

we're going to keep it basic and we're

play02:07

going to say our max health is 100. to

play02:09

see our private variable we can go up

play02:11

here to these three dots on the

play02:12

inspector

play02:13

and we can change this to debug mode and

play02:15

you'll see now that we have

play02:16

our private health variable and if we

play02:18

just go to play you'll see that our

play02:20

script just sets our

play02:22

health to our max health now let's have

play02:24

our player take some basic damage

play02:26

under our update we're going to say

play02:28

public void

play02:29

damage player and since our health is an

play02:31

integer we're also going to pass in an

play02:33

integer in this function and we're going

play02:35

to name it damage and our logic in this

play02:37

function is going to start off really

play02:39

easy

play02:39

and we're just going to say our health

play02:41

is minus equal damage

play02:43

and the reason this function is public

play02:45

is because it's going to be accessed

play02:46

from outside the script but for now

play02:48

we're just going to test it so we're

play02:49

going to make

play02:50

a test function up inside of our void

play02:52

update

play02:53

call and we're going to say if

play02:56

input.getkeydown and for test purposes i

play02:59

like to use the right side of my

play03:01

keyboard so we're going to use the right

play03:03

shift

play03:05

and then to test the damage we're just

play03:07

going to say damage player

play03:11

and here it's going to take our integer

play03:12

and we're just going to say 30 and then

play03:14

we're going to log

play03:15

a message so we can see it actually

play03:17

happening

play03:19

so we're going to say debug.log player

play03:22

damaged

play03:23

[Music]

play03:28

then if you save and go into unity and

play03:29

play test you'll see

play03:31

that our health does go down by 30 every

play03:34

time we hit shift

play03:35

and it even goes into negatives but

play03:36

we'll fix that later

play03:39

so we have our basic health but doom

play03:41

also has basic armor

play03:43

so let's do that

play03:46

so back in our player health script

play03:48

we're going to do the exact same thing

play03:50

up here at the top we're going to use a

play03:52

public int

play03:53

max armor and we're going to use a

play03:55

private int for armor

play04:00

and in the start we're gonna set our

play04:02

armor

play04:03

to equal our max armor

play04:07

and this is just for our testing

play04:09

purposes because

play04:10

usually you'd want your player to start

play04:12

with no armor and have to pick it up as

play04:14

they go

play04:15

so down the road we will have this where

play04:16

it sets a zero from the start

play04:19

so we're going to need a bit more logic

play04:20

because now we need the damage to affect

play04:22

the armor before it affects the player's

play04:24

health

play04:25

we'll include all this logic inside the

play04:26

damaged player function that we already

play04:28

have

play04:30

so the gist of it is if the player has

play04:32

armor damage at first

play04:34

but there needs to be deeper logic than

play04:35

this because if the player has enough

play04:38

armor to absorb

play04:39

all the damage then we only want to

play04:41

damage the armor

play04:42

and if the player only has enough armor

play04:44

to absorb some of the damage then we

play04:46

want the armor to be damaged first

play04:48

and then the rest of the damage to go to

play04:50

the player

play04:52

so using these comments will flesh out

play04:54

this function

play04:56

so first we'll find out if the player

play04:58

has any armor at all

play04:59

we'll use an if statement and say if

play05:01

armor is greater than zero

play05:04

we want to damage the armor else if we

play05:07

don't have any armor then we just

play05:09

damaged the player

play05:10

like normal so we'll grab this line we

play05:12

already have and move it into the else

play05:13

condition of the if statement

play05:15

that takes care of our first comment

play05:17

here so next we'll take care of the

play05:19

other two

play05:20

both require the player to have some

play05:22

armor so inside the if statement where

play05:24

we check if we have armor

play05:26

then we'll have another check to figure

play05:28

out how much we have and how we'll

play05:30

handle the damage

play05:31

so if our armor is greater than or equal

play05:34

to the damage

play05:35

our player's health remains the same and

play05:37

will issue all the damage to the armor

play05:39

by saying armor minus equals damage

play05:42

now we'll say else if armor is less than

play05:45

damage

play05:46

and will need to figure out how much the

play05:48

armor can take and give the remaining

play05:50

damage to the player

play05:51

so to do this we'll use an int called

play05:54

remaining damage

play05:55

and this will be a local variable

play05:57

because it's not needed outside of this

play05:58

function

play06:00

so now we'll just say remaining damage

play06:02

equals

play06:03

damage minus armor that'll set the

play06:06

remaining damage to whatever is left

play06:08

that the armor can't handle

play06:10

so now that the armor is depleted we'll

play06:12

just set the armor to zero

play06:15

and then we'll say health minus equals

play06:18

remaining damage and that should divide

play06:20

the damage between the armor

play06:22

and the health and that'll knock out the

play06:24

last to-do comment so we'll clean this

play06:26

up and we'll get rid of the comments and

play06:29

we can save

play06:29

and test in unity you'll see at the

play06:32

bottom right that we're still in debug

play06:33

mode so we see our values changed in the

play06:35

inspector

play06:36

so at the start you'll see how our

play06:37

health and armor are set to the max

play06:39

so now if we press the shift key it

play06:41

damages the armor first so we went from

play06:43

having 50 to 20.

play06:45

so now if we damage him again it's going

play06:47

to take all the remaining 20 from the

play06:49

armor

play06:50

and give the other 10 to our players and

play06:52

our players health is at 90

play06:53

and if we continue to spam the damage

play06:55

key eventually we go into negative

play06:57

numbers

play06:58

so as our last step we'll add in

play07:00

something to kill off the player

play07:01

so let's go back into our player health

play07:02

script

play07:07

so we could put a check in our update

play07:09

something like

play07:10

if health is less than or equal to zero

play07:13

then the player is dead

play07:14

and if this is a smaller game that's

play07:16

probably fine but since we know that the

play07:18

player's health

play07:19

only changes when we get damaged then we

play07:21

can go inside of our damaged player

play07:23

function

play07:24

and check there and that way the check

play07:26

is not happening every frame and just

play07:28

bogging our performance down

play07:30

so let's remove that and down in our

play07:32

damaged player underneath all this logic

play07:35

then we're gonna check if we're dead so

play07:38

we're gonna say

play07:38

if our health is less than equal to zero

play07:41

then the player is dead

play07:43

an easy way for this to be displayed to

play07:46

us is just to use a debug.log

play07:48

so we can say debug.log player has died

play07:51

but imma go one farther and i'm going to

play07:53

set it where our scene resets

play07:55

when we die to reset our scene we'll

play07:57

need our scene manager

play07:59

so at the very very top we're going to

play08:01

add a using statement

play08:02

and it's going to be used in unity

play08:04

engine dot scene management

play08:06

then back in the very bottom below our

play08:07

debug.log

play08:09

we can simply say scene current scene

play08:14

equals scene manager dot get active

play08:16

scene

play08:17

that's going to return this scene and

play08:19

then we're going to say

play08:20

scene manager dot load scene and this

play08:23

takes in an integer so we're going to

play08:25

say our current scene that we just set

play08:27

and we're going to say dot build index

play08:30

so now we can save

play08:32

and go into unity for one final test

play08:36

so we're just going to move over here so

play08:38

we can see when our scene resets

play08:40

we're just gonna spam our damaged test

play08:42

key

play08:44

and when our health reaches zero

play08:47

the scene resets and you can see here in

play08:50

our console

play08:51

that the player has indeed died so

play08:54

that's everything working

play08:55

and before i forget let's go back into

play08:57

the inspector here on these three dots

play08:59

and we'll set this

play09:00

back to normal mode that's about it for

play09:02

this video we have enemies and we have a

play09:04

player with armor and health

play09:06

the next episode will probably set up a

play09:07

basic inventory and also mess around

play09:09

with triggers

play09:10

some will give the player health and

play09:11

armor such as pickups and others will

play09:13

damage the player such as lava or toxic

play09:15

waste

play09:16

if you're enjoying the series please

play09:17

like and subscribe so you don't miss the

play09:18

next one

play09:19

spawn camp out

Rate This

5.0 / 5 (0 votes)

Related Tags
Unity开发游戏编程角色健康护甲系统伤害逻辑死亡机制脚本编写游戏设计玩家互动教程视频
Do you need a summary in English?