Menu
CoddyTech

Verstecken

Lektion 12 von 20 im Kurs Roblox-Spiel: Entkomme der Dunkelheit von Coddy.

Die Closet-Räume haben einen Schrank mit einer Eingabeaufforderung „Verstecken“. Wenn du sie betätigst, gelangst du hinein (zu seinem Inside-Marker) und dein Charakter wird als Hidden markiert. Betätigst du sie erneut, gelangst du zurück in den Raum.

Die nearestCharacter-Funktion des Monsters überspringt versteckte Charaktere, sodass es bei vollständig versteckten Spielern stehen bleibt. Und ein Spieler, der den Schrank verlässt, ohne die Eingabeaufforderung zu betätigen, ist nicht mehr versteckt: Eine Schleife entfernt die Markierung, wenn er sich mehr als 4 Studs von jedem Inside eines Schranks entfernt befindet.

if root and character.Humanoid.Health > 0 and not character:GetAttribute("Hidden") then
challenge icon

Aufgabe

Mittel
  1. Schreibe setupCloset(closet): Der Front.Prompt versteckt den Spieler (Pivot zu Inside, 2.5 nach oben; Hidden setzen) oder holt ihn, wenn er versteckt ist, wieder heraus (3 Studs aus dem Front heraus pivotieren, mit Blick in den Raum; Hidden löschen). Rufe die Funktion in addRoom für das Closet eines Raums auf.
  2. Überspringe versteckte Charaktere in nearestCharacter.
  3. Eine Schleife: Lösche alle 0.25 Sekunden Hidden bei einem Charakter, der mehr als 4 Studs von jedem Inside entfernt ist.

Drücke Play und dann Check.

Probier es selbst

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

local rooms = workspace.Rooms
local lastRoom = rooms.Lobby -- der neueste Raum
local count = 0 -- bisher erstellte Räume
local monster = nil

-- Die Nacht bricht herein: keine Sonne, überall ein wenig Licht und Nebel
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")

-- Ein Gegenstand, den ein Spieler bei sich trägt: in der Hand oder in seinem Backpack
local function findTool(player, name)
	return (player.Character and player.Character:FindFirstChild(name)) or player.Backpack:FindFirstChild(name)
end

-- Eine Tür um ihr Scharnier aufschwingen lassen
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

-- Der nächste lebende Spieler innerhalb von MonsterSight und seine Entfernung
local function nearestCharacter(position)
	local best, bestDistance = nil, Settings.MonsterSight
	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

-- Auf einen Punkt zugehen: bei freiem Weg geradeaus, sonst entlang eines Pfads
local function walkToward(shadow, goal, path)
	local root = shadow.HumanoidRootPart
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = { shadow }
	local hit = workspace:Raycast(root.Position, goal - root.Position, params)
	if not hit or hit.Instance.Parent:FindFirstChildOfClass("Humanoid") then
		shadow.Humanoid:MoveTo(goal)
		return
	end
	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
end

-- Der Verstand des Monsters: alle Viertelsekunde jemandem hinterher
local function runMonster(shadow)
	local humanoid = shadow.Humanoid
	local root = shadow.HumanoidRootPart
	local path = PathfindingService:CreatePath()
	while shadow.Parent do
		local character = nearestCharacter(root.Position)
		if character then
			walkToward(shadow, character.HumanoidRootPart.Position, path)
		else
			humanoid:MoveTo(root.Position)
		end
		task.wait(0.25)
	end
end

-- Das Monster erscheint hinter dir: am Eingang des Raums, der zwei Räume vor dem neuesten liegt
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 -- weiter unten definiert: Eine Tür fügt einen Raum hinzu, und ein Raum hat eine Tür

-- Was eine Tür tut, wenn ein Spieler sie öffnet
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)

-- Beim Betreten eines Raums: Er wird zum Room des Spielers und zu seinem Checkpoint
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)

-- Ein neuer Raum am Ausgang des neuesten Raums
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)
	-- Ein verschlossener Raum bewahrt seinen Schlüssel im Inneren auf
	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
	-- Den neuesten Raum und KeepRooms Räume dahinter behalten
	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

-- Jeder Spieler: Room auf der Bestenliste und eine Taschenlampe bei jedem neuen Leben
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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Roblox-Spiel: Entkomme der Dunkelheit