Interact system
3D-Interaktionssystem + NPC-Dialog-Engine, ganz ohne Dependencies. Setz eine Interaktion an jede beliebige Stelle der Map: auf eine Entity, auf eine freie Koordinate oder auf einen NPC, den du im selben Aufruf spawnst. Kein ox_lib, kein Framework, nichts, was du serverseitig einrichten musst.
Was es kann
Keine einzige Dependency
Seit 1.1.0 bringt die Resource ihr eigenes DUI-Handling, ihre Proximity-Points und ihre Wait-Helper in `bridges/compat.lua` selbst mit, alles auf reinen Natives geschrieben. Du musst nichts vorher installieren und dir keine Ladereihenfolge merken. Läuft ox_lib bei dir ohnehin und du willst ihm die Arbeit überlassen, setz `Config.UseOxLib = true` und kommentier eine Zeile im Manifest ein.
Technische
Daten
Alles, was du
bekommst
-
Fünfzehn Sprachdateien, gefüllt ausgeliefert
Deine Spieler lesen das Script vom ersten Start an in ihrer Sprache, und die Dateien liegen außerhalb des Escrows, du kannst also jede Zeile im laufenden Betrieb ändern. Ehrlicher Hinweis: Sie sind von uns übersetzt und geprüft, nicht von Muttersprachlern aller fünfzehn gegengelesen. Sag uns, was in deiner falsch klingt, dann korrigieren wir es.
-
Alles in config.lua einstellbar
Standard-Label, Taste, Distanzen, Icon und Farbe eines Punkts, benannte Farben, die Zuordnung von Tastenkürzeln zu Control-Indizes, der Ped für Einträge ohne eigenes Modell, die Spawn-Distanz und `Config.Hud`, um zu bestimmen, welches HUD während eines Dialogs ausgeblendet wird. Das alles hat in 1.1.0 den Escrow verlassen.
-
Drei funktionierende Beispiele
Ein ATM-Watcher über den Model-Hash mit Zwei-Tasten-Menü, ein NPC mit komplett verzweigtem Dialog und GPS-Waypoint und ein Tanzpunkt mit mehreren Bindings. Das sind echte Dateien in `config/`, lösch sie, sobald deine eigenen stehen.
-
Discord-Support und Updates auf Lebenszeit
Zugang zum Support-Channel und jedes künftige Update ohne Aufpreis. Keine Premium-Stufe, kein kostenpflichtiges Add-on.
Guide zur Integration
Installation
-
Resource ablegen
Hol dir das Script aus deinem Tebex-Konto und kopier den Ordner
avenida_interact/auf deinem Server nachresources/[avenida]/. -
In der server.cfg aktivieren
Füg
ensure avenida_interacthinzu. Vorher muss nichts anderes starten: Seit 1.1.0 hat die Resource keine Dependencies, die Ladereihenfolge ist also egal. -
Deine Defaults setzen
Öffne
config/config.luaund stell ein, was für alle Punkte gilt: Label, Taste, die DistanzenshowIconundcanInteract, Icon, Farbe, benannte Farben, die Spawn-Distanz der Peds undConfig.Hudfür das HUD, das während eines Dialogs ausgeblendet wird. -
Demos entfernen
Die Beispiele in
config/entities/,config/peds/undconfig/positions/sind aktiv, solange ihre Dateien da sind. Lösch die, die du nicht willst. Das Manifest globt diese Ordner, mehr musst du nicht anfassen. -
Hot Reload testen
Starte den Server und tipp im Spiel
/restart avenida_interact. Die Icons verschwinden und kommen sauber zurück, und die Punkte deiner eigenen Resources bleiben erhalten, ohne dass du deine Session neu startest.
Schnellstart
Dein erster Interaktionspunkt in 30 Sekunden
Leg eine `myscript/client.lua` in deiner eigenen Resource an und füg das hier ein. Ein cyanfarbener Marker erscheint ab 30m, der Prompt „E - Hello“ rollt ab 2m aus. Laufen muss dafür nur avenida_interact selbst.
-- myscript/client.lua
exports.avenida_interact:positionRegister({
coords = vec3(-265.0, -963.6, 31.2),
showIcon = 30.0, -- marker fades in at 30m
canInteract = 2.0, -- label unrolls at 2m
hintIcon = 'interact', -- see the icon list below
hintColor = '#22d3ee', -- hex, or an alias from Config.Colors
message = 'Hello',
bind = 'E',
onInteract = function()
TriggerEvent('chat:addMessage', { args = { 'Hello, world!' } })
end,
})API-Referenz
Öffentliche Exports nach Bereich gruppiert. Jede Zeile zeigt die Signatur und was der Export macht, nicht wie er es macht.
Interact Points
positionRegister
exports.avenida_interact:positionRegister(cfg) --> idRegistriert einen Punkt auf festen Koordinaten. Nimmt jedes visuelle Feld (
hintIcon,hintColor,showIcon,canInteract,offsetZ,blips) pluschoices[]für mehrere Tasten auf demselben Punkt.canInteractakzeptiert eine Zahl oder eine Funktion, du kannst den Prompt also an einen Job, ein Item oder einen Cooldown binden. Gibt eine ID zurück.pedRegister
exports.avenida_interact:pedRegister(cfg) --> idSpawnt einen konfigurierten NPC (Modell,
animDictundanimNameoder ein Scenario, Blip), hängt einen Punkt daran und gibt seinen Index zurück. Der Ped ist unverwundbar, flieht nicht und geht nicht in Ragdoll. Er spawnt und verschwindet wieder im Umkreis vonConfig.PedSpawnRange, standardmäßig 50m. SetzrandomComponents = falsebei einem Händler mit festem Namen, sonst sieht jeder Spieler ein anderes Outfit.pedRemove
exports.avenida_interact:pedRemove(idx)Neu in 1.1.0. Despawnt einen mit
pedRegisterregistrierten Ped und löscht seine Registrierung, damit ein temporärer Questgeber wieder gehen kann, wenn die Quest vorbei ist.entityRegister
exports.avenida_interact:entityRegister(cfg) --> idHängt einen Punkt an eine bestehende Entity, die du als
cfg.entityübergibst. Unterstütztcfg.bone, um den Prompt an einen Bone statt an das Zentrum der Entity zu hängen. Für alles, was ein anderes Script gespawnt hat: ein Fahrzeug, ein platziertes Prop, ein fallengelassenes Item.entityRegisterByHash
exports.avenida_interact:entityRegisterByHash(hash, cfg)Passiver Watcher: Die Config gilt für jede Entity dieses Modells, für die schon gestreamten und für die, die später auftauchen. Ein einziger Thread deckt alle registrierten Hashes ab und geht sie alle 5s durch. Genau das willst du für ATMs, Automaten und Türen, statt eine Koordinatenliste zu pflegen.
entityRemove
exports.avenida_interact:entityRemove(idx)Hängt den von
entityRegisterzurückgegebenen Punkt wieder ab. Die Entity selbst bleibt unangetastet.interactCreate
exports.avenida_interact:interactCreate(cfg) --> idPunkt zur Laufzeit, nach Bedarf erzeugt und entfernt. Für alles, was nur eine Weile existiert: ein Missionsziel, eine Tasche am Boden, eine Leiche zum Durchsuchen.
interactRemove
exports.avenida_interact:interactRemove(id)Entfernt einen mit
interactCreateerzeugten Punkt und seinen Blip, falls er einen deklariert hat.unlockLastInteract
exports.avenida_interact:unlockLastInteract()Ein Punkt sperrt sich nach der Benutzung selbst, damit eine gehaltene Taste ihn nicht zweimal auslöst. Ruf das am Ende deiner Aktion auf, um ihn wieder freizugeben. Ist der Spieler noch in Reichweite, kommt der Prompt direkt zurück, sonst wartet er, bis der Spieler wieder in Reichweite kommt.
Prompt API
HandleTextUI
exports.avenida_interact:HandleTextUI(id, data) --> duiHandlerErzeugt oder aktualisiert eine eigenständige 3D-Sprechblase, ganz ohne Interaktionspunkt dahinter. Für den Fall, dass du die Sichtbarkeit aus deinem eigenen Thread steuern willst. Gibt den Handler zurück, den du an
Draw3DSpriteweitergibst.Draw3DSprite
exports.avenida_interact:Draw3DSprite({ duiHandler, coords, maxDistance, hintOnly? })Zeichnet die Sprechblase in Weltkoordinaten aus einem Render-Thread, entzerrt anhand des Seitenverhältnisses. Mit
hintOnly = truewird nur der Marker gezeichnet, das ist der Zustand, den ein normaler Punkt aus der Ferne zeigt.CloseTextUI
exports.avenida_interact:CloseTextUI(id)Blendet eine Sprechblase aus, behält ihr DUI aber im Speicher, das erneute Öffnen geht damit ohne Verzögerung.
RemoveTextUI
exports.avenida_interact:RemoveTextUI(id)Entfernt eine Sprechblase endgültig und gibt ihr DUI frei. Nimm das, wenn du weißt, dass sie nicht wiederkommt.
RemoveTextUIs
exports.avenida_interact:RemoveTextUIs()Entfernt alle aktiven Sprechblasen. Beim Stoppen der Resource passiert das automatisch.
IsDuiVisible
exports.avenida_interact:IsDuiVisible() --> booleanGibt
truezurück, solange ein Prompt auf dem Bildschirm ist. Frag den Export ab, damit sich deine eigenen Prompts nicht über eine laufende Interaktion legen.
Key handler
HandleHoldTextUI
exports.avenida_interact:HandleHoldTextUI(id, data) --> duiHandlerDie Schicht, auf der die Punkte aufbauen: Sie zeichnet einen Prompt an
Coordsund überwacht dessen Taste aus einem Manager-Thread, der alle 50ms läuft.datanimmtBindToHold(Control-Index),DistanceHold,Coords,ChoicesUIundChoicesCtrlfür einen Prompt mit mehreren Tasten,onCallback(id)undcanInteract(id, dist). Löst beim Tastendruck aus, mit 500ms Debounce, und dein Callback läuft in einempcall, ein Fehler auf deiner Seite reißt den Prompt also nicht mit runter.CloseHoldTextUI
exports.avenida_interact:CloseHoldTextUI(id)Blendet den Prompt aus, ohne die Instanz zu zerstören, für einen sauberen Abgang, wenn der Spieler die Zone verlässt.
RemoveHoldTextUI
exports.avenida_interact:RemoveHoldTextUI(id)Zerstört eine Instanz und gibt ihr DUI frei.
RemoveHoldTextUIs
exports.avenida_interact:RemoveHoldTextUIs()Zerstört alle aktiven Instanzen.
Rezepte
Praxisnahe Copy-Paste-Beispiele. In deine eigene Resource kopieren, Werte anpassen, fertig.
Der einfachste Fall: ein Punkt auf festen Koordinaten, mit seinem Blip in derselben Table. Der Marker erscheint ab 30m, das Label ab 2m. Pack das in eine beliebige Client-Datei deiner Resource.
exports.avenida_interact:positionRegister({
coords = vec3(149.5, -1040.4, 29.4),
showIcon = 30.0,
canInteract = 2.0,
hintIcon = 'bank',
hintColor = 'blue',
message = 'Use the ATM',
bind = 'E',
onInteract = function()
TriggerEvent('myserver-banking:openATM')
end,
blips = {
sprite = 277,
color = 2,
scale = 0.8,
text = 'ATM',
display = 4,
},
})Der Watcher registriert deine Config einmal pro Modell und wendet sie auf jedes passende Prop an, egal ob es jetzt schon gestreamt ist oder erst später auftaucht. Jede Auswahl trägt ihr eigenes Label, ihre eigene Farbe und ihre eigene `condition`, der Raubüberfall taucht also nur auf, wenn dein Police-Script es erlaubt. Achte auf den Feldnamen: Eine Auswahl nutzt `condition`, nicht `canInteract`.
local ATM_PROPS = {
'prop_atm_01', 'prop_atm_02', 'prop_atm_03', 'prop_fleeca_atm',
}
for _, prop in ipairs(ATM_PROPS) do
exports.avenida_interact:entityRegisterByHash(prop, {
canInteract = 1.2,
offsetZ = 1.0,
hintIcon = 'bank',
hintColor = 'blue',
choices = {
{
bind = 'E',
message = 'Use the ATM',
onInteract = function()
TriggerEvent('myserver-banking:atmUse')
end,
},
{
bind = 'G',
message = 'Rob the ATM',
hintColor = 'red',
condition = function()
return exports['myserver-police']:hasEnoughCops(2)
end,
onInteract = function(entity)
TriggerServerEvent('myserver-robbery:startATM', NetworkGetNetworkIdFromEntity(entity))
end,
},
},
})
endEin vollständiger Questgeber: Der Ped spawnt mit Animation und Blip, und die Dialogantworten führen aus, was du willst, hier den Native `SetNewWaypoint`. `changeDialog` ersetzt Text und Antworten, du verschachtelst also so tief, wie das Gespräch es braucht. `randomComponents = false` sorgt dafür, dass Maria bei jedem Spieler dasselbe Outfit trägt.
exports.avenida_interact:pedRegister({
coords = vec4(-1393.81, -1064.09, 3.17, 266.09),
model = 'a_f_y_vinewood_04',
animDict = 'anim@amb@waving@male',
animName = 'ground_wave',
randomComponents = false,
message = 'Talk with Maria',
showIcon = 10.0,
canInteract = 3.0,
hintIcon = 'talk',
hintColor = 'gold',
blips = { sprite = 119, color = 50, text = 'Lumberjack', scale = 0.8 },
dialogue = {
name = 'Maria',
startMsg = 'Hello, are you ready to start your shift?',
elements = {
{
label = 'Yes, where do I start?',
action = function(changeDialog, close)
SetNewWaypoint(-584.01, 5491.59)
changeDialog('The forest is on your GPS now.', {
{ label = 'Got it!', action = function(_, close) close() end },
})
end,
},
{
label = 'I\'ll come back later',
action = function(_, close) close() end,
},
},
},
})Fehlerbehebung
- Nein. Seit 1.1.0 baut `bridges/compat.lua` die DUI-Erstellung, die Proximity-Points und die Wait-Helper mit reinen Natives nach, und die Zeile `@ox_lib/init.lua` ist im Manifest auskommentiert. Wenn du das lieber über ox_lib laufen lässt, setz `Config.UseOxLib = true` und kommentier die Zeile ein. Beide Wege werden gepflegt, der native ist der Standard.
- Erstens die Reichweite: `showIcon` steht in `Config.Defaults` auf 4m, was wenig ist, wenn du einen Marker aus der Ferne erwartet hast, also übergib deinen eigenen Wert. Zweitens muss die Entity bei `entityRegister` zum Aufrufzeitpunkt existieren, während `entityRegisterByHash` auf sie wartet, was bei Game-Props der richtige Weg ist. Drittens setz `Config.Debug = true`, dann landen interne Fehler in der Client-Konsole.
- Eine Auswahl liest `condition`, nicht `canInteract`. `canInteract` ist das Feld des Punkts selbst, dort nimmt es eine Zahl oder eine Funktion. Innerhalb von `choices[]` heißt die Sperre `condition = function() ... end`, und eine Auswahl, deren `condition` `false` zurückgibt, wird schlicht nicht gezeichnet.
- Jeden Hex-Wert wie `#22d3ee` oder einen Namen aus `Config.Colors`, die mit `red`, `blue`, `green`, `gold`, `purple` und `white` ausgeliefert wird. Diese Table ist escrow-frei, häng also die Palette deines Servers dran und nutz überall deine eigenen Namen. Ein unbekanntes `hintIcon` wird als Text gezeichnet, du kannst ein Emoji also als schnelles Icon nehmen.
- Das ist in 1.1.0 behoben. Die DUI-Textur liegt jetzt fest auf 1920x1080 und wird beim Zeichnen anhand des echten Seitenverhältnisses entzerrt, und das Icon ändert seine Größe nicht mehr mit der Distanz. Die Antwortboxen der Dialoge haben oberhalb von 2560x1440 ebenfalls mehr Höhe bekommen. Zieh das Update, wenn du noch auf 1.0.x bist.
- Die Zuordnung läuft über `GetInvokingResource()`, ein Punkt gehört also der Resource, die den Export aufgerufen hat. Wenn du aus einem gemeinsamen Handler registrierst, der im Kontext einer anderen Resource läuft, richtet sich das Aufräumen nach dieser anderen Resource. Pack den Aufruf in eine Funktion der Resource, der der Punkt gehört. Seit 1.1.0 werden Punkte auch beim Start einer Resource gelöscht, ein Restart lässt also keine Geister mehr zurück.
- Du musst gar nichts anhängen: Die Resource kennt dein Framework nicht und redet nie mit deinem Server. Lies den Job oder den Grade des Spielers in `canInteract` oder in der `condition` einer Auswahl und ruf deine eigenen Events aus `onInteract` heraus auf. Alles, was auf deinem Framework läuft, läuft unverändert hinter diesen beiden Funktionen.
- Gemessen mit 100 Punkten: 0.00ms im Leerlauf. Gezeichnet wird nur innerhalb der `showIcon`-Reichweite, und die Tastenüberwachung läuft alle 50ms für Instanzen in Reichweite. Tausende Punkte über die Map verteilt kosten also nichts, solange sie nicht alle in derselben Straße stehen.
Was Käufer sagen
5.0 2 verifizierte Bewertungen
Revoria very good scriptwriters a reactive and competent listening team I recommend go there with your eyes closed!!
theara Best script, best support! Fast support and friendly!
EMPFOHLEN Avenida TeamBarber shop
Ein Barbershop, inszeniert wie eine Szene, mit einer Kamera, die der Spieler wirklich steuert. Der Charakter kommt herein, setzt sich, und der Barber legt los, während eine Orbit-Kamera den Kopf ins Bild rückt. Haare, Bart, Overlays und der komplette Satz an Skin-Details, live am Charakter zu sehen, bevor ein einziger Dollar ausgegeben ist.
EMPFOHLEN Avenida TeamClothing store
Ein Kleidungsladen mit gespeicherten Outfits, Firmen-Garderoben und einem Editor, der den Katalog direkt im Spiel bepreist. Jede Komponente und jedes Prop, Stück für Stück gekauft oder als ganzer Look, mit einem serverseitigen Register, das verhindert, dass jemand etwas trägt, wofür er nie bezahlt hat.
EMPFOHLEN Avenida TeamCore Skin (3 in 1)
Barbershop, Tattoo-Studio und Kleidungsladen in einer einzigen FiveM-Resource. 1615 Tattoos, jede Kleidungskomponente und jedes Prop, der komplette Bereich für Kopf und Haut, verteilt auf 36 Läden. Eine Oberfläche, eine Kamera, ein Kaufablauf und nur eine Sache, die du auf ESX, QBCore, vRP oder Standalone installierst.