Menu
CoddyTech

벽을 따라

Coddy의 Roblox 게임: 어둠에서 탈출하기 코스 레슨. 20개 중 10번째.

문 옆 방에 서 있으면 괴물은 벽으로 걸어갑니다. MoveTo는 직선으로 이동하기 때문입니다. 두 가지를 바꾸면 괴물이 사냥꾼이 됩니다.

첫째, Settings.MonsterSight 범위 안에서만 사냥합니다. 둘째, 벽이 가로막으면 경로를 찾습니다. workspace:Raycast는 괴물에서 당신에게 광선을 쏩니다. 아무것도 맞지 않거나 당신을 맞히면 길이 뚫려 있다는 뜻입니다. 그렇지 않으면 PathfindingService가 벽을 돌아 문간을 통과하는 길을 찾고, 괴물은 경로의 다음 지점으로 걸어갑니다. 그리고 0.25초 후에 다시 경로를 요청합니다.

path:ComputeAsync(root.Position, goal)
local points = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success and points[2] then
	shadow.Humanoid:MoveTo(points[2].Position)
end
challenge icon

챌린지

중급
  1. PathfindingService를 가져오고 각 몬스터에 경로를 지정합니다. runMonster에서 local path = PathfindingService:CreatePath()를 사용하세요.
  2. nearestCharacter의 최적 거리를 Settings.MonsterSight로 설정합니다.
  3. walkToward(shadow, goal, path)를 작성합니다. 레이캐스트에서 몬스터는 제외하고, 앞이 뚫려 있으면 직진하며, 앞에 벽이 있으면 경로의 다음 지점으로 이동합니다.
  4. walkToward로 추격하고, 범위 안에 아무도 없으면 가만히 서 있습니다.

Play를 누른 다음 Check를 누르세요.

직접 해보기

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Lighting = game:GetService("Lighting")
local TweenService = game:GetService("TweenService")
local Settings = require(game.ReplicatedStorage.Settings)

local rooms = workspace.Rooms
local lastRoom = rooms.Lobby -- 가장 최근에 생성된 방
local count = 0 -- 지금까지 생성된 방의 수
local monster = nil

-- 밤이 찾아옴: 해는 없고, 곳곳에 희미한 빛과 안개가 있음
Lighting.ClockTime = Settings.ClockTime
Lighting.Ambient = Settings.Ambient
Lighting.OutdoorAmbient = Settings.Ambient
Lighting.FogColor = Color3.new(0, 0, 0)
Lighting.FogEnd = Settings.FogEnd
print("Lights out")

-- 플레이어가 지닌 도구: 손에 들고 있거나 Backpack에 있음
local function findTool(player, name)
	return (player.Character and player.Character:FindFirstChild(name)) or player.Backpack:FindFirstChild(name)
end

-- 경첩을 중심으로 문을 회전시켜 열기
local function openDoor(door)
	door:SetAttribute("Open", true)
	door.Panel.Prompt.Enabled = false
	local hinge, panel = door.Hinge, door.Panel
	local goal = hinge.CFrame * CFrame.Angles(0, math.rad(90), 0) * hinge.CFrame:ToObjectSpace(panel.CFrame)
	TweenService:Create(panel, TweenInfo.new(0.6), { CFrame = goal }):Play()
end

-- 가장 가까운 살아 있는 플레이어와 그 거리
local function nearestCharacter(position)
	local best, bestDistance = nil, math.huge
	for _, player in Players:GetPlayers() do
		local character = player.Character
		local root = character and character:FindFirstChild("HumanoidRootPart")
		if root and character.Humanoid.Health > 0 then
			local distance = (root.Position - position).Magnitude
			if distance < bestDistance then
				best, bestDistance = character, distance
			end
		end
	end
	return best, bestDistance
end

-- 괴물의 행동: 0.25초마다 누군가를 쫓음
local function runMonster(shadow)
	local humanoid = shadow.Humanoid
	local root = shadow.HumanoidRootPart
	while shadow.Parent do
		local character = nearestCharacter(root.Position)
		if character then
			humanoid:MoveTo(character.HumanoidRootPart.Position)
		end
		task.wait(0.25)
	end
end

-- 괴물이 뒤에서 나타남: 가장 최근 방보다 두 방 앞선 방의 입구에서
local function spawnMonster()
	local behind = nil
	for _, room in rooms:GetChildren() do
		if room:GetAttribute("Number") == count - 2 then
			behind = room
		end
	end
	if not behind then
		return
	end
	monster = ServerStorage.Shadow:Clone()
	monster:PivotTo(behind.Entrance.CFrame + Vector3.new(0, 3.1, 0))
	monster.Humanoid.WalkSpeed = Settings.MonsterSpeed
	monster.Parent = workspace
	task.spawn(runMonster, monster)
end

local addRoom -- 아래에 작성됨: 문을 열면 방이 추가되고, 방에는 문이 있음

-- 플레이어가 문을 열었을 때 일어나는 일
local function setupDoor(door)
	door.Panel.Prompt.Triggered:Connect(function(player)
		if door:GetAttribute("Open") then
			return
		end
		if door:GetAttribute("Locked") then
			local key = findTool(player, "Key")
			if not key then
				return
			end
			key:Destroy()
			door:SetAttribute("Locked", nil)
		end
		if door.Parent == lastRoom then
			addRoom()
		end
		openDoor(door)
	end)
end
setupDoor(workspace.Rooms.Lobby.Door)

-- 방에 들어가면 그 방이 플레이어의 Room과 체크포인트가 됨
local function setupEntry(room)
	room.Entry.Touched:Connect(function(hit)
		local player = Players:GetPlayerFromCharacter(hit.Parent)
		if player then
			local number = room:GetAttribute("Number")
			player.leaderstats.Room.Value = number
			player.RespawnLocation = room.Checkpoint
		end
	end)
end
setupEntry(workspace.Rooms.Lobby)

-- 가장 최근 방의 출구에 새 방을 생성
function addRoom()
	count += 1
	local name = Settings.Order[(count - 1) % #Settings.Order + 1]
	if count >= Settings.RoomsToEscape then
		name = "Exit"
	end
	local room = ServerStorage.Rooms[name]:Clone()
	room:PivotTo(lastRoom.Exit.CFrame)
	room:SetAttribute("Number", count)
	room.Sign.SurfaceGui.Number.Text = "Room " .. count
	room.Parent = rooms
	lastRoom = room
	setupDoor(room.Door)
	setupEntry(room)
	-- 잠긴 방은 열쇠를 방 안에 보관한다
	local keySpot = room:FindFirstChild("KeySpot")
	if keySpot then
		local key = ServerStorage.Key:Clone()
		key.Handle.CFrame = keySpot.CFrame
		key.Parent = room
		key.Handle.Prompt.Triggered:Connect(function(player)
			key.Handle.Prompt.Enabled = false
			key.Parent = player.Backpack
		end)
	end
	-- 가장 최근 방과 그 뒤의 KeepRooms개 방을 유지한다
	for _, old in rooms:GetChildren() do
		if old:GetAttribute("Number") < count - Settings.KeepRooms then
			old:Destroy()
		end
	end
	if count == Settings.MonsterFrom then
		spawnMonster()
	end
	return room
end

-- 모든 플레이어: 리더보드에 Room을 표시하고, 부활할 때마다 손전등을 지급한다
Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local room = Instance.new("IntValue")
	room.Name = "Room"
	room.Parent = leaderstats

	player.CharacterAdded:Connect(function()
		local flashlight = ServerStorage.Flashlight:Clone()
		flashlight.Parent = player.Backpack
		local beam = flashlight.Handle.Beam
		flashlight.Activated:Connect(function()
			beam.Enabled = not beam.Enabled
		end)
	end)
end)
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Roblox 게임: 어둠에서 탈출하기의 모든 레슨