I’m working on an automated profiling system. We want to grab the PlayerCharacter’s Location and Rotation, so we can figure out the View Frustum, and make a heat map which draws a correspondence between a hitch, and where the PlayerCharacter was looking at the time.
Right now, we have automated performance working, and the (my) task is just to export the Player’s Location and Rotation in the CSV.
My attempt is like this:
// MyCsvProfileMacros.h
#pragma once
#include <ProfilingDebugging/CsvProfiler.h>
CSV_DECLARE_CATEGORY_EXTERN(MyPlayerCharacterStatCategory);
#define CSV_PROFILE_PLAYER_CHARACTER_LOCATION(StatVector) \
CSV_CUSTOM_STAT(MyPlayerCharacterStatCategory, PlayerCharacterLocation_X, StatVector.X, ECsvCustomStatOp::Set) \
CSV_CUSTOM_STAT(MyPlayerCharacterStatCategory, PlayerCharacterLocation_Y, StatVector.Y, ECsvCustomStatOp::Set) \
CSV_CUSTOM_STAT(MyPlayerCharacterStatCategory, PlayerCharacterLocation_Z, StatVector.Z, ECsvCustomStatOp::Set)
// NOTE: be sure to use an FVector, and not an FRotator
#define CSV_PROFILE_PLAYER_CHARACTER_ROTATION(StatVector) \
CSV_CUSTOM_STAT(MyPlayerCharacterStatCategory, PlayerCharacterRotation_X, StatVector.X, ECsvCustomStatOp::Set) \
CSV_CUSTOM_STAT(MyPlayerCharacterStatCategory, PlayerCharacterRotation_Y, StatVector.Y, ECsvCustomStatOp::Set) \
CSV_CUSTOM_STAT(MyPlayerCharacterStatCategory, PlayerCharacterRotation_Z, StatVector.Z, ECsvCustomStatOp::Set)
// MyWorkingGauntletController.cpp
#include "MyWorkingGauntletController.h"
#include <MyCsvProfileMacros.h>
CSV_DEFINE_CATEGORY(PlayerCharacterStat, false);
// ...
// Not Depicted: Gauntlet Controller manages starting and stopping the CsvProfile
void MyWorkingGauntletController::OnTick(float timeDelta_s)
{
if(m_bHasAllNeededResources && m_bIsProfiling)
{
if(APawn* pPawn = m_pPlayerController->GetPawn())
{
const FVector location = pPawn->GetActorLocation();
const FVector rotation = pPawn->GetActorRotation().Vector();
CSV_PROFILE_PLAYER_CHARACTER_LOCATION(location);
CSV_PROFILE_PLAYER_CHARACTER_ROTATION(rotation);
}
}
}
So, this is a depiction of the code I’m working with, but It reproduces the main points.
I know:
- One must Enable the CsvCategory—ideally using the INI file. I’ve done this by using the dev console, and by setting the CSV_DEFINE_CATEGORY macro to true
- And not both at the same time, turning it on, then off again
- CsvProfile documents are being generated
- I am cooking a new packaged build to test changes
- The IDE reports compiling my changes into the new binaries
- I am using the new package build to test changes
- When I attach to the running Game process, I can “catch” the execution in the “OnTick” fn depicted above, and see the location and rotation values, and they seem correct
What I think should happen:
I am anticipating the CsvProfile document to contain columns like:
- MyPlayerCharacterStatCategory/PlayerCharacterLocation_X
- MyPlayerCharacterStatCategory/PlayerCharacterLocation_Y
- etc…
And I anticipate those columns to just hold the value from the time it was measured, (not accruing over time).
What is happening now:
None of this stuff is output in my CsvProfile.csv. The existing system works as it has been, but none of these changes show up.
What do?
I don’t know if this is the right approach, and even if it is the right approach, I can’t tell what I’m doing wrong.
Strictly speaking, it doesn’t have to be in the CsvProfile, but there is enough existing infrastructure (in my personal situation) to make it seem worth doing.
Would appreciate any advice, suggestions, threats, or accusations.
Thank you for undertaking the effort of reading this madness.