본문 바로가기

로블록스 개발 기초

로블록스 코딩 - 용암 만들기(2/2)

캐릭터 모델과 휴머노이드 객체

앞서 우리는 LavaFloor라는 Part(여기서는 그냥 블럭이라고 불렀으나 로블록스에서는 Part라는 이름으로 부른다)을 만들었다. 이 Part의 Touched 이벤트에 killPlayer() 함수를 연결시켜서, 또 다른 Part에 의한 Touched이벤트가 생기면 killPlayer() 함수를 호출한다는 부분까지 알았다.

LavaFloor 블럭에 다른 Part가 닿는다는 의미는, 플레이어의 캐릭터 모델에 포함된 파트들 중에 하나와 닿았는 말이다. 그것은 왼쪽 다리, 오른쪽 다리, 몸통, 머리가 될 수도 있다. 아무튼 캐릭터 모델의 한 파트와 닿았을 때, killPlayer()가 발생되고 왼쪽 다리파트, 오른쪽 다리 파트등이 파라메타로 killPlayer() 함수 내로 보내지게 된다.

캐릭터 모델의 한 파타만 용암 파트에 닿을 수 있다는 말은 아니다. 다른 어떤 파트도 용암 파트에 닿으면 Touched 이벤트가 발생한다. 그냥 여기서는 다른 상황은 생각하지 말고 캐릭터 모델의 파트에 집중하자.
  • 캐릭터 모델은 플레이어의 아바타를 구성하는 모든 오브젝트를 포함한다.
    아바타 몸을 이루는 머리, 몸통, 다리 파트등을 모두 포함한 모델이 캐릭터 모델이 된다.
  • 아바타가 입는 옷, 악세사리등도 캐릭터 모델에 포함된다.
  • 캐릭터 모델에는 Humanoid 라는 특별한 객체도 들어있는데 이 휴머노이드 객체에는 플레이어의 HP를 포함한 여러가지 속성들이 들어있다. 우리는 이 휴머노이드의 HP속성을 0으로 만들어서 플레이어 아바타를 죽일 수 있다.

Touched 이벤트를 발생시킨 파트에서부터 휴머노이드 객체의 Health속성에 접근하는 과정을 정리해보면,

  1. 머리, 다리, 팔등의 어떤 파트에서 캐릭터 모델을 찾는다.
  2. 캐릭터 모델안에 휴머노이드 객체를 찾는다.
  3. 휴머노이드 객체의 Health 속성을 변경한다.

머리, 다리, 팔등의 어떤 파트를 otherPart라고 하면, otherPart.Parent 는 캐릭터 모델이 된다. 캐릭터 모델을 구성하는 파트이니, 그 파트의 Parent 오브젝트는 캐릭터 모델이 되는 것은 당연한 얘기이다.

local lava = script.Parent

-- lava 에 닿은 otherPart
local function killPlayer(otherPart)
    -- partParent에는 캐릭터 모델이 대입된다. 
    local partParent = otherPart.Parent
end
 
lava.Touched:Connect(killPlayer)

캐릭터 모델 안에는 휴머노이드 객체가 들어있다. 이 Humanoid 객체에 접근하기 위해서 FindFirstChild함수를 이용한다. FindFirstChild() 함수는 원하는 이름을 파라메터로 넘기면 그 이름을 가진 자식 객체를 찾아서 반환한다. 같은 이름의 자식 객체가 있는 경우에는 처음에 찾은 자식 객체를 반환한다.

local lava = script.Parent
 
local function killPlayer(otherPart)
    local partParent = otherPart.Parent
    -- FindFirstChild() 함수를 통해 휴머노이드 객체를 찾음.
    local humanoid = partParent:FindFirstChild("Humanoid")
end
 
lava.Touched:Connect(killPlayer)

휴머노이드(Humanoid) 체크하기

위의 과정으로 우리는 otherPart에서부터 휴머노이드 객체의 Health속성의 접근까지 알아보았다.

여기에는 한가지 문제가 있는데...

otherPart를 통해 휴모노이드를 찾는 과정 중에서, 우리는 otherPart라는 것을 캐릭터의 한 부분일 것으로 가정했다. 하지만 사실 LavaFloor에 닿을 수 있는 파트라는 것이 캐릭터의 파트 뿐만이 아니다. 경우에 따라 예상할 수 없는 파트가 Touched 이벤트를 발생시킬 수도 있지 않겠는가. 즉 otherPart의 Parent는 캐릭터 모델이 될 수도 있지만, 다른 어떤 것이 될 수도 있는 것이다. 이 경우에 FindFirstChild()로 휴머노이드를 아무리 찾아봤자, 찾을 수 없는 경우가 생길 수 있다. FindFirstChild()로 객체를 찾지 못할 경우에 nil이라는 자료형으로 반환한다. nil은 아무것도 아니다라는 뜻으로 이해하자. 

아무튼 humanoid 에 nil이 대입되는 경우는 여러 이유로 인해 실제 플레이어의 휴머노이드에는 접근 하지 못했다는 의미가 된다. 휴머노이드 객체가 아니므로 Health 속성을 변경할려는 시도를 하면 프로그램이 에러를 발생하게 된다. 따라서 humanoid의 Health 속성에 접근하기 전에 humanoid가 nil 이 아닌지를 체크하는 작업이 필요하게 된다.

여기서 우리는 if문을 사용한다. lua 언어에서 if문은 다음과 같은 문법을 사용한다.

if 조건문 then
    -- 조건문이 true일때 실행되는 내용
end

자 이제 실제 소스 코드를 확인하자.

local lava = script.Parent
 
local function killPlayer(otherPart)
    local partParent = otherPart.Parent
    local humanoid = partParent:FindFirstChild("Humanoid")
    if humanoid then
 
    end
end
 
lava.Touched:Connect(killPlayer)

조건문에는 단순히 humanoid가 들어 있는데 lua언어 문법에서 nil은 그 자체가 false를 나타낸다. 따라서 nil 이 아니면 true, nil 이라면 false를 가리키는 조건문이 되는 것이다. 물론 저 조건문을 "humanoid ~= nil"로 사용할 수도 있다. lua언어에서는 적합한 문법이므로 여기서는 제일 단순하게 humanoid 로만으로 조건문을 사용하였다. 루아에서는 다른 언어와 다르게 "!=" 연산이 "~="을 사용하는 점도 기억해두자.

Health 속성 변경

휴머노이드 Health 속성을 0으로 셋팅하면 플레이어의 아바타는 즉시 죽게된다.

local lava = script.Parent
 
local function killPlayer(otherPart)
    local partParent = otherPart.Parent
    local humanoid = partParent:FindFirstChild("Humanoid")
    if humanoid then
        humanoid.Health = 0
    end
end
 
lava.Touched:Connect(killPlayer)

이로써, 용암 블럭에 캐릭터가 닿으면 죽는 기능은 완성되었다. 테스트를 통해 게임 아바타가 잘 죽는지 확인해보자.

요약

  • Touched 이벤트를 통해 캐릭터 모델의 파트에서부터 휴머노이드 속성 접근까지의 과정 알아보기
  • if문 사용법 알아보기
  • FindFirstChild() 함수 사용해보기

다음글

2021.04.16 - [로블록스 개발 기초] - 로블록스 코딩 - 서서히 사라지는 블럭(1/2)