implementowanie zachowań blastera jest procesem programowania eksplozji mechanika w doświadczeniach strzelcy pierwszej osoby. Chociaż gracze mogą eksplodować jednym kliknięciem lub naciśnięciem przycisku, tworzenie satysfakcjonującego i dokładnego zachowania eksplozji jest ważne, ponieważ poprawia to zabawę graczy.
Używając do referencji 示例 laser tag experience, ta sekcja tutorialu uczy cię o skryptach za implementacją zachowania laserowego dla dwóch różnych typów laserów, w tym kierunkach:
- Wykrywanie, gdy gracze naciskają przycisk wybuchu.
- Sprawdzenie, czy gracz może użyć swojego blastera, jeśli niedawno naciągnął przycisk „Explosja”.
- Generowanie danych eksplozji, które mówią serwerowi, kto inicjował eksplozję, skąd pochodzi i jakie było ostateczne miejsce docelowe każdego lasera.
- Powiadomienie serwera o danym eksplozji, aby mógł wykonać odpowiednie działania, jeśli eksplozja uderzyła inną gracz.
- Zresetowanie blastera między każdym atakiem, aby dać blasterowi wystarczająco dużo czasu na schnięcie, zanim może eksplodować ponownie.
Po zakończeniu tej sekcji dowiesz się o skryptach, które umożliwiają blasterowi wykrycie, gdy jego pociski kolidują z innymi graczami, a potem odejmij odpowiednią ilość zdrowia zgodnie z każdym wpisywaćblastera.
Wykryj wejście gracza
Pierwszym krokiem do wdrożenia zachowania blastera jest słuchanie, gdy gracz nacisnął przycisk wybuchowy. Typ wejścia, który używają gracze do naciskania przycisku wybuchowego, zależy od urządzenia, z którego korzystają do uzyskania dostępu do doświadczenia. Na przykład, wtyczka laserowa do przycisku wybuchowego wspiera sterowanie myszką
Ten kod klienta używa ContextActionService, aby związać MouseButton1 i ButtonR2 z akcjiwybuchową. Oznacza to, że za każdym razem, gdy gracz naciśnie lewy przycisk myszy lub przycisk R2 na urządzeniu mobilnym, wt
Przetwarzacz danych użytkownika
ContextActionService:BindAction("_", onBlasterActivated, false,Enum.UserInputType.MouseButton1,Enum.KeyCode.ButtonR2)
Kolejnym ważnym uzupełnieniem jest użycie Enum.UserInputState.Begin w definicji onBlasterActivated(). Wiele interakcji interfejsu użytkownika, takich jak wybór blastera w tym przykładzie, nie następuje, dopóki przycisk nie pojawi się ( Enum.UserInput
Aby pokazać, możesz zmienić Enum.UserInputState.Begin na Enum.UserInputState.End, a następnie przetestować, jak reakcja na eksplozję wpływa na grę w doświadczeniu. Na przykład, jeśli gracze mogą przytrzymać przycisk bez uruchomienia eksplozji, jak to może zmienić ich doświadczenie, gdy tagują innych graczy?
Przetwarzacz danych użytkownika
local function onBlasterActivated(_actionName: string,
inputState: Enum.UserInputState, _inputObject: InputObject)
if inputState == Enum.UserInputState.End then -- aktualizowana linia, upewnij się, że zmieniłeś wstecz
attemptBlastClient()
end
end
Sprawdź, czy gracz może eksplodować
Po wykryciu przez UserInputHandler przycisku lub uderzenia ekranu, wzywa ReplicatedStorage > Blaster
możliwość wykonania
local function canLocalPlayerBlast(): boolean
return localPlayer:GetAttribute(PlayerAttribute.blasterStateClient) == BlasterState.Ready
end
Jeśli
Ta lekka przerwa zapobiega, że możesz eksplodować tak szybko, jak możesz klikać. Na przykład, jeśli zmienisz funkcję zawsze return true, możesz szybko eksplodować swojego blastera bez żadnego opóźnienia, co jest nieprawdopodobne dla rozgrywkaw laser tagi.
możliwość wykonania
local function canLocalPlayerBlast(): boolean
return true -- aktualizowana linia, upewnij się, że zmieniłeś wstecz
end
Generuj dane eksplozji
Po weryfikacji, że blaster gracza jest w stanie Ready, attemptBlastClient wzywa ReplicatedStorage > 2> attemptBlastClient2> > 5> blastClient5>. Pierwszym krokiem
Następnym krokiem jest generacja danych eksplozji. Jeśli przeglądasz ReplicatedStorage > Blaster > BlastData , możesz zobaczyć, że każda eksplozja składa się z trzech części informacji:
- Gracz, który inicjuje eksplozję.
- A DataType.CFrame , które reprezentuje punkt pochodzenia eksplozji.
- Tabela RayResult, która zawiera ostateczne miejsce docelowe każdego lasera i gracza, jeśli dotknie inny gracz.
Aby generować te dane, blastClient wzywa ReplicatedStorage > attemptBlastClient > 2>błąd prób2> > 5>błąd prób5> > 8>生成BlastData8>, który można przeglądać poniżej.
GenerujBlastData
local function generateBlastData(): BlastData.Type
local blasterConfig = getBlasterConfig()
local rayDirections = getDirectionsForBlast(
currentCamera.CFrame, blasterConfig)
local rayResults = castLaserRay(
localPlayer, currentCamera.CFrame.Position, rayDirections)
local blastData: BlastData.Type = {
player = localPlayer,
originCFrame = currentCamera.CFrame,
rayResults = rayResults,
}
return blastData
end
Funkcja ta zaczyna się używając getBlasterConfig , aby odzyskać wpisywaćblastera gracza. Przykład dostarcza dwa rodzaje blasterów: jeden, który produkuje kilka promieni z szerokim rozprzestrzenianiem poziomym, i inny, który produkuje pojedynczy promień. Można znaleźć ich konfiguracje w ReplicatedStorage > Inst
Funkcja wtedy używa currentCamera.CFrame jako punkt wyjścia dla eksplozji, przesyłając ją do getDirectionsForBlast. W tym momencie kod nie jest już o blaster
Powiadom Serwer
Gdy blastClient ma ukończone dane dla eksplozji, wtedy uruchamia dwa wydarzenia:
eksplozjaClient
local laserBlastedBindableEvent = ReplicatedStorage.Instances.LaserBlastedBindableEventlocal laserBlastedEvent = ReplicatedStorage.Instances.LaserBlastedEventlaserBlastedBindableEvent:Fire(blastData)laserBlastedEvent:FireServer(blastData)
Class.BindableEvent poinformuje inne skrypty klientów o eksplozji. Na przykład, ReplicatedStorage > FirstPersonBlasterVisuals używa tego wydarzenia, aby wiedzieć, kiedy wyświetlić efekty wizualne, takie
LaserBlastHandler
local function onLaserBlastedEvent(playerBlasted: Player, blastData: BlastData.Type)
local validatedBlastData = getValidatedBlastData(playerBlasted, blastData)
if not validatedBlastData then
return
end
if not canPlayerBlast(playerBlasted) then
return
end
blastServer(playerBlasted)
processTaggedPlayers(playerBlasted, blastData)
for _, replicateToPlayer in Players:GetPlayers() do
if playerBlasted == replicateToPlayer then
continue
end
replicateBlastEvent:FireClient(replicateToPlayer, playerBlasted, blastData)
end
end
Aby pomóc zapobiec oszustwom, serwer musi weryfikować wszystkie dane, które każdy klient wysyła. Te czynności obejmują:
- Czy BlastData jest tabelą? Czy zawiera Class.CFrame i inną tabelę nazyającą się rayResults?
- Czy gracz ma założony blaster?
- Czy gracz ma postać i lokalizację w świecie?
- Po wysłaniu danych eksplozji, czy gracz przeszedł zbyt dużą odległość od miejsca, w którym eksplodował promień laserowy?
Ten ostatni test wiąże się z wezwanie do sądu, a zgodnie z czasami serwera i szybkością ruchu gracza, możesz zdecydować, że różne wartości są nadmierne dla własnego doświadczenia. Aby pokazać, jak wykonać ten wniosek sądowy, możesz uzyskać poczucie typowej wielkości zmiany pozycji, dodając oświadczenie drukowania w getValidatedBlastData i testując
dostać potwierdzone dane eksplozji
local distanceFromCharacterToOrigin = blastData.originCFrame.Position - rootPartCFrame.Positionprint(distanceFromCharacterToOrigin.Magnitude) -- aktualna linia, upewnij się, że usuwać, wyjmowaćif distanceFromCharacterToOrigin.Magnitude > ToleranceValues.DISTANCE_SANITY_CHECK_TOLERANCE_STUDS thenwarn(`Player {player.Name} failed an origin sanity check while blasting`)returnend
Podczas swojego ruchu i eksplozji, zauważaj wynik. Może to wyglądać coś takiego:
1.90196299552917483.15495586395263672.57428836822509774.80445861816406252.6434271335601807
Jeśli zwiększysz szybkość przesuwania dla graczy w ReplicatedStorage > PlayerStateHandler > togglePlayerMovement , to prawdopodobnie znajdziesz wiele niepowodzenia ze względu na nadmierne przesuwanie między wstrzymań.
Przenieśnik gracza
local ENABLED_WALK_SPEED = 60 -- updated line, be sure to change back
Następnie serwer robi co obserwuje:
- Zweryfikowuje rayResults .
- Sprawdza, czy gracz może eksplodować.
- Zresetuje stan błastra.
- Redukuje zdrowie dla każdego oznaczonego gracza.
- Replikuje eksplozję do wszystkich innych graczy, aby mogli zobaczyć wizualizacje trzecioludzkie.
Dla więcej informacji na temat tych operacji serwera, zobacz sekcję Wykrywanie trafień w samouczku.
Zresetuj Blaster
W doświadczeniu laserowego tagu próbkowego laser używa mechanizmu termicznego. Zamiast ponownego ładowania po serii rzucania, potrzebuje czasu na "wylanie" między każdym rzucaniem. Ten sam opóźniony czas odnowienia następuje zarówno na klienta ( blastClient ) i serwera ( blastServer ) z serwera działającym jako źródło prawdy.
eksplozjaSerwer
local blasterConfig = getBlasterConfig(player)
local secondsBetweenBlasts = blasterConfig:GetAttribute("secondsBetweenBlasts")
task.delay(secondsBetweenBlasts, function()
local currentState = player:GetAttribute(PlayerAttribute.blasterStateServer)
if currentState == BlasterState.Blasting then
player:SetAttribute(PlayerAttribute.blasterStateServer, BlasterState.Ready)
end
end)
Attribut secondsBetweenBlasts jest częścią konfiguracji blastera w ReplicatedStorage > Instances > 1>LaserBlastersFolder1>. Po przekroczeniu opóźnienia 4>secondsBetweenBlasts4>, gracz może znowu eksplodować, a cały proces powtarza się. Aby pomó
W tym momencie gracze mogą wywołać i odrodzić, celować i wystrzelić, ale doświadczenie nadal musi określić wyniki każdej eksplozji. W następnej sekcji tutorialu nauczysz się programować umiejętność dla blastera, aby wykryć, gdy eksplozja trafi innego gracza, a następnie zmniejsz odpowiednią ilość zdrowia gracza zgodnie z ustawieniami blastera.