Roblox'un standart Humanoid kontrolcüsü basit oyunlar için uygun olsa da, tempolu aksiyon ve parkur oyunlarında takılmalara ve platformlardan fırlama hatalarına yol açar.
Özel bir fizik kontrolcüsü inşa ederek hareket üzerinde mutlak hakimiyet sağlayabilirsiniz. VectorForce ile karakteri yerden hafifçe yüksekte tutan bir yay sistemi ve zemin eğimine uyum sağlayan raycast projeksiyonuyla AAA kalitesinde akıcı bir oynanış elde edilir.
1. Standart Humanoid Sisteminin Temel Kısıtlamaları
Aksiyon oyunlarında özel kontrolcüye neden ihtiyaç duyulur:
- Katı Durum Makinesi: Önceden tanımlı geçiş gecikmeleri hızlı yön değiştirmeyi zorlaştırır.
- Hareketli Nesnelerden Fırlama: Araçların üzerinde dururken karakterin aniden harita dışına savrulması.
- Basamaklarda Titreme: Yükseklik değişimlerinde kamerayı sarsan ani zıplamalar.
- Tam Kontrol: Heartbeat döngüsünde doğrudan matematiksel hız hesaplaması.
2. Asılı Kapsül ve VectorForce Yaylı Süspansiyon
Zemine takılmadan akıcı hareket etmek için temasız süzülme prensibi:
- Sanal Yaylı Askı: Aşağı doğru fırlatılan raycast ile ağırlığı dengede tutan yay kuvveti.
- Sürtünmesiz Dış Kapsül: Kenarlara ve çatlaklara takılmayı önleyen pürüzsüz dış yüzey.
- AlignOrientation ile Dik Duruş: Karakterin devrilmesini engelleyip sadece yatay dönüşe izin verme.
- LinearVelocity ile Anında Tepki: Hızlanma gecikmesi olmadan tuşa basıldığı an istenen hıza ulaşma.
--!strict
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local CustomController = {}
local player = Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart") :: BasePart
local TARGET_HEIGHT = 4.2
local SPRING_STIFFNESS = 1800
local SPRING_DAMPING = 160
local WALK_SPEED = 24
local RAY_PARAMS = RaycastParams.new()
RAY_PARAMS.FilterType = RaycastFilterType.Exclude
local linearVelocity = Instance.new("LinearVelocity")
linearVelocity.MaxForce = 40000
linearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
local attachment = Instance.new("Attachment")
attachment.Parent = hrp
linearVelocity.Attachment0 = attachment
linearVelocity.Parent = hrp
function CustomController.Update(dt: number)
local moveDir = Vector3.zero
local cam = Workspace.CurrentCamera
if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveDir += cam.CFrame.LookVector end
if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveDir -= cam.CFrame.LookVector end
if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveDir += cam.CFrame.RightVector end
if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveDir -= cam.CFrame.RightVector end
moveDir = Vector3.new(moveDir.X, 0, moveDir.Z)
if moveDir.Magnitude > 0.01 then moveDir = moveDir.Unit end
RAY_PARAMS.FilterDescendantsInstances = { char }
local ray = Workspace:Raycast(hrp.Position, Vector3.new(0, -TARGET_HEIGHT * 1.5, 0), RAY_PARAMS)
local vForce = 0
local targetVel = moveDir * WALK_SPEED
if ray and ray.Instance and ray.Instance.CanCollide then
local dist = (hrp.Position - ray.Position).Magnitude
targetVel = moveDir - (ray.Normal * moveDir:Dot(ray.Normal))
targetVel = targetVel.Unit * WALK_SPEED
local err = TARGET_HEIGHT - dist
vForce = (err * SPRING_STIFFNESS) - (hrp.AssemblyLinearVelocity.Y * SPRING_DAMPING)
end
linearVelocity.VectorVelocity = Vector3.new(targetVel.X, targetVel.Y + (vForce * dt), targetVel.Z)
end
RunService.Heartbeat:Connect(CustomController.Update)
return CustomController
3. Raycast Zemin Tespiti ve Yüzey Vektör Projeksiyonu
Yokuş çıkarken yavaşlamayı ve inişte kontrolü kaybetmeyi önleme:
- Zemin Normali Tespiti: RaycastResult üzerinden zeminin eğim açısını okuma.
- Vektör Projeksiyonu: Karakterin hareket yönünü zemin eğimine paralel olarak yeniden yönlendirme.
- Maksimum Tırmanma Açısı: 45 dereceden dik yamaçlarda kaymayı zorunlu kılma.
- Uçurum Algılama: Yan ışınlarla karakter düşmeden önce boşluğu tespit etme.
4. Eylemsizlik, Momentum ve Dinamik Kayma
Hızlı tempolu parkur mekanikleri ekleme:
- Çömelerek Kayma: Koşarken çömelme tuşuna basıldığında sürtünmeyi geçici olarak kaldırma.
- Yokuş Aşağı Hızlanma: İnişlerde yerçekimi desteğiyle ekstra sürat kazanma.
- Momentum Korunumu: Kayma bittiğinde aniden durmayıp hızı yumuşakça sönümleme.
- Havada Yönlendirme (Air Control): Zıplama anında yön değiştirebilme yeteneği.
5. Prosedürel Animasyon ve Ayakların Yere Oturması
Fiziksel hız ile 3D karakter animasyonlarının kusursuz uyumu:
- Ayak Kaymasını Önleme: Animasyon oynatma hızını gerçek yer hızına göre ayarlama.
- 8 Yönlü Karışım: Yön vektörlerine göre yumuşak adım geçişleri.
- IKControl Entegrasyonu: Ayakların engebeli yüzeylere tam oturması.
- İstemci Tabanlı Hesaplama: Ağ gecikmesini sıfırlamak için fiziği yerel cihazda işleme.
Frequently Asked Questions
Kapsülün zemine temas etmeden havada durması neden gereklidir?
Doğrudan temas durumunda küçük yüzey çatlakları karakteri takar; yaylı süspansiyon kesintisiz akıcılık sağlar.
Vektör projeksiyonu yokuşlarda yavaşlamayı nasıl önler?
Hareketi yere çarpmak yerine eğime paralel şekilde yönlendirerek enerjiyi korur.
Hareketli trenlerde savrulma sorununu çözer mi?
Evet, zemin hızı raycast ile okunup doğrudan karakterin hızına eklenebilir.