JIT
Moving website like you are an idiot
اريد موقع اذا شخص فتجه موقع يتحرك في شاشة مثل you are an idiot

بالتأكيد، يمكنني إنشاء صفحة ويب تحاكي هذا التأثير باستخدام HTML و CSS و JavaScript. سيتحرك عنصر داخل الصفحة بشكل عشوائي.

الآن، عند فتح الصفحة، سترى صندوقًا أزرق يتحرك بشكل عشوائي داخل نافذة المتصفح.

Updated files
v1
لا اقصد نفسه شاشة قوقل تتحرك وليس مربع يتحرك

فهمت قصدك الآن. للأسف، لا يمكن لشيفرة JavaScript الموجودة داخل صفحة ويب أن تتحكم مباشرة في نافذة المتصفح الرئيسية (مثل نافذة جوجل كروم أو فايرفوكس) وتحريكها على شاشة المستخدم. هذا يعتبر إجراءً أمنيًا لمنع المواقع الضارة من التحكم في متصفحك.

التأثير الذي تصفه ("You Are An Idiot") كان يعتمد غالبًا على تقنيات قديمة أو برمجيات خبيثة تستغل ثغرات أمنية لم تعد موجودة في المتصفحات الحديثة، أو أنها كانت تفتح نوافذ منبثقة متعددة وتحاول تحريكها (وهو أمر مقيد بشدة الآن).

الحل البديل:

ما يمكننا فعله هو محاكاة هذا التأثير داخل صفحة الويب نفسها. سننشئ عنصرًا يشبه النافذة الصغيرة ونجعله يتحرك عشوائيًا داخل الصفحة الحالية. هذا سيعطي انطباعًا مشابهًا ولكن ضمن حدود الأمان للمتصفح.

الآن، سترى عنصرًا يشبه نافذة صغيرة يتحرك بشكل عشوائي داخل الصفحة. هذا أقرب ما يمكن تحقيقه لمحاكاة التأثير الذي تريده باستخدام تقنيات الويب القياسية والآمنة.

Updated files
v2
هذه عادي بس تقدر تسويلي سكربت يخلي NPC يلاحق لاعب ولكن يرسم محطط لكي يلحق لاعب وابا انشمين مشي له في ربولكس لاي

بالتأكيد! يمكننا استخدام PathfindingService في Roblox لإنشاء مسار ذكي للشخصية غير اللاعبة (NPC) لتتبع اللاعب، مع تجنب العقبات. سنقوم أيضًا بتشغيل رسوم متحركة للمشي.

المتطلبات:

  1. نموذج NPC: يجب أن يكون لديك نموذج (Model) للشخصية غير اللاعبة في Workspace.
  2. Humanoid و HumanoidRootPart: يجب أن يحتوي النموذج على Humanoid و HumanoidRootPart.
  3. Animator: يجب أن يحتوي الـ Humanoid على Animator. إذا لم يكن موجودًا، أضفه يدويًا في الاستوديو.
  4. Animation: يجب أن يكون لديك Animation للمشي تم تحميلها إلى Roblox وحصلت على معرفها (ID).

السكربت (ضعه داخل نموذج الـ NPC):

lua --[[ Script Name: NPChasePlayerWithPathfinding Description: Makes the NPC chase the nearest player using PathfindingService and plays a walk animation. Location: Place this script directly inside the NPC Model in Workspace. --]]

-- Services local PathfindingService = game:GetService("PathfindingService") local Players = game:GetService("Players") local RunService = game:GetService("RunService")

-- NPC Components local npc = script.Parent local humanoid = npc:WaitForChild("Humanoid") local rootPart = npc:WaitForChild("HumanoidRootPart") local animator = humanoid:WaitForChild("Animator") -- Make sure this exists under Humanoid!

-- Animation Setup local walkAnimation = Instance.new("Animation") -- !!! استبدل هذا بالمعرف الخاص بأنيميشن المشي لديك !!! walkAnimation.AnimationId = "rbxassetid://YOUR_WALK_ANIMATION_ID_HERE" local walkAnimTrack = animator:LoadAnimation(walkAnimation) walkAnimTrack.Looped = true -- اجعل الأنيميشن يتكرر walkAnimTrack.Priority = Enum.AnimationPriority.Action -- أو Movement، حسب الحاجة

-- Configuration local CHASE_DISTANCE = 100 -- أقصى مسافة للمطاردة (بالـ studs) local STOP_DISTANCE = 5 -- المسافة التي يتوقف عندها الـ NPC عن اللاعب local PATH_RECOMPUTE_TIME = 1 -- كم مرة (بالثواني) يتم إعادة حساب المسار

-- Internal Variables local currentTarget = nil local currentPath = nil local currentWaypointIndex = 0 local timeSinceLastPathRecompute = 0

-- Function to find the nearest player within range local function findNearestPlayer() local nearestPlayer = nil local minDistance = CHASE_DISTANCE

for _, player in ipairs(Players:GetPlayers()) do
	local character = player.Character
	if character then
		local playerRoot = character:FindFirstChild("HumanoidRootPart")
		local playerHumanoid = character:FindFirstChild("Humanoid")

		if playerRoot and playerHumanoid and playerHumanoid.Health > 0 then
			local distance = (rootPart.Position - playerRoot.Position).Magnitude
			if distance < minDistance then
				minDistance = distance
				nearestPlayer = character
			end
		end
	end
end
return nearestPlayer

end

-- Function to compute and follow the path local function followPath(targetCharacter) local targetRoot = targetCharacter:FindFirstChild("HumanoidRootPart") if not targetRoot then return end -- Target lost root part

-- Create and compute the path
local path = PathfindingService:CreatePath({
	AgentRadius = 3, -- Adjust based on NPC size
	AgentHeight = 6,
	AgentCanJump = true -- Allow NPC to jump if needed
})

local success, errorMessage = pcall(function()
	path:ComputeAsync(rootPart.Position, targetRoot.Position)
end)

if success and path.Status == Enum.PathStatus.Success then
	currentPath = path
	currentWaypointIndex = 1 -- Start from the first waypoint
	local waypoints = currentPath:GetWaypoints()

	if #waypoints > 0 then
		-- Start walking animation if not already playing
		if not walkAnimTrack.IsPlaying then
			walkAnimTrack:Play()
		end
		-- Move to the first *actual* waypoint (index 2, as 1 is usually the start)
		if #waypoints > 1 then
			currentWaypointIndex = 2
			humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
		else
			-- If only one waypoint (target is very close/reachable directly)
			humanoid:MoveTo(waypoints[1].Position)
		end
	else
		-- No waypoints generated, maybe target is unreachable or too close
		if walkAnimTrack.IsPlaying then
			walkAnimTrack:Stop()
		end
		humanoid:MoveTo(targetRoot.Position) -- Try moving directly
	end
else
	-- Path computation failed
	warn("Pathfinding error for NPC:", npc.Name, errorMessage or path.Status)
	currentPath = nil
	if walkAnimTrack.IsPlaying then
		walkAnimTrack:Stop()
	end
end

end

-- Function to handle reaching a waypoint or path interruption local function onWaypointReached(reached) if reached and currentPath and currentWaypointIndex < #currentPath:GetWaypoints() then currentWaypointIndex = currentWaypointIndex + 1 humanoid:MoveTo(currentPath:GetWaypoints()[currentWaypointIndex].Position) else -- Reached end of path or path was interrupted if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end currentPath = nil -- Clear path so it recalculates end end

-- Connect MoveToFinished event humanoid.MoveToFinished:Connect(onWaypointReached)

-- Main loop using Heartbeat for smooth updates RunService.Heartbeat:Connect(function(deltaTime) timeSinceLastPathRecompute = timeSinceLastPathRecompute + deltaTime

currentTarget = findNearestPlayer()

if currentTarget then
	local targetRoot = currentTarget:FindFirstChild("HumanoidRootPart")
	if not targetRoot then
		-- Target lost root part (maybe died or left)
		currentTarget = nil
		if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
		humanoid:MoveTo(rootPart.Position) -- Stop moving
		currentPath = nil
		return
	end

	local distanceToTarget = (rootPart.Position - targetRoot.Position).Magnitude

	-- Stop if close enough
	if distanceToTarget <= STOP_DISTANCE then
		if walkAnimTrack.IsPlaying then
			walkAnimTrack:Stop()
		end
		humanoid:MoveTo(rootPart.Position) -- Stop moving precisely
		currentPath = nil -- Clear path
		return -- Don't recalculate path if already close
	end

	-- Recalculate path periodically or if no path exists
	if timeSinceLastPathRecompute >= PATH_RECOMPUTE_TIME or not currentPath then
		timeSinceLastPathRecompute = 0
		followPath(currentTarget)
	end

else
	-- No target found
	if walkAnimTrack.IsPlaying then
		walkAnimTrack:Stop()
	end
	-- Optional: Add idle behavior here (e.g., wander)
	if humanoid.MoveDirection.Magnitude > 0 then -- If still moving from previous path
		humanoid:MoveTo(rootPart.Position) -- Stop moving
	end
	currentPath = nil
end

end)

شرح:

  1. الإعداد: يتم الحصول على الخدمات اللازمة، مكونات الـ NPC (Humanoid, RootPart, Animator)، وإعداد الأنيميشن. تأكد من استبدال "rbxassetid://YOUR_WALK_ANIMATION_ID_HERE" بالمعرف الصحيح للأنيميشن الخاص بك.
  2. findNearestPlayer: تبحث هذه الدالة عن أقرب لاعب ضمن مسافة CHASE_DISTANCE وتتأكد من أن اللاعب حي.
  3. followPath:
    • تستخدم PathfindingService:CreatePath() لإنشاء كائن مسار.
    • تستخدم path:ComputeAsync() لحساب المسار من موقع الـ NPC إلى موقع اللاعب.
    • إذا نجح الحساب، يتم الحصول على نقاط الطريق (waypoints).
    • يتم تشغيل أنيميشن المشي.
    • يتم استخدام humanoid:MoveTo() للتحرك نحو نقطة الطريق التالية.
  4. onWaypointReached: يتم استدعاء هذه الدالة عندما يصل الـ NPC إلى نقطة طريق أو عندما يتم مقاطعة الحركة. إذا كان هناك المزيد من نقاط الطريق، فإنه يتحرك إلى النقطة التالية؛ وإلا فإنه يوقف الأنيميشن ويمسح المسار الحالي.
  5. الحلقة الرئيسية (RunService.Heartbeat):
    • تعمل هذه الحلقة باستمرار.
    • تبحث عن أقرب لاعب.
    • إذا تم العثور على لاعب وهو بعيد بما فيه الكفاية:
      • يتم إعادة حساب المسار كل PATH_RECOMPUTE_TIME ثانية أو إذا لم يكن هناك مسار حالي. هذا يضمن أن الـ NPC يتكيف مع حركة اللاعب.
    • إذا كان اللاعب قريبًا جدًا (STOP_DISTANCE):
      • يتوقف الـ NPC ويوقف الأنيميشن.
    • إذا لم يتم العثور على لاعب:
      • يتوقف الـ NPC ويوقف الأنيميشن.

كيفية الاستخدام:

  1. أنشئ نموذج NPC الخاص بك وتأكد من وجود Humanoid, HumanoidRootPart, و Animator.
  2. أنشئ Animation للمشي وقم بتحميلها إلى Roblox. انسخ معرفها (Asset ID).
  3. أنشئ Script جديدًا داخل نموذج الـ NPC.
  4. الصق الكود أعلاه في السكربت.
  5. هام: استبدل YOUR_WALK_ANIMATION_ID_HERE في السكربت بمعرف أنيميشن المشي الخاص بك.
  6. قم بتشغيل اللعبة، ويجب أن يبدأ الـ NPC في مطاردة أقرب لاعب باستخدام المسار المحسوب.*_
اريد انشمين يكون ID

حسنًا، سأقوم بتضمين معرف (ID) لأنيميشن مشي شائع من مكتبة Roblox كمثال في السكربت.

تذكر: هذا مجرد مثال. للحصول على أفضل نتيجة، يجب عليك استخدام معرف الأنيميشن الخاص بك الذي قمت بإنشائه أو العثور عليه ويتناسب مع شكل الـ NPC الخاص بك.

كيف تجد أو تحصل على معرف أنيميشن:

  1. إنشاء خاص بك: استخدم محرر الأنيميشن في Roblox Studio لإنشاء أنيميشن مشي مخصص لنموذج الـ NPC الخاص بك. بعد الحفظ والنشر إلى Roblox، ستحصل على معرف (Asset ID).
  2. استخدام مكتبة Roblox: ابحث في Toolbox داخل Roblox Studio عن "Walk Animation" أو ما شابه. اختر واحدة، أضفها إلى لعبتك (عادةً تحت الـ NPC أو في مكان مثل ReplicatedStorage)، وانسخ AnimationId من خصائصها.

السكربت مع معرف أنيميشن كمثال:

lua --[[ Script Name: NPChasePlayerWithPathfinding Description: Makes the NPC chase the nearest player using PathfindingService and plays a walk animation. Location: Place this script directly inside the NPC Model in Workspace. --]]

-- Services local PathfindingService = game:GetService("PathfindingService") local Players = game:GetService("Players") local RunService = game:GetService("RunService")

-- NPC Components local npc = script.Parent local humanoid = npc:WaitForChild("Humanoid") local rootPart = npc:WaitForChild("HumanoidRootPart") local animator = humanoid:WaitForChild("Animator") -- Make sure this exists under Humanoid!

-- Animation Setup local walkAnimation = Instance.new("Animation")

-- !!! مثال لمعرف أنيميشن مشي من Roblox - استبدله بالمعرف الخاص بك إذا أردت !!! walkAnimation.AnimationId = "rbxassetid://180426354" -- (R15 Walk Animation)

local walkAnimTrack = animator:LoadAnimation(walkAnimation) walkAnimTrack.Looped = true -- اجعل الأنيميشن يتكرر walkAnimTrack.Priority = Enum.AnimationPriority.Action -- أو Movement، حسب الحاجة

-- Configuration local CHASE_DISTANCE = 100 -- أقصى مسافة للمطاردة (بالـ studs) local STOP_DISTANCE = 5 -- المسافة التي يتوقف عندها الـ NPC عن اللاعب local PATH_RECOMPUTE_TIME = 1 -- كم مرة (بالثواني) يتم إعادة حساب المسار

-- Internal Variables local currentTarget = nil local currentPath = nil local currentWaypointIndex = 0 local timeSinceLastPathRecompute = 0

-- Function to find the nearest player within range local function findNearestPlayer() local nearestPlayer = nil local minDistance = CHASE_DISTANCE

for _, player in ipairs(Players:GetPlayers()) do
	local character = player.Character
	if character then
		local playerRoot = character:FindFirstChild("HumanoidRootPart")
		local playerHumanoid = character:FindFirstChild("Humanoid")

		if playerRoot and playerHumanoid and playerHumanoid.Health > 0 then
			local distance = (rootPart.Position - playerRoot.Position).Magnitude
			if distance < minDistance then
				minDistance = distance
				nearestPlayer = character
			end
		end
	end
end
return nearestPlayer

end

-- Function to compute and follow the path local function followPath(targetCharacter) local targetRoot = targetCharacter:FindFirstChild("HumanoidRootPart") if not targetRoot then return end -- Target lost root part

-- Create and compute the path
local path = PathfindingService:CreatePath({
	AgentRadius = 3, -- Adjust based on NPC size
	AgentHeight = 6,
	AgentCanJump = true -- Allow NPC to jump if needed
})

local success, errorMessage = pcall(function()
	path:ComputeAsync(rootPart.Position, targetRoot.Position)
end)

if success and path.Status == Enum.PathStatus.Success then
	currentPath = path
	currentWaypointIndex = 1 -- Start from the first waypoint
	local waypoints = currentPath:GetWaypoints()

	if #waypoints > 0 then
		-- Start walking animation if not already playing
		if not walkAnimTrack.IsPlaying then
			walkAnimTrack:Play()
		end
		-- Move to the first *actual* waypoint (index 2, as 1 is usually the start)
		if #waypoints > 1 then
			currentWaypointIndex = 2
			humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
		else
			-- If only one waypoint (target is very close/reachable directly)
			humanoid:MoveTo(waypoints[1].Position)
		end
	else
		-- No waypoints generated, maybe target is unreachable or too close
		if walkAnimTrack.IsPlaying then
			walkAnimTrack:Stop()
		end
		humanoid:MoveTo(targetRoot.Position) -- Try moving directly
	end
else
	-- Path computation failed
	warn("Pathfinding error for NPC:", npc.Name, errorMessage or path.Status)
	currentPath = nil
	if walkAnimTrack.IsPlaying then
		walkAnimTrack:Stop()
	end
end

end

-- Function to handle reaching a waypoint or path interruption local function onWaypointReached(reached) if reached and currentPath and currentWaypointIndex < #currentPath:GetWaypoints() then currentWaypointIndex = currentWaypointIndex + 1 humanoid:MoveTo(currentPath:GetWaypoints()[currentWaypointIndex].Position) else -- Reached end of path or path was interrupted if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end currentPath = nil -- Clear path so it recalculates end end

-- Connect MoveToFinished event humanoid.MoveToFinished:Connect(onWaypointReached)

-- Main loop using Heartbeat for smooth updates RunService.Heartbeat:Connect(function(deltaTime) timeSinceLastPathRecompute = timeSinceLastPathRecompute + deltaTime

currentTarget = findNearestPlayer()

if currentTarget then
	local targetRoot = currentTarget:FindFirstChild("HumanoidRootPart")
	if not targetRoot then
		-- Target lost root part (maybe died or left)
		currentTarget = nil
		if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
		humanoid:MoveTo(rootPart.Position) -- Stop moving
		currentPath = nil
		return
	end

	local distanceToTarget = (rootPart.Position - targetRoot.Position).Magnitude

	-- Stop if close enough
	if distanceToTarget <= STOP_DISTANCE then
		if walkAnimTrack.IsPlaying then
			walkAnimTrack:Stop()
		end
		humanoid:MoveTo(rootPart.Position) -- Stop moving precisely
		currentPath = nil -- Clear path
		return -- Don't recalculate path if already close
	end

	-- Recalculate path periodically or if no path exists
	if timeSinceLastPathRecompute >= PATH_RECOMPUTE_TIME or not currentPath then
		timeSinceLastPathRecompute = 0
		followPath(currentTarget)
	end

else
	-- No target found
	if walkAnimTrack.IsPlaying then
		walkAnimTrack:Stop()
	end
	-- Optional: Add idle behavior here (e.g., wander)
	if humanoid.MoveDirection.Magnitude > 0 then -- If still moving from previous path
		humanoid:MoveTo(rootPart.Position) -- Stop moving
	end
	currentPath = nil
end

end)

التغيير الرئيسي:

تم تغيير السطر:

walkAnimation.AnimationId = "rbxassetid://YOUR_WALK_ANIMATION_ID_HERE"

إلى:

walkAnimation.AnimationId = "rbxassetid://180426354" -- (R15 Walk Animation)

الآن السكربت جاهز للاستخدام مع أنيميشن المشي الافتراضي لـ R15. إذا كان الـ NPC الخاص بك يستخدم R6 أو لديك أنيميشن أفضل، فقط استبدل الرقم 180426354 بالمعرف الصحيح._

اكتبلي سكربت بدون تعملات حتا نص لكي انسخه

lua local PathfindingService = game:GetService("PathfindingService") local Players = game:GetService("Players") local RunService = game:GetService("RunService")

local npc = script.Parent local humanoid = npc:WaitForChild("Humanoid") local rootPart = npc:WaitForChild("HumanoidRootPart") local animator = humanoid:WaitForChild("Animator")

local walkAnimation = Instance.new("Animation") walkAnimation.AnimationId = "rbxassetid://180426354"

local walkAnimTrack = animator:LoadAnimation(walkAnimation) walkAnimTrack.Looped = true walkAnimTrack.Priority = Enum.AnimationPriority.Action

local CHASE_DISTANCE = 100 local STOP_DISTANCE = 5 local PATH_RECOMPUTE_TIME = 1

local currentTarget = nil local currentPath = nil local currentWaypointIndex = 0 local timeSinceLastPathRecompute = 0

local function findNearestPlayer() local nearestPlayer = nil local minDistance = CHASE_DISTANCE for _, player in ipairs(Players:GetPlayers()) do local character = player.Character if character then local playerRoot = character:FindFirstChild("HumanoidRootPart") local playerHumanoid = character:FindFirstChild("Humanoid") if playerRoot and playerHumanoid and playerHumanoid.Health > 0 then local distance = (rootPart.Position - playerRoot.Position).Magnitude if distance < minDistance then minDistance = distance nearestPlayer = character end end end end return nearestPlayer end

local function followPath(targetCharacter) local targetRoot = targetCharacter:FindFirstChild("HumanoidRootPart") if not targetRoot then return end

local path = PathfindingService:CreatePath({
	AgentRadius = 3,
	AgentHeight = 6,
	AgentCanJump = true
})

local success, errorMessage = pcall(function()
	path:ComputeAsync(rootPart.Position, targetRoot.Position)
end)

if success and path.Status == Enum.PathStatus.Success then
	currentPath = path
	currentWaypointIndex = 1
	local waypoints = currentPath:GetWaypoints()
	if #waypoints > 0 then
		if not walkAnimTrack.IsPlaying then
			walkAnimTrack:Play()
		end
		if #waypoints > 1 then
			currentWaypointIndex = 2
			humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
		else
			humanoid:MoveTo(waypoints[1].Position)
		end
	else
		if walkAnimTrack.IsPlaying then
			walkAnimTrack:Stop()
		end
		humanoid:MoveTo(targetRoot.Position)
	end
else
	currentPath = nil
	if walkAnimTrack.IsPlaying then
		walkAnimTrack:Stop()
	end
end

end

local function onWaypointReached(reached) if reached and currentPath and currentWaypointIndex < #currentPath:GetWaypoints() then currentWaypointIndex = currentWaypointIndex + 1 humanoid:MoveTo(currentPath:GetWaypoints()[currentWaypointIndex].Position) else if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end currentPath = nil end end

humanoid.MoveToFinished:Connect(onWaypointReached)

RunService.Heartbeat:Connect(function(deltaTime) timeSinceLastPathRecompute = timeSinceLastPathRecompute + deltaTime currentTarget = findNearestPlayer()

if currentTarget then
	local targetRoot = currentTarget:FindFirstChild("HumanoidRootPart")
	if not targetRoot then
		currentTarget = nil
		if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
		humanoid:MoveTo(rootPart.Position)
		currentPath = nil
		return
	end

	local distanceToTarget = (rootPart.Position - targetRoot.Position).Magnitude

	if distanceToTarget <= STOP_DISTANCE then
		if walkAnimTrack.IsPlaying then
			walkAnimTrack:Stop()
		end
		humanoid:MoveTo(rootPart.Position)
		currentPath = nil
		return
	end

	if timeSinceLastPathRecompute >= PATH_RECOMPUTE_TIME or not currentPath then
		timeSinceLastPathRecompute = 0
		followPath(currentTarget)
	end
else
	if walkAnimTrack.IsPlaying then
		walkAnimTrack:Stop()
	end
	if humanoid.MoveDirection.Magnitude > 0 then
		humanoid:MoveTo(rootPart.Position)
	end
	currentPath = nil
end

end) _

رائع اين اضع سكربت

ضع السكربت مباشرة داخل نموذج (Model) الشخصية غير اللاعبة (NPC) التي تريدها أن تلاحق اللاعب.

خطوات:

  1. افتح Roblox Studio وافتح مكان لعبتك (Place).
  2. في نافذة Explorer (المستكشف)، ابحث عن النموذج (Model) الخاص بالـ NPC. (عادة ما يكون في Workspace).
  3. انقر بزر الماوس الأيمن على اسم النموذج (Model) الخاص بالـ NPC.
  4. اختر Insert Object (إدراج كائن).
  5. اختر Script من القائمة.
  6. سيظهر سكربت جديد داخل النموذج. افتحه.
  7. احذف أي كود موجود بداخله (مثل print("Hello world!")).
  8. الصق الكود الذي أعطيتك إياه بالكامل داخل هذا السكربت.
  9. أغلق نافذة السكربت.

الآن، عندما تبدأ اللعبة، سيتم تشغيل السكربت تلقائيًا وسيبدأ الـ NPC في البحث عن اللاعبين وملاحقتهم.

سكربت لديه مشكلة انه يتأخر بشكل ملحوظ وايضا اذا لف لاعب دوائر سركبت لن يعمل اريد يحلق لاعب بدون تخطيط مسار لكن اذا كان امام جادر يرسم مخطط لي بعد عن جادر

فهمت تمامًا. تريد سلوكًا أكثر مباشرة واستجابة، حيث يتحرك الـ NPC مباشرة نحو اللاعب طالما أن الطريق واضح، ولا يستخدم PathfindingService إلا عندما يصطدم بعائق أو يكون الطريق مسدودًا. هذا سيقلل من التأخير الملحوظ.

سنستخدم Raycasting (إطلاق الشعاع) للتحقق مما إذا كان هناك خط رؤية مباشر بين الـ NPC واللاعب.

السكربت المعدل (ضعه داخل نموذج الـ NPC):

lua --[[ Script Name: NPCDirectChaseWithObstacleAvoidance Description: Makes the NPC chase the nearest player directly when possible, using PathfindingService only when the direct path is blocked. Location: Place this script directly inside the NPC Model in Workspace. --]]

-- Services local PathfindingService = game:GetService("PathfindingService") local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Workspace = game:GetService("Workspace") -- Needed for Raycasting

-- NPC Components local npc = script.Parent local humanoid = npc:WaitForChild("Humanoid") local rootPart = npc:WaitForChild("HumanoidRootPart") local animator = humanoid:WaitForChild("Animator")

-- Animation Setup local walkAnimation = Instance.new("Animation") walkAnimation.AnimationId = "rbxassetid://180426354" -- Example R15 Walk ID local walkAnimTrack = animator:LoadAnimation(walkAnimation) walkAnimTrack.Looped = true walkAnimTrack.Priority = Enum.AnimationPriority.Action

-- Configuration local CHASE_DISTANCE = 100 -- Max distance to start chasing local STOP_DISTANCE = 6 -- Distance to stop at (slightly larger for direct move) local PATH_RECOMPUTE_TIME = 1.5 -- How often to re-check/re-calculate path if pathfinding local RAYCAST_DISTANCE_BUFFER = 5 -- How much further than the player to cast the ray

-- Raycast Parameters (to ignore the NPC itself) local raycastParams = RaycastParams.new() raycastParams.FilterType = Enum.RaycastFilterType.Exclude raycastParams.FilterDescendantsInstances = {npc} raycastParams.IgnoreWater = true

-- Internal Variables local currentTarget = nil local currentPath = nil local currentWaypointIndex = 0 local timeSinceLastPathRecompute = 0 local isPathfinding = false -- Track if currently using PathfindingService

-- Function to find the nearest player (same as before) local function findNearestPlayer() local nearestPlayer = nil local minDistance = CHASE_DISTANCE for _, player in ipairs(Players:GetPlayers()) do local character = player.Character if character then local playerRoot = character:FindFirstChild("HumanoidRootPart") local playerHumanoid = character:FindFirstChild("Humanoid") if playerRoot and playerHumanoid and playerHumanoid.Health > 0 then local distance = (rootPart.Position - playerRoot.Position).Magnitude if distance < minDistance then minDistance = distance nearestPlayer = character end end end end return nearestPlayer end

-- Function to compute and start following a path using PathfindingService local function computeAndFollowPath(targetCharacter) local targetRoot = targetCharacter:FindFirstChild("HumanoidRootPart") if not targetRoot then return end

-- Create and compute the path
local path = PathfindingService:CreatePath({
	AgentRadius = 3, AgentHeight = 6, AgentCanJump = true
})

local success, errorMessage = pcall(function()
	path:ComputeAsync(rootPart.Position, targetRoot.Position)
end)

if success and path.Status == Enum.PathStatus.Success then
	currentPath = path
	local waypoints = currentPath:GetWaypoints()
	if #waypoints > 0 then
		isPathfinding = true -- Enter pathfinding mode
		currentWaypointIndex = 1 -- Reset waypoint index
		if not walkAnimTrack.IsPlaying then walkAnimTrack:Play() end -- Ensure animation plays

		-- Move to the first *actual* waypoint (index 2) if available
		if #waypoints > 1 then
			currentWaypointIndex = 2
			humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
		else
			-- Only one waypoint (target is very close/reachable directly via path)
			humanoid:MoveTo(waypoints[1].Position)
		end
	else
		-- Path has no waypoints (target likely very close/unreachable?)
		isPathfinding = false -- Exit pathfinding mode as it failed
		currentPath = nil
		if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
		humanoid:MoveTo(rootPart.Position) -- Stop if path is empty
	end
else
	-- Path computation failed
	warn("Pathfinding error for NPC:", npc.Name, errorMessage or path.Status)
	isPathfinding = false
	currentPath = nil
	if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
	humanoid:MoveTo(rootPart.Position) -- Stop if path fails
end

end

-- Function to handle reaching a waypoint or path interruption during Pathfinding local function onWaypointReached(reached) -- Only process if we are currently in pathfinding mode and have a valid path if isPathfinding and currentPath then if reached and currentWaypointIndex < #currentPath:GetWaypoints() then -- Move to the next waypoint currentWaypointIndex = currentWaypointIndex + 1 humanoid:MoveTo(currentPath:GetWaypoints()[currentWaypointIndex].Position) else -- Reached the end of the path OR path was interrupted (reached == false) isPathfinding = false currentPath = nil -- Don't stop animation/movement here, let the main loop decide the next action -- based on line-of-sight check in the next frame. end end end

-- Connect MoveToFinished event humanoid.MoveToFinished:Connect(onWaypointReached)

-- Main loop using Heartbeat for smooth updates RunService.Heartbeat:Connect(function(deltaTime) timeSinceLastPathRecompute = timeSinceLastPathRecompute + deltaTime currentTarget = findNearestPlayer()

if currentTarget then
	local targetRoot = currentTarget:FindFirstChild("HumanoidRootPart")
	local targetHumanoid = currentTarget:FindFirstChild("Humanoid") -- Check if target is alive

	-- Validate target
	if not targetRoot or not targetHumanoid or targetHumanoid.Health <= 0 then
		currentTarget = nil -- Target lost or died
		-- Fall-through to the 'else' block below to stop NPC
	else
		-- Target is valid
		local distanceToTarget = (rootPart.Position - targetRoot.Position).Magnitude

		-- Stop if close enough
		if distanceToTarget <= STOP_DISTANCE then
			isPathfinding = false
			currentPath = nil
			if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
			humanoid:MoveTo(rootPart.Position) -- Stop precisely
			return -- Exit Heartbeat iteration early
		end

		-- Check Line of Sight using Raycast
		local origin = rootPart.Position
		local direction = (targetRoot.Position - origin)
		-- Cast slightly further than the actual distance to ensure we hit the player if path is clear
		local rayDistance = direction.Magnitude + RAYCAST_DISTANCE_BUFFER
		local raycastResult = Workspace:Raycast(origin, direction.Unit * rayDistance, raycastParams)

		local directPathClear = false
		if raycastResult then
			-- Check if the ray hit the target character or something else
			if raycastResult.Instance:IsDescendantOf(currentTarget) then
				directPathClear = true -- Hit the target player, path is clear!
			else
				directPathClear = false -- Hit an obstacle
			end
		else
			-- Ray hit nothing within the cast distance.
			-- This implies a clear path *if* the target is actually within that distance.
			if distanceToTarget < rayDistance then
				directPathClear = true
			end
		end

		-- === Movement Logic ===
		if directPathClear then
			-- DIRECT CHASE MODE
			if isPathfinding then
				-- If we were pathfinding, stop it now
				isPathfinding = false
				currentPath = nil
				-- Don't stop MoveTo immediately, the new MoveTo will override
			end
			humanoid:MoveTo(targetRoot.Position)
			if not walkAnimTrack.IsPlaying then
				walkAnimTrack:Play()
			end
			timeSinceLastPathRecompute = 0 -- Reset path timer as we are moving directly

		else
			-- OBSTACLE DETECTED - PATHFINDING MODE
			-- Recalculate path if not currently pathfinding, or if it's time to recompute
			if not isPathfinding or timeSinceLastPathRecompute >= PATH_RECOMPUTE_TIME then
				timeSinceLastPathRecompute = 0
				computeAndFollowPath(currentTarget)
			elseif isPathfinding and not walkAnimTrack.IsPlaying and humanoid.MoveDirection.Magnitude > 0.1 then
				-- If already pathfinding but animation stopped (e.g. after brief stop), restart it
				walkAnimTrack:Play()
			end
		end

		return -- Exit Heartbeat iteration after processing target
	end
end

-- === No Target Found or Target Invalidated ===
isPathfinding = false
currentPath = nil
if walkAnimTrack.IsPlaying then
	walkAnimTrack:Stop()
end
-- Stop moving only if currently moving
if humanoid.MoveDirection.Magnitude > 0.1 then
	humanoid:MoveTo(rootPart.Position)
end

end)

التغييرات الرئيسية:

  1. Raycasting:
    • نستخدم Workspace:Raycast() في كل دورة Heartbeat للتحقق من وجود عوائق بين الـ NPC واللاعب.
    • raycastParams يتم إعداده لتجاهل الـ NPC نفسه.
  2. منطق الحركة الثنائي:
    • إذا كان directPathClear صحيحًا (لا يوجد عائق):
      • يتم إيقاف أي عملية Pathfinding جارية (isPathfinding = false, currentPath = nil).
      • يتم استخدام humanoid:MoveTo(targetRoot.Position) للتحرك مباشرة نحو اللاعب.
      • يتم تشغيل أنيميشن المشي.
    • إذا كان directPathClear خاطئًا (يوجد عائق):
      • يتم الدخول في وضع Pathfinding.
      • يتم استدعاء computeAndFollowPath() لحساب المسار وتتبعه (فقط إذا لم يكن يتبع مسارًا بالفعل أو إذا حان وقت إعادة الحساب).
  3. إدارة الحالة (isPathfinding): تم إضافة متغير isPathfinding لتتبع ما إذا كان الـ NPC يستخدم حاليًا PathfindingService أم يتحرك مباشرة. هذا يساعد في الانتقال السلس بين الوضعين.
  4. تحسين onWaypointReached: تم تبسيطها قليلاً، حيث أن القرار الرئيسي بالتبديل بين الأوضاع يحدث الآن في حلقة Heartbeat بناءً على الـ Raycast.
  5. التحقق من صحة الهدف: تم إضافة تحقق إضافي للتأكد من أن اللاعب المستهدف لا يزال موجودًا وحيًا قبل محاولة التحرك نحوه.

كيف يعمل الآن:

  • سيحاول الـ NPC دائمًا التحرك مباشرة نحو اللاعب.
  • إذا اكتشف شعاع (Raycast) وجود جدار أو أي عائق آخر بينه وبين اللاعب، فسيقوم بتشغيل PathfindingService لحساب طريق حول العائق.
  • بمجرد أن يصبح الطريق المباشر واضحًا مرة أخرى (يكتشف الـ Raycast اللاعب مباشرة)، سيعود الـ NPC إلى التحرك المباشر الأسرع.
  • هذا يقلل بشكل كبير من التأخير عندما يكون الطريق مفتوحًا ويجعل الـ NPC أكثر استجابة لحركات اللاعب في المساحات المفتوحة._
هل يمكنك كتاب سكربت في ناذة تالية

lua --[[ Script Name: NPCDirectChaseWithObstacleAvoidance Description: Makes the NPC chase the nearest player directly when possible, using PathfindingService only when the direct path is blocked. Location: Place this script directly inside the NPC Model in Workspace. --]]

-- Services local PathfindingService = game:GetService("PathfindingService") local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Workspace = game:GetService("Workspace") -- Needed for Raycasting

-- NPC Components local npc = script.Parent local humanoid = npc:WaitForChild("Humanoid") local rootPart = npc:WaitForChild("HumanoidRootPart") local animator = humanoid:WaitForChild("Animator")

-- Animation Setup local walkAnimation = Instance.new("Animation") walkAnimation.AnimationId = "rbxassetid://180426354" -- Example R15 Walk ID local walkAnimTrack = animator:LoadAnimation(walkAnimation) walkAnimTrack.Looped = true walkAnimTrack.Priority = Enum.AnimationPriority.Action

-- Configuration local CHASE_DISTANCE = 100 -- Max distance to start chasing local STOP_DISTANCE = 6 -- Distance to stop at (slightly larger for direct move) local PATH_RECOMPUTE_TIME = 1.5 -- How often to re-check/re-calculate path if pathfinding local RAYCAST_DISTANCE_BUFFER = 5 -- How much further than the player to cast the ray

-- Raycast Parameters (to ignore the NPC itself) local raycastParams = RaycastParams.new() raycastParams.FilterType = Enum.RaycastFilterType.Exclude raycastParams.FilterDescendantsInstances = {npc} raycastParams.IgnoreWater = true

-- Internal Variables local currentTarget = nil local currentPath = nil local currentWaypointIndex = 0 local timeSinceLastPathRecompute = 0 local isPathfinding = false -- Track if currently using PathfindingService

-- Function to find the nearest player (same as before) local function findNearestPlayer() local nearestPlayer = nil local minDistance = CHASE_DISTANCE for _, player in ipairs(Players:GetPlayers()) do local character = player.Character if character then local playerRoot = character:FindFirstChild("HumanoidRootPart") local playerHumanoid = character:FindFirstChild("Humanoid") if playerRoot and playerHumanoid and playerHumanoid.Health > 0 then local distance = (rootPart.Position - playerRoot.Position).Magnitude if distance < minDistance then minDistance = distance nearestPlayer = character end end end end return nearestPlayer end

-- Function to compute and start following a path using PathfindingService local function computeAndFollowPath(targetCharacter) local targetRoot = targetCharacter:FindFirstChild("HumanoidRootPart") if not targetRoot then return end

-- Create and compute the path
local path = PathfindingService:CreatePath({
	AgentRadius = 3, AgentHeight = 6, AgentCanJump = true
})

local success, errorMessage = pcall(function()
	path:ComputeAsync(rootPart.Position, targetRoot.Position)
end)

if success and path.Status == Enum.PathStatus.Success then
	currentPath = path
	local waypoints = currentPath:GetWaypoints()
	if #waypoints > 0 then
		isPathfinding = true -- Enter pathfinding mode
		currentWaypointIndex = 1 -- Reset waypoint index
		if not walkAnimTrack.IsPlaying then walkAnimTrack:Play() end -- Ensure animation plays

		-- Move to the first *actual* waypoint (index 2) if available
		if #waypoints > 1 then
			currentWaypointIndex = 2
			humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
		else
			-- Only one waypoint (target is very close/reachable directly via path)
			humanoid:MoveTo(waypoints[1].Position)
		end
	else
		-- Path has no waypoints (target likely very close/unreachable?)
		isPathfinding = false -- Exit pathfinding mode as it failed
		currentPath = nil
		if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
		humanoid:MoveTo(rootPart.Position) -- Stop if path is empty
	end
else
	-- Path computation failed
	warn("Pathfinding error for NPC:", npc.Name, errorMessage or path.Status)
	isPathfinding = false
	currentPath = nil
	if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
	humanoid:MoveTo(rootPart.Position) -- Stop if path fails
end

end

-- Function to handle reaching a waypoint or path interruption during Pathfinding local function onWaypointReached(reached) -- Only process if we are currently in pathfinding mode and have a valid path if isPathfinding and currentPath then if reached and currentWaypointIndex < #currentPath:GetWaypoints() then -- Move to the next waypoint currentWaypointIndex = currentWaypointIndex + 1 humanoid:MoveTo(currentPath:GetWaypoints()[currentWaypointIndex].Position) else -- Reached the end of the path OR path was interrupted (reached == false) isPathfinding = false currentPath = nil -- Don't stop animation/movement here, let the main loop decide the next action -- based on line-of-sight check in the next frame. end end end

-- Connect MoveToFinished event humanoid.MoveToFinished:Connect(onWaypointReached)

-- Main loop using Heartbeat for smooth updates RunService.Heartbeat:Connect(function(deltaTime) timeSinceLastPathRecompute = timeSinceLastPathRecompute + deltaTime currentTarget = findNearestPlayer()

if currentTarget then
	local targetRoot = currentTarget:FindFirstChild("HumanoidRootPart")
	local targetHumanoid = currentTarget:FindFirstChild("Humanoid") -- Check if target is alive

	-- Validate target
	if not targetRoot or not targetHumanoid or targetHumanoid.Health <= 0 then
		currentTarget = nil -- Target lost or died
		-- Fall-through to the 'else' block below to stop NPC
	else
		-- Target is valid
		local distanceToTarget = (rootPart.Position - targetRoot.Position).Magnitude

		-- Stop if close enough
		if distanceToTarget <= STOP_DISTANCE then
			isPathfinding = false
			currentPath = nil
			if walkAnimTrack.IsPlaying then walkAnimTrack:Stop() end
			humanoid:MoveTo(rootPart.Position) -- Stop precisely
			return -- Exit Heartbeat iteration early
		end

		-- Check Line of Sight using Raycast
		local origin = rootPart.Position
		local direction = (targetRoot.Position - origin)
		-- Cast slightly further than the actual distance to ensure we hit the player if path is clear
		local rayDistance = direction.Magnitude + RAYCAST_DISTANCE_BUFFER
		local raycastResult = Workspace:Raycast(origin, direction.Unit * rayDistance, raycastParams)

		local directPathClear = false
		if raycastResult then
			-- Check if the ray hit the target character or something else
			if raycastResult.Instance:IsDescendantOf(currentTarget) then
				directPathClear = true -- Hit the target player, path is clear!
			else
				directPathClear = false -- Hit an obstacle
			end
		else
			-- Ray hit nothing within the cast distance.
			-- This implies a clear path *if* the target is actually within that distance.
			if distanceToTarget < rayDistance then
				directPathClear = true
			end
		end

		-- === Movement Logic ===
		if directPathClear then
			-- DIRECT CHASE MODE
			if isPathfinding then
				-- If we were pathfinding, stop it now
				isPathfinding = false
				currentPath = nil
				-- Don't stop MoveTo immediately, the new MoveTo will override
			end
			humanoid:MoveTo(targetRoot.Position)
			if not walkAnimTrack.IsPlaying then
				walkAnimTrack:Play()
			end
			timeSinceLastPathRecompute = 0 -- Reset path timer as we are moving directly

		else
			-- OBSTACLE DETECTED - PATHFINDING MODE
			-- Recalculate path if not currently pathfinding, or if it's time to recompute
			if not isPathfinding or timeSinceLastPathRecompute >= PATH_RECOMPUTE_TIME then
				timeSinceLastPathRecompute = 0
				computeAndFollowPath(currentTarget)
			elseif isPathfinding and not walkAnimTrack.IsPlaying and humanoid.MoveDirection.Magnitude > 0.1 then
				-- If already pathfinding but animation stopped (e.g. after brief stop), restart it
				walkAnimTrack:Play()
			end
		end

		return -- Exit Heartbeat iteration after processing target
	end
end

-- === No Target Found or Target Invalidated ===
isPathfinding = false
currentPath = nil
if walkAnimTrack.IsPlaying then
	walkAnimTrack:Stop()
end
-- Stop moving only if currently moving
if humanoid.MoveDirection.Magnitude > 0.1 then
	humanoid:MoveTo(rootPart.Position)
end

end) *_