Kamera und Timing
ScriptCamera, TickLoop, AreaFollower und ServerClock - geskriptete Kameras, Jobs pro Frame, die nur bei Bedarf laufen, den Bereich des Spielers an den Server melden und die Server-Uhr auf dem Client.
Eine geskriptete Kamera für Ausstellungsräume und Szenen, ein Job pro Frame, den du nur einschaltest, solange er gebraucht wird, die Client-Hälfte des Bereichs-Streamings des Servers und die Server-Uhr für Countdowns. Periodische Arbeit allgemein ist every(ms, fn) (siehe Lib: Shared und fivem); nie setInterval oder ein nacktes setTick.
ScriptCamera
new ScriptCamera
Eine geskriptete Kamera: die Ausstellungsansicht eines Shops, ein Editor, eine Szene, ein Fernglas. start erstellt und zeigt sie, die anderen Methoden bewegen und verändern sie, stop blendet weich zur Spielkamera zurück und zerstört sie. Eine Kamera, die noch läuft, wenn deine Ressource stoppt, wird sofort zurückgegeben, sodass der Spieler nie darin festhängt.
Seite: Client · Wartet: nein
new ScriptCamera(type?: string)Kein Lua-Zwilling: Lua-Ressourcen nutzen CreateCam, RenderScriptCams und DestroyCam.
Parameter
Prop
Type
CameraView
Wohin eine Kamera schaut, genutzt von start, move und glideTo:
Prop
Type
Mitglieder
Prop
Type
Beispiel
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
Erstellt die Kamera (wenn sie noch nicht existiert), setzt sie an einen Punkt und macht sie zur Ansicht, mit weicher Überblendung von der Spielkamera.
Seite: Client · Wartet: nein
camera.start(at: Vec3, view?: CameraView, easeMs?: number): voidParameter
Prop
Type
Rückgabewert
void. Siehe das Klassenbeispiel.
camera.move
Bewegt die Kamera, sofort oder gleitend (das Spiel interpoliert). Tut nichts, solange gestoppt.
Seite: Client · Wartet: nein
camera.move(at: Vec3, view?: CameraView, ms?: number): voidParameter
Prop
Type
Rückgabewert
void.
Beispiel
camera.move({ x: -42.0, y: -1099.0, z: 28.5 }, { pointAt: CAR }, 600);camera.glideTo
Blendet zu einer neuen Einstellung über: Eine zweite Kamera am neuen Ort übernimmt von dieser, und die alte wird nach der Überblendung zerstört. Wackeln und Unschärfe werden übernommen. Startet die Kamera, wenn sie gestoppt ist (oder wenn ms 0 ist).
Seite: Client · Wartet: nein
camera.glideTo(at: Vec3, view: CameraView, ms: number): voidParameter
Prop
Type
Rückgabewert
void. Siehe das Klassenbeispiel.
camera.attach
Lässt die Kamera einer Entity mit einem Versatz im eigenen Raum der Entity folgen.
Seite: Client · Wartet: nein
camera.attach(entity: number, offset: Vec3, relative?: boolean): voidParameter
Prop
Type
Rückgabewert
void.
Beispiel
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
Lässt die Kamera weiter auf einen Punkt schauen.
Seite: Client · Wartet: nein
camera.pointAt(target: Vec3): voidParameter
Prop
Type
Rückgabewert
void.
camera.setFov
Ändert das Sichtfeld (Zoom).
Seite: Client · Wartet: nein
camera.setFov(fov: number): voidParameter
Prop
Type
Rückgabewert
void.
Beispiel
// Fernglas: mit dem Mausrad zoomen.
let fov = 40;
export function zoom(step: number): void {
fov = Math.min(70, Math.max(5, fov + step));
camera.setFov(fov);
}camera.shake
Fügt das Kamerawackeln des Spiels hinzu. Amplitude 0 stoppt es.
Seite: Client · Wartet: nein
camera.shake(type: string, amplitude: number): voidParameter
Prop
Type
Rückgabewert
void.
Beispiel
camera.shake("HAND_SHAKE", 0.3);camera.blur
Schärfentiefe: scharf zwischen zwei Entfernungen, unscharf außerhalb. Übergib null für keine. Sie braucht ein Native pro Frame, das nur läuft, solange eine Unschärfe gesetzt ist.
Seite: Client · Wartet: nein
camera.blur(dof: CameraBlur | null): voidParameter
Prop
Type
Rückgabewert
void.
Beispiel
camera.blur({ near: 2, far: 8, strength: 0.8 });camera.stop
Gibt die Ansicht an die Spielkamera zurück (weich über easeMs) und zerstört die Kamera. Wackeln und Unschärfe enden ebenfalls. Tut nichts, solange gestoppt.
Seite: Client · Wartet: nein
camera.stop(easeMs?: number): voidParameter
Prop
Type
Rückgabewert
void. Siehe das Klassenbeispiel.
TickLoop
new TickLoop
Ein Job pro Frame (every(0, fn) auf dem einen Scheduler deiner Ressource), der aus ist, bis du ihn einschaltest. Nutze ihn für alles, was nur manchmal in jedem Frame laufen muss: einen Marker in der Nähe zeichnen, eine Platzierungsvorschau, deaktiviertes Schießen beim Zielen auf einen Freund.
Seite: Client · Wartet: nein
new TickLoop(onFrame: () => void, name?: string)Kein Lua-Zwilling: aiLib.every(0, fn, { active = false, name = name }) und job:set(active).
Parameter
Prop
Type
Mitglieder
Prop
Type
Beispiel
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),
});Jeder Job deiner Ressource läuft aus einem setTick, das nur existiert, solange ein Job an ist. Erstelle die Schleife einmal am Anfang der Datei und schalte sie, statt pro Start eine neue zu erstellen.
AreaFollower
new AreaFollower
Die Client-Hälfte eines Server-AreaStream (Bereichs-Streaming): Sie meldet dem Server, in welcher Rasterzelle der Spieler steht, sobald sie sich ändert (alle 2 Sekunden geprüft, solange gestartet), sodass der Server nur die Weltobjekte (Drops, Pflanzen, platzierte Props) um den Spieler sendet. Erstelle eine am Anfang der Datei.
Seite: Client · Wartet: nein
new AreaFollower(event: string, cellSize?: number)Kein Lua-Zwilling.
Parameter
Prop
Type
Mitglieder
Prop
Type
Beispiel
import { AreaFollower, onServerEvent } from "@aicore-fivem/lib/client";
const follower = new AreaFollower("myplants:cell");
follower.start();
const plants = new Map<number, unknown>();
// Der Stream sendet (reset, puts, removes): einen Snapshot mit reset true, danach nur Änderungen.
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);
},
);Der Server prüft eine gemeldete Zelle gegen die echte Position des Spielers (followReported akzeptiert nur Zellen innerhalb einer Zelle um den Ped), sodass ein Cheater keinen weit entfernten Bereich anfordern kann.
ServerClock
new ServerClock
Die Server-Uhr auf einem Client. Client- und Server-Uhr können sich unterscheiden, daher muss ein Countdown bis zu einer Serverzeit (ein Raub-Cooldown, das Ende einer Auktion) zuerst in lokale Zeit umgerechnet werden. Rufe sync mit dem Date.now() des Servers auf, sobald ein Snapshot oder eine Startnachricht ankommt.
Seite: Client (aus @aicore-fivem/lib/shared) · Wartet: nein
new ServerClock()Kein Lua-Zwilling.
Mitglieder
Prop
Type
Beispiel
import { every, onServerEvent } from "@aicore-fivem/lib/client";
import { ServerClock } from "@aicore-fivem/lib/shared";
const clock = new ServerClock();
let endsAt = 0; // lokale Zeit
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 });
});Der Server sendet die Endzeit einmal; der Client zählt auf seiner eigenen Uhr herunter. Sende nie jede Sekunde die verbleibende Zeit.
Abfragen und Laden
raycast, groundZ, locationName, vehicleLabel, waypoint, pedHeadshot, onShot und die request-Lader - das Spiel nach der Welt fragen und Spiel-Assets laden.
Mitgliedschaft und Spielerdaten
hasJob, inGang, onDutyIn, allows, onMembershipChange, getPlayerData, onPlayerData und seedPlayerData - Charakter, Geld, Jobs, Dienst und Gangs des lokalen Spielers, wie ai-core sie schickt.