Kamera i czas
ScriptCamera, TickLoop, AreaFollower i ServerClock - kamery skryptowe, zadania co klatkę działające tylko wtedy, gdy są potrzebne, zgłaszanie obszaru gracza do serwera i zegar serwera na kliencie.
Kamera skryptowa dla salonów i scen, zadanie co klatkę, które włączasz tylko wtedy, gdy jest potrzebne, kliencka połowa strumieniowania obszarów serwera i zegar serwera do odliczań. Praca okresowa w ogóle to every(ms, fn) (zobacz Lib: shared i fivem); nigdy setInterval ani gołe setTick.
ScriptCamera
new ScriptCamera
Kamera skryptowa: widok salonu sklepu, edytor, scena, lornetka. start ją tworzy i pokazuje, pozostałe metody ją przesuwają i zmieniają, stop płynnie wraca do kamery gry i ją niszczy. Kamera, która nadal działa, gdy twój zasób się zatrzymuje, jest od razu oddawana, więc gracz nigdy w niej nie utknie.
Strona: Klient · Czeka: nie
new ScriptCamera(type?: string)Brak odpowiednika w Lua: zasoby Lua używają CreateCam, RenderScriptCams i DestroyCam.
Parametry
Prop
Type
CameraView
Gdzie patrzy kamera, używane przez start, move i glideTo:
Prop
Type
Składowe
Prop
Type
Przykład
import { ScriptCamera } from "@aicore-fivem/lib/client";
const camera = new ScriptCamera();
const CAR = { x: -44.4, y: -1097.1, z: 26.4 };
export function openShowroom(): void {
camera.start({ x: -40.2, y: -1100.5, z: 27.6 }, { pointAt: CAR, fov: 50 }, 800);
}
export function frontView(): void {
camera.glideTo({ x: -47.5, y: -1093.8, z: 27.2 }, { pointAt: CAR, fov: 45 }, 1200);
}
export function closeShowroom(): void {
camera.stop(800);
}camera.start
Tworzy kamerę (gdy jeszcze nie istnieje), stawia ją w punkcie i robi z niej widok, płynnie przechodząc z kamery gry.
Strona: Klient · Czeka: nie
camera.start(at: Vec3, view?: CameraView, easeMs?: number): voidParametry
Prop
Type
Zwracana wartość
void. Zobacz przykład klasy.
camera.move
Przesuwa kamerę, od razu albo płynnie (interpoluje gra). Nic nie robi, gdy jest zatrzymana.
Strona: Klient · Czeka: nie
camera.move(at: Vec3, view?: CameraView, ms?: number): voidParametry
Prop
Type
Zwracana wartość
void.
Przykład
camera.move({ x: -42.0, y: -1099.0, z: 28.5 }, { pointAt: CAR }, 600);camera.glideTo
Przechodzi do nowego ujęcia: druga kamera w nowym miejscu przejmuje od tej, a stara jest niszczona po przejściu. Drgania i rozmycie przechodzą dalej. Uruchamia kamerę, gdy jest zatrzymana (albo gdy ms wynosi 0).
Strona: Klient · Czeka: nie
camera.glideTo(at: Vec3, view: CameraView, ms: number): voidParametry
Prop
Type
Zwracana wartość
void. Zobacz przykład klasy.
camera.attach
Sprawia, że kamera podąża za encją z przesunięciem we własnym układzie encji.
Strona: Klient · Czeka: nie
camera.attach(entity: number, offset: Vec3, relative?: boolean): voidParametry
Prop
Type
Zwracana wartość
void.
Przykład
import { cache, ScriptCamera } from "@aicore-fivem/lib/client";
const chase = new ScriptCamera();
if (cache.vehicle !== false) {
chase.start({ x: 0, y: 0, z: 0 });
chase.attach(cache.vehicle, { x: 0, y: -6, z: 2 });
}camera.pointAt
Sprawia, że kamera stale patrzy na punkt.
Strona: Klient · Czeka: nie
camera.pointAt(target: Vec3): voidParametry
Prop
Type
Zwracana wartość
void.
camera.setFov
Zmienia pole widzenia (przybliżenie).
Strona: Klient · Czeka: nie
camera.setFov(fov: number): voidParametry
Prop
Type
Zwracana wartość
void.
Przykład
// Lornetka: przybliżanie kółkiem myszy.
let fov = 40;
export function zoom(step: number): void {
fov = Math.min(70, Math.max(5, fov + step));
camera.setFov(fov);
}camera.shake
Dodaje drgania kamery z gry. Amplituda 0 je zatrzymuje.
Strona: Klient · Czeka: nie
camera.shake(type: string, amplitude: number): voidParametry
Prop
Type
Zwracana wartość
void.
Przykład
camera.shake("HAND_SHAKE", 0.3);camera.blur
Głębia ostrości: ostro między dwiema odległościami, rozmyte poza nimi. Podaj null, żeby jej nie było. Wymaga natywki co klatkę, która działa tylko wtedy, gdy ustawione jest rozmycie.
Strona: Klient · Czeka: nie
camera.blur(dof: CameraBlur | null): voidParametry
Prop
Type
Zwracana wartość
void.
Przykład
camera.blur({ near: 2, far: 8, strength: 0.8 });camera.stop
Oddaje widok kamerze gry (płynnie przez easeMs) i niszczy kamerę. Drgania i rozmycie też się kończą. Nic nie robi, gdy jest zatrzymana.
Strona: Klient · Czeka: nie
camera.stop(easeMs?: number): voidParametry
Prop
Type
Zwracana wartość
void. Zobacz przykład klasy.
TickLoop
new TickLoop
Zadanie co klatkę (every(0, fn) w jedynym harmonogramie twojego zasobu), które jest wyłączone, dopóki go nie włączysz. Używaj go do wszystkiego, co musi działać co klatkę tylko czasami: rysowanie markera w pobliżu, podgląd stawiania, blokada strzelania przy celowaniu w przyjaciela.
Strona: Klient · Czeka: nie
new TickLoop(onFrame: () => void, name?: string)Brak odpowiednika w Lua: aiLib.every(0, fn, { active = false, name = name }) i job:set(active).
Parametry
Prop
Type
Składowe
Prop
Type
Przykład
import { TickLoop, Zones } from "@aicore-fivem/lib/client";
const SPOT = { x: 215.8, y: -810.1, z: 30.7 };
const light = new TickLoop(() => {
DrawLightWithRange(SPOT.x, SPOT.y, SPOT.z + 2, 61, 247, 158, 8, 4);
}, "garageLight");
const zones = new Zones();
zones.add("garage", {
shape: { type: "sphere", center: SPOT, radius: 25 },
onEnter: () => light.set(true),
onExit: () => light.set(false),
});Każde zadanie twojego zasobu działa z jednego setTick, który istnieje tylko wtedy, gdy jakieś zadanie jest włączone. Utwórz pętlę raz na górze pliku i ją przełączaj, zamiast tworzyć nową przy każdym starcie.
AreaFollower
new AreaFollower
Kliencka połowa serwerowego AreaStream (Strumieniowanie obszarów): mówi serwerowi, w której komórce siatki stoi gracz, za każdym razem, gdy się zmieni (sprawdzane co 2 sekundy po uruchomieniu), więc serwer wysyła tylko obiekty świata (zrzuty, rośliny, postawione propy) wokół gracza. Utwórz jeden na górze pliku.
Strona: Klient · Czeka: nie
new AreaFollower(event: string, cellSize?: number)Brak odpowiednika w Lua.
Parametry
Prop
Type
Składowe
Prop
Type
Przykład
import { AreaFollower, onServerEvent } from "@aicore-fivem/lib/client";
const follower = new AreaFollower("myplants:cell");
follower.start();
const plants = new Map<number, unknown>();
// Strumień wysyła (reset, puts, removes): jedna migawka z reset true, potem tylko zmiany.
onServerEvent(
"myplants:area",
{
args: ([reset, puts, removes]) =>
typeof reset === "boolean" && Array.isArray(puts) && Array.isArray(removes)
? ([reset, puts, removes] as const)
: null,
},
(reset, puts, removes) => {
if (reset) plants.clear();
for (const plant of puts as Array<{ id?: unknown } | null>)
if (typeof plant?.id === "number") plants.set(plant.id, plant);
for (const id of removes) if (typeof id === "number") plants.delete(id);
},
);Serwer sprawdza zgłoszoną komórkę względem prawdziwej pozycji gracza (followReported przyjmuje tylko komórki w odległości jednej komórki od peda), więc oszust nie może poprosić o odległy obszar.
ServerClock
new ServerClock
Zegar serwera na kliencie. Zegary klienta i serwera mogą się różnić, więc odliczanie do czasu serwera (cooldown napadu, koniec aukcji) trzeba najpierw zamienić na czas lokalny. Wywołuj sync z Date.now() serwera, gdy tylko przyjdzie migawka albo wiadomość startowa.
Strona: Klient (z @aicore-fivem/lib/shared) · Czeka: nie
new ServerClock()Brak odpowiednika w Lua.
Składowe
Prop
Type
Przykład
import { every, onServerEvent } from "@aicore-fivem/lib/client";
import { ServerClock } from "@aicore-fivem/lib/shared";
const clock = new ServerClock();
let endsAt = 0; // czas lokalny
onServerEvent(
"myauction:state",
{ args: ([now, ends]) => (typeof now === "number" && typeof ends === "number" ? [now, ends] : null) },
(now, ends) => {
clock.sync(now);
endsAt = clock.toLocal(ends);
},
);
every(1000, () => {
const left = Math.max(0, Math.round((endsAt - Date.now()) / 1000));
SendNUIMessage({ action: "countdown", data: left });
});Serwer wysyła czas końca raz; klient odlicza na własnym zegarze. Nigdy nie wysyłaj pozostałego czasu co sekundę.
Sondy i wczytywanie
raycast, groundZ, locationName, vehicleLabel, waypoint, pedHeadshot, onShot i loadery request - pytanie gry o świat i wczytywanie zasobów gry.
Członkostwo i dane gracza
hasJob, inGang, onDutyIn, allows, onMembershipChange, getPlayerData, onPlayerData i seedPlayerData - postać, pieniądze, prace, służba i gangi lokalnego gracza tak, jak wypycha je ai-core.