30/10/2022
Når du udvikler spil eller applikationer i Unreal Engine, især til mobile platforme som iPhone, er evnen til at forstå, hvad din kode foretager sig under kørsel, afgørende. Logning er et uundværligt værktøj i denne proces, da det giver dig et vindue ind i din applikations indre virkemåde. Uanset om det handler om at spore fejl, overvåge ydeevne eller blot verificere, at visse kodeblokke udføres som forventet, er effektiv logning nøglen til en problemfri udviklingsoplevelse. Denne artikel vil dykke ned i de forskellige metoder til logning i Unreal Engine og vise dig, hvor du kan finde og interagere med dine logfiler, med et særligt fokus på relevansen for mobiludvikling.

- Hvad er Logning, og Hvorfor er det Vigtigt?
- Skrivning af Logs i Unreal Engine: UE_LOG
- Moderne Logning med UE_LOGFMT (Unreal Engine 5.2+)
- Adgang til Dine Logs
- Log Detaljeringsniveauer (Verbosity Levels)
- Brugerdefinerede Logkategorier
- Udskrivning af Beskeder til Skærmen
- Tilføjelse af Beskeder til Viewport Stats Subsystem
- Ofte Stillede Spørgsmål om Logning i Unreal Engine
Hvad er Logning, og Hvorfor er det Vigtigt?
Logning handler om at føre en ordnet registrering af hændelser, funktionskald, variabelværdier på et bestemt tidspunkt under kørsel og mere. Typisk gemmes dette som tekst i en logfil. For en softwareudvikler er det et uvurderligt værktøj, især under fejlfinding, da det kan give detaljeret information om, hvad koden gør på et hvilket som helst givent tidspunkt. Gode anvendelsestilfælde inkluderer at sikre, at visse kodeblokke bliver udført, inspicere dataværdier, der sendes mellem funktioner, og rapportere potentielle problemer. For mobiludviklere er logning endnu mere kritisk, da direkte debugging på enheder ofte er mere udfordrende, og logfiler kan være den primære kilde til information om nedbrud eller uventet adfærd på en fysisk enhed som en iPhone eller Android-telefon.
Skrivning af Logs i Unreal Engine: UE_LOG
Den mest grundlæggende og almindelige metode til at skrive logbeskeder i Unreal Engine er ved hjælp af makroen UE_LOG. Denne makro er designet til at outputte logbeskeder direkte til logfilen, hvilket gør den ideel til at spore komplekse processer og fejl, der opstår under spillets eller applikationens levetid.
Et simpelt eksempel på en logbesked er:
UE_LOG(LogTemp, Warning, TEXT("Hello"));Det er vigtigt at sikre, at du kompilerer dit projekt, før du tester ændringerne, da logningsudsagn ellers ikke vil give noget output.
UE_LOG tager tre primære parametre:
- Logkategori: Den første parameter er navnet på logkategorien. Der findes mange indbyggede kategorier i motoren (defineret i
CoreGlobals.h), men du kan også oprette dine egne tilpassede kategorier for bedre organisering. En veldefineret kategori kan hjælpe dig med at filtrere og finde specifikke oplysninger hurtigt, især når du analyserer logfiler fra en mobil enhed. - Detaljeringsniveau (Verbosity Level): Den anden parameter angiver detaljeringsniveauet for beskeden, f.eks.
Warning,Error,Displayosv. Dette giver dig kontrol over, hvor vigtig en besked er, og om den skal vises under forskellige logindstillinger. - Tekstbesked: Den sidste parameter er selve tekstbeskeden. Her skal du pakke din streng ind i makroen
TEXT(). Dette er et særtræk vedUE_LOG, som sikrer korrekt håndtering af strenglitteraler på tværs af forskellige platforme og kompilatorer, hvilket er særligt relevant i et tværplatformsmiljø som Unreal Engine.
Formateringseksempler med UE_LOG
UE_LOG understøtter printf-lignende format specifiers, hvilket giver dig stor fleksibilitet i, hvordan du logger variable værdier. Her er nogle hurtige referenceeksempler:
- Logning af en FString:
UE_LOG(LogTemp, Warning, TEXT("Aktorens navn er %s"), *YourActor->GetName());Bemærk brugen af
*for at dereferenceFStringtil en C-stil streng. - Logning af en Bool:
UE_LOG(LogTemp, Warning, TEXT("Den booleske værdi er %s"), (bYourBool ? TEXT("true"): TEXT("false")));Booleans kræver en ternær operator for at konvertere dem til en streng, da
UE_LOGikke direkte kan printe dem. - Logning af et Heltal (Integer):
UE_LOG(LogTemp, Warning, TEXT("Heltalsværdien er: %d"), YourInteger);En ligetil anvendelse af
%d. - Logning af et Flydende Tal (Float):
UE_LOG(LogTemp, Warning, TEXT("Den flydende værdi er: %f"), YourFloat);Brug
%ftil flydende tal. - Logning af en FVector:
UE_LOG(LogTemp, Warning, TEXT("Vektorværdien er: %s"), *YourVector.ToString());FVector::ToString()konverterer vektoren til en læsbar streng. - Logning med Flere Specifiers:
UE_LOG(LogTemp, Warning, TEXT("Nuværende værdier er: vektor %s, float %f, og heltal %d"), *YourVector.ToString(), YourFloat, YourInteger);Du kan kombinere flere specifiers i én logbesked for at få et omfattende overblik over relaterede data.
Moderne Logning med UE_LOGFMT (Unreal Engine 5.2+)
Med introduktionen af Unreal Engine 5.2 blev en ny makro, UE_LOGFMT, tilgængelig, som løser mange af de "quirks" og udfordringer, der er forbundet med den ældre UE_LOG. For at bruge UE_LOGFMT skal du inkludere "Logging/StructuredLog.h".
UE_LOGFMT er designet til at være mindre omstændelig og mere intuitiv:
- Den kræver ikke konstant indpakning af logtekst i
TEXT()makroen. - Den er i stand til at printe grundlæggende typer som Booleans og
FStringdirekte, uden behov for manuelle konverteringer. - Den kræver ikke bevidsthed om typer, når forskellige variabler udskrives.
På sin mest simple form kan UE_LOGFMT bruges således:
UE_LOGFMT(LogTemp, Log, "Denne besked vil blive udskrevet til min log");Når du udskriver variabler til log, tilbyder UE_LOGFMT en renere og mere konsistent syntaks:
FString Name("SomeName"); int32 Value = 999; UE_LOGFMT(LogTemp, Log, "Udskriver mit Navn {0} med Værdi {1}", Name, Value);UE_LOGFMT accepterer parametre på to måder:
- Positionelle Parametre: Feltværdierne skal nøjagtigt matche de felter, der henvises til af logudsagnet. For eksempel, i
"Loading '{0}' failed with error {1}", erstattes{0}af den første variabel og{1}af den anden. Rækkefølgen er implicit vigtig. - Navngivne Parametre: Felterne skal indeholde hvert felt, der henvises til af formatet. Rækkefølgen er irrelevant, og ekstra felter er tilladt. Dette forbedrer læsbarheden betydeligt, især for komplekse logbeskeder. F.eks.
"Loading '{Name}' failed with error {Error}", hvor du derefter angiver værdierne med navne som("Error", ErrorCode). Dette gør dine logbeskeder mere forståelige og lettere at fejlfinde, især i store teams eller når du analyserer logs fra en mobiltest.
Adgang til Dine Logs
Nu hvor du ved, hvordan man skriver logs, er det næste skridt at vide, hvor du kan finde dem. Der er flere måder at få adgang til logfilerne, når du arbejder med Unreal Engine, hvilket er afgørende for effektiv fejlfinding og overvågning.
1. Logfiler i Gemt Mappe
Hvis din Play-In-Editor (PIE) session er afsluttet, kan du finde den fulde log for den session i mappen YourProjectName\Saved\Logs. Logs fra tidligere sessioner vil også være tilgængelige her. Denne metode er især nyttig, når du har brug for at analysere en session, der er afsluttet, eller når du modtager logfiler fra en testet mobil enhed (f.eks. en QA-tester, der har kørt din app på en iPhone og sendt dig logfilen). For at finde din projektmappe kan du åbne dit projektbibliotek i Epic Games launcher, højreklikke på det pågældende projekt og derefter vælge "Show in Folder"-muligheden.
2. Output Log Fanen i Unreal Editor
Du kan se logoutputtet i realtid, mens du spiller i Editor, i fanen "Output Log". Hvis den ikke er åben som standard, kan du finde den under Window -> Developer Tools -> Output Log i UE4 og under Window -> Output Log i UE5. Ud over realtidslogning vil denne fane også gemme alle logoplysninger fra alle spillesessioner, der fandt sted under den aktuelle Unreal Editor-session. Dette er din primære kilde til øjeblikkelig feedback under udvikling.
3. Kørbar Fil med -Log Parameter
Hvis du har en kørbar fil (f.eks. en pakket build af dit spil), kan du oprette en genvej med -Log i slutningen af navnet for at åbne loggen, når du starter den eksekverbare fil. Dette er nyttigt for at fejlfinde standalone-builds på din computer, før de implementeres på mobile enheder.
4. Konsollen i Spillet
Du kan åbne konsollen, når dit spil kører, ved at trykke på tilde (~) tasten og få adgang til loggen ved at skrive konsolkommandoen showlog og trykke Enter. Bemærk, at hvis du gør dette under en Play-In-Editor-session, vil et klik på 'x' for at lukke loggen lukke din Unreal Editor-session. Denne metode giver dig mulighed for at inspicere logs direkte i spillet, hvilket kan være praktisk til hurtige checks uden at forlade spilvinduet.
Log Detaljeringsniveauer (Verbosity Levels)
I visse tilfælde er det nyttigt at se et mindre eller mere detaljeret logoutput. Log detaljeringsniveauer giver nem kontrol over detaljeringsgraden i en given log. Hvis et bestemt logudsagn er mere detaljeret end den kompileringstidsdetaljeringsgrad, vil det ikke blive kompileret ind i spilkoden. Derefter indstilles niveauet for hele loggen til standard detaljeringsgraden, som kan ændres i Engine.ini-filen. Køretidsdetaljeringsgraden kan ændres via kommandolinjen. Givet et bestemt detaljeringsniveau for loggen, vil kun logbeskeder med matchende eller lavere detaljeringsniveau blive udskrevet til den. Beskeder med et højere detaljeringsniveau vil blive ignoreret. Dette er særligt vigtigt for mobiludvikling, hvor unødvendige logs kan påvirke ydeevnen og fylde lagerpladsen unødigt op.
Følgende tabel viser alle tilgængelige detaljeringsniveauer, fra laveste detaljegrad til højeste:
| Detaljeringsniveau | Udskrives i Konsol? | Udskrives i Editors Log? | Bemærkninger |
|---|---|---|---|
| Fatal | Ja | N/A | Lukker sessionen ned, selvom logning er deaktiveret. Brug dette kun for kritiske, ugenoprettelige fejl. |
| Error | Ja | Ja | Logtekst er farvet rød. Indikerer en fejl, der forhindrer en funktion i at virke korrekt, men ikke nødvendigvis et nedbrud. |
| Warning | Ja | Ja | Logtekst er farvet gul. Indikerer potentielle problemer, der bør undersøges, men som ikke forhindrer kørsel. |
| Display | Ja | Ja | Logtekst er farvet grå. Generelle meddelelser, der er nyttige for brugeren eller udvikleren. |
| Log | Nej | Ja | Logtekst er farvet grå. Standard logmeddelelser, typisk brugt til generel information under udvikling. |
| Verbose | Nej | Nej | Meget detaljeret. Bruges til dybdegående fejlfinding af specifikke systemer. |
| VeryVerbose | Nej | Nej | Ekstremt detaljeret. Kun til de mest intense fejlfindingsscenarier, typisk under en kort periode. |
Hvert logudsagn erklærer, hvilken logkategori det tilhører, samt dets detaljeringsniveau. Dette giver dig finmasket kontrol over, hvilke oplysninger der optages, og er afgørende for at holde dine logfiler overskuelige, især på mobile enheder med begrænset lagerplads og ydeevne.
Ændring af Standard Log Detaljeringsgrad
Via Engine.ini
Detaljeringsindstillinger for hver logkategori kan indstilles i enten Engine.ini eller DefaultEngine.ini. Dette er en god måde at sætte standardniveauer for dit projekt:
[Core.Log] Global= LogCategoryName=For eksempel, for at indstille LogTemp til at vise advarsler som standard, ville du skrive:
[Core.Log] LogTemp=WarningDette giver dig mulighed for at tilpasse logoutputtet til dine specifikke behov for forskellige builds, f.eks. en mindre detaljeret log for en release-build til iPhone.
Via Kommandolinjeparameter
Detaljeringsindstillinger for hver logkategori kan også indstilles via en kommandolinjeparameter, der sendes, når spillet eller editoren startes. I slutningen af den kommandolinje, der bruges til at starte din kørbar fil, skal du tilføje følgende flag:
-LogCmds="global Verbose, LogPython Verbose, LogAnimMontage off, LogDeepDriveAgent VeryVerbose"Denne metode er yderst fleksibel for testformål, da du kan ændre logadfærd uden at genkompilere eller ændre konfigurationsfiler. For eksempel, når du tester en specifik funktion på en mobil enhed via en udviklingsbuild, kan du starte den med et højt detaljeringsniveau for en bestemt kategori.
Ændring af Log Detaljeringsgrad ved Kørselstid
Detaljeringsindstillinger for hver logkategori kan også indstilles via konsolkommando ved kørselstid. Mens spillet kører, åbn konsollen og kør en kommando med følgende format:
log <CategoryName> <VerbosityLevel>Eksempel:
log LogTemp VerboseDette er ideelt til at justere logoutputtet dynamisk under en testsession, f.eks. når du har brug for at grave dybt ned i et problem, der kun opstår under specifikke omstændigheder på en mobil enhed.
Brugerdefinerede Logkategorier
Oprettelse af dine egne logkategorier vil gøre det meget lettere at parse dine logfiler, da du kan slå synligheden af logkategorier til og fra i "Output Log"-vinduet. Det er normalt en god idé at oprette en ny logkategori for hvert større system i dit projekt, f.eks. en proceduremæssig niveaugenerator, eller måske for din spiltilstand. For mobiludvikling kan dette være særligt nyttigt til at adskille logs fra touch-input, batteristyring, netværkskommunikation eller enheds-specifikke integrationer.
Du kan definere en ny logkategori ved at placere disse to kodebidder, hvor du har brug for at bruge denne logkategori. Du kunne placere disse i deres egen fil og inkludere den, hvor du har brug for den. Disse bør være på topniveauet af din kode, ikke inde i funktioner eller klasser.
Header Fil (.h)
DECLARE_LOG_CATEGORY_EXTERN(LogCustom, Log, All);Cpp Fil (.cpp)
DEFINE_LOG_CATEGORY(LogCustom);Syntaksen for header-filen er DECLARE_LOG_CATEGORY_EXTERN(CategoryName, DefaultVerbosity, CompileTimeVerbosity). DefaultVerbosity er detaljeringsniveauet, der bruges, når et ikke er specificeret i ini-filerne eller på kommandolinjen. Alt, der er mere detaljeret end dette, vil ikke blive logget. CompileTimeVerbosity er den maksimale detaljeringsgrad, der skal kompileres i koden. Alt, der er mere detaljeret end dette, vil ikke blive kompileret. Værdierne i eksemplet ovenfor er et godt udgangspunkt for din logkategori.
Det er almindeligt at se logkategorier præfikset med Log, men det er ikke et krav. At følge denne konvention vil give dig mulighed for nemt at sortere logkategorier alfabetisk. Brug af en anden CompileTimeVerbosity end All udskriver muligvis ikke dine logs i Output Log, så vær forsigtig med at ændre dette.
Udskrivning af Beskeder til Skærmen
Strengt taget tæller udskrivning af en besked til skærmen under kørsel ikke som logning, da beskeden ikke gemmes i en fil. Men det er ofte mere bekvemt end at bruge en logbesked under udvikling og/eller fejlfinding, da det giver dig mulighed for at se beskeden i spilvinduet uden at skulle have et separat vindue åbent for loggen. Alt fra variabelværdier i realtid til funktionskaldsorden kan nemt ses på denne måde. Dette er dog mindre praktisk på en mobil enhed, medmindre du tester i editor.
Her er et eksempel på en simpel strengbesked:
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::White, TEXT("Denne besked vil vises på skærmen!"));Parametrene er som følger:
- Nøgle (Key): Hvis nøglen er sat til
-1, tilføjes en ny besked til skærmen, hver gang denne kodelinje udføres. Hvis nøglen er et positivt heltal (typen eruint64), erstatter hver ny besked den tidligere besked med den samme nøgle. - Tid (Time): Varigheden (i sekunder) som beskeden vil blive vist. Type:
float. - Farve (Color): En
FColor, der bestemmer tekstens farve. Brug foruddefinerede konstanter somFColor::Whitefor nem læsning. - Besked (Message): Selve beskeden. Hele strengen skal kun fylde én parameter, derfor kræver udskrivning med
printf-parametre brug afFString::Printf():GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Nogle variabelværdier: x = %f, y = %f"), x, y));
AddOnScreenDebugMessage() har yderligere to valgfrie parametre: en boolean, der bestemmer, om nye beskeder vises øverst (hvis sand) eller nederst (hvis falsk), og en 2D-vektor, der bestemmer tekstens skala. Dette er nyttigt, hvis beskederne er for små eller for store.
Visual Studio kan understrege GEngine og hævde, at den er udefineret. Du behøver dog ikke eksplicit at inkludere Engine.h eller EngineGlobals.h for at bruge den i nogen af dine klasser. Den bør kompilere og fungere fint trods den røde understregning.
Tilføjelse af Beskeder til Viewport Stats Subsystem
Unreal Engine 4.26 introducerede Viewport Stats Subsystem, som giver mulighed for at tilføje beskeder til den aktuelle viewport, såsom "LIGHTING NEEDS TO BE REBUILT" og "BLUEPRINT COMPILE ERROR". Dette er mere et system-niveau værktøj, men kan være relevant for at informere udviklere om visuelle eller kompileringsrelaterede problemer. Her er et kodeeksempel:
if (UViewportStatsSubsystem* ViewportSubsystem = GetWorld()->GetSubsystem()) { FViewportDisplayCallback Callback; Callback.BindDynamic(this, &UCustomClass::DisplayViewportMessage); ViewportSubsystem->AddDisplayDelegate(Callback); ViewportSubsystem->AddDisplayDelegate([](FText& OutText, FLinearColor& OutColor) { OutText = NSLOCTEXT("FooNamespace", "Blarg", "Vis besked her"); OutColor = FLinearColor::Red; return bShouldDisplay; }); }Du kan inspicere denne klasse for at tjekke alle tilgængelige muligheder. Dette er et mere avanceret brugstilfælde, der typisk ikke bruges til generel fejlfinding, men snarere til at give systemrelaterede statusopdateringer.
Ofte Stillede Spørgsmål om Logning i Unreal Engine
- Hvordan finder jeg ud af, om en besked er logget i Unreal?
- Du kan observere dine logs i Unreal Editor ved at navigere til
Window > Output Log. Output Log-vinduet er din primære kilde til realtidsinformation. Alternativt kan du finde logfiler for tidligere sessioner i mappenYourProjectName\Saved\Logs. For mobiludvikling kan disse logfiler også hentes fra enheden efter en testsession. - Hvorfor er logning vigtigt for mobiludvikling i Unreal Engine?
- Logning er særligt vigtigt for mobiludvikling, fordi direkte debugging på enheder som iPhones eller Android-telefoner kan være besværligt. Logfiler giver dig en detaljeret oversigt over, hvad der skete under en kørsel, selv efter et nedbrud. De hjælper dig med at identificere ydeevneproblemer, hukommelseslækager, unormale adfærdsmønstre og enhedsspecifikke fejl, som ellers ville være svære at diagnosticere uden for editoren.
- Kan jeg se logs fra en iPhone/Android-enhed direkte i Unreal Editor?
- Unreal Editor's Output Log viser logs fra PIE-sessioner og builds, der kører på din computer. For at se logs fra en faktisk iPhone eller Android-enhed skal du typisk bruge enhedsspecifikke værktøjer som Xcode Organizer (for iOS) eller Android Studio's Logcat (for Android). Du kan også konfigurere dit projekt til at gemme logfiler på enheden, som derefter kan trækkes ud til analyse på din computer (f.eks. fra
Saved/Logsmappen på enheden). - Hvad er den primære forskel mellem UE_LOG og UE_LOGFMT?
UE_LOGer den ældre makro, der kræver brug afTEXT()til strenglitteraler og specifikkeprintf-formateringsspecifiers for forskellige datatyper.UE_LOGFMT(tilgængelig fra UE 5.2) er en mere moderne og brugervenlig makro, der understøtter struktureret logning, automatisk håndtering af strenglitteraler og variabeltyper samt navngivne eller positionelle parametre. Dette gør koden renere og logbeskederne lettere at læse og vedligeholde.- Hvordan kan jeg oprette mine egne logkategorier, og hvorfor skulle jeg gøre det?
- Du opretter dine egne logkategorier ved at bruge
DECLARE_LOG_CATEGORY_EXTERNi en headerfil ogDEFINE_LOG_CATEGORYi en C++-fil. Dette er en god praksis for at organisere dine logs efter system eller funktionalitet (f.eks.LogPlayerMovement,LogUI,LogNetwork). Egne kategorier giver dig mulighed for selektivt at aktivere eller deaktivere logoutput for specifikke dele af dit spil, hvilket er uvurderligt for at holde logfilerne overskuelige og reducere "støj", især under intensive fejlfindingssessioner på mobile enheder.
Logning er en grundlæggende færdighed for enhver Unreal Engine-udvikler, og dens betydning forstærkes yderligere, når man arbejder med mobiludvikling. Ved at mestre de forskellige logningsmetoder og forstå, hvor og hvordan man får adgang til logdata, kan du effektivt diagnosticere problemer, optimere ydeevne og sikre en robust og stabil applikation på tværs af alle dine målplatforme, inklusiv iPhone.
Hvis du vil læse andre artikler, der ligner Logning i Unreal Engine: Din Guide til Mobiludvikling, kan du besøge kategorien Teknologi.
