diff --git a/Source/StudyFrameworkPlugin/Private/GazeTracking/SFGazeTracker.cpp b/Source/StudyFrameworkPlugin/Private/GazeTracking/SFGazeTracker.cpp
index 615f974285bbd220573f5d032064aabf8bb6e52c..9838a59422f8f2b8abb1982e5fcb31f7916d5f09 100644
--- a/Source/StudyFrameworkPlugin/Private/GazeTracking/SFGazeTracker.cpp
+++ b/Source/StudyFrameworkPlugin/Private/GazeTracking/SFGazeTracker.cpp
@@ -1,5 +1,5 @@
 #include "GazeTracking/SFGazeTracker.h"
-
+#include "Logging/SFLoggingBPLibrary.h"
 #include "SFGameInstance.h"
 #include "GazeTracking/SFGazeTarget.h"
 #include "GazeTracking/SFGazeTargetActor.h"
@@ -26,7 +26,7 @@ void USFGazeTracker::Init(EGazeTrackerMode Mode)
 		}
 		else
 		{
-			USFGameInstance::Get()->LogComment("No Vive Pro Eye present, use head rotation only for gaze tracking.");
+			USFLoggingBPLibrary::LogComment("No Vive Pro Eye present, use head rotation only for gaze tracking.", true);
 		}
 #else
 		FSFUtils::OpenMessageBox("SRanipal Plugin is not present, cannot use eye tracking! Check out, e.g., StudyFramework Wiki where to get it", true);
@@ -34,10 +34,11 @@ void USFGazeTracker::Init(EGazeTrackerMode Mode)
 	}
 }
 
-FGazeRay USFGazeTracker::GetGazeDirection()
+FGazeRay USFGazeTracker::GetLocalGazeDirection()
 {
-	if(!IsTrackingEyes())
+	if(!bEyeTrackingStarted)
 	{
+		// if no eye tracker is used we always "look ahead"
 		FGazeRay GazeRay;
 		GazeRay.Origin = FVector::ZeroVector;
 		GazeRay.Direction = FVector::ForwardVector;;
@@ -54,29 +55,52 @@ FGazeRay USFGazeTracker::GetGazeDirection()
 	return GazeRay;
 }
 
-FString USFGazeTracker::GetCurrentGazeTarget()
+FGazeRay USFGazeTracker::GetWorldGazeDirection()
 {
-	FString GazedAtTarget = "";
-	const float Distance = 1000.0f;
-
-	FGazeRay GazeRay = GetGazeDirection();
-	// if no eye tracker is used we always "look ahead"
-	// GazeDirection = FVector(1,0,0);
+	FGazeRay LocalGazeRay = GetLocalGazeDirection();
 
 	UWorld* World = USFGameInstance::Get()->GetWorld();
 
 	//the gaze ray is relative to the HMD
 	const APlayerCameraManager* CamManager = World->GetFirstPlayerController()->
-	                                                                 PlayerCameraManager;
+		PlayerCameraManager;
 	const FVector CameraLocation = CamManager->GetCameraLocation();
 	const FRotator CameraRotation = CamManager->GetCameraRotation();
-	const FVector RayCastOrigin = CameraLocation + CameraRotation.RotateVector(GazeRay.Origin);
-	const FVector RayCastEnd = (CameraRotation.RotateVector(GazeRay.Direction) * Distance) + RayCastOrigin;
+
+	FGazeRay GazeRay;
+	GazeRay.Origin = CameraLocation + CameraRotation.RotateVector(LocalGazeRay.Origin);
+	GazeRay.Direction = CameraRotation.RotateVector(LocalGazeRay.Direction);
+
+	return GazeRay;
+}
+
+FString USFGazeTracker::GetCurrentGazeTarget()
+{
+	FString GazedAtTarget = "";
+	const float Distance = 1000.0f;
+
+	FGazeRay GazeRay = GetWorldGazeDirection();
+
+
+	const FVector RayCastOrigin = GazeRay.Origin;
+	const FVector RayCastEnd = (GazeRay.Direction * Distance) + RayCastOrigin;
 
 	//FSFUtils::Log("Cast Ray from "+RayCastOrigin.ToString()+" to "+RayCastEnd.ToString());
 
 	FHitResult HitResult;
-	World->LineTraceSingleByChannel(HitResult, RayCastOrigin, RayCastEnd, EYE_TRACKING_TRACE_CHANNEL);
+	UWorld* World = USFGameInstance::Get()->GetWorld();
+	FCollisionQueryParams QueryParams;
+	QueryParams.AddIgnoredActor(World->GetFirstPlayerController()->AcknowledgedPawn);
+	QueryParams.AddIgnoredActor(USFGameInstance::Get()->GetHUD()->GetHUDHelper());
+
+	World->LineTraceSingleByChannel(HitResult, RayCastOrigin, RayCastEnd, EYE_TRACKING_TRACE_CHANNEL, QueryParams);
+
+	if (bDebugRenderRayTraces)
+	{
+		//this line trace is more comfortable for debug drawing, however has problems with channel tracing, so we use LineTraceSingleByChannel() above
+		FHitResult TmpHitRes;
+		UKismetSystemLibrary::LineTraceSingle(World, RayCastOrigin, RayCastEnd, ETraceTypeQuery::TraceTypeQuery4, false, {}, EDrawDebugTrace::ForDuration, TmpHitRes, true);
+	}
 
 
 	if (HitResult.bBlockingHit)
@@ -104,17 +128,22 @@ FString USFGazeTracker::GetCurrentGazeTarget()
 void USFGazeTracker::LaunchCalibration()
 {
 #ifdef WITH_SRANIPAL
-	//TODO: not tested yet!
 	ViveSR::anipal::Eye::LaunchEyeCalibration(nullptr);
 #endif
 }
 
 bool USFGazeTracker::IsTrackingEyes()
 {
-	//TODO: maybe use
-	//#ifdef WITH_SRANIPAL
-	//ViveSR::anipal::AnipalStatus Status;
-	//int Error = ViveSR::anipal::GetStatus(ViveSR::anipal::Eye::ANIPAL_TYPE_EYE_V2, &Status);
-	//#endif
-	return bEyeTrackingStarted;
+	if (!bEyeTrackingStarted)
+		return false;
+
+#ifdef WITH_SRANIPAL
+	ViveSR::anipal::Eye::EyeData_v2 Data;
+	ViveSR::anipal::Eye::GetEyeData_v2(&Data);
+
+	//no_user apparently is true, when a user is there... (weird but consistent)
+	return Data.no_user;
+#endif
+
+	return true;
 }
diff --git a/Source/StudyFrameworkPlugin/Private/HUD/SFMasterHUD.cpp b/Source/StudyFrameworkPlugin/Private/HUD/SFMasterHUD.cpp
index 516bbd0361f3dd43cd962d494902a31c397bb359..70cb6b3a7d01edc16bcfda71db5ad32f18b22948 100644
--- a/Source/StudyFrameworkPlugin/Private/HUD/SFMasterHUD.cpp
+++ b/Source/StudyFrameworkPlugin/Private/HUD/SFMasterHUD.cpp
@@ -243,3 +243,7 @@ void ASFMasterHUD::OnShowConditionsButtonPressed()
 		}
 	}
 }
+
+const ASFHMDSpectatorHUDHelp* ASFMasterHUD::GetHUDHelper() {
+	return HMDHUDHelper;
+}
diff --git a/Source/StudyFrameworkPlugin/Private/Logging/SFLogObject.cpp b/Source/StudyFrameworkPlugin/Private/Logging/SFLogObject.cpp
index 9fd1adc7703af844e628de2238e8520fdc7b1bc7..53568658e6068dd04b368f9feb31c27b08fcf33c 100644
--- a/Source/StudyFrameworkPlugin/Private/Logging/SFLogObject.cpp
+++ b/Source/StudyFrameworkPlugin/Private/Logging/SFLogObject.cpp
@@ -50,7 +50,7 @@ void USFLogObject::Initialize() {
 }
 
 // NOTE: When changing header row, update output (see below)
-void USFLogObject::LogHeaderRows() {
+void USFLogObject::WritePositionLogHeaderRow() {
 	FString PositionLogHeader = FString("ElapsedTime") +
 		"\t" + FString("LogName") +
 		"\t" + FString("Condition") +
@@ -63,7 +63,7 @@ void USFLogObject::LogHeaderRows() {
 	UniLog.Log(PositionLogHeader, "PositionLog");
 }
 
-void USFLogObject::LoggingLoopsLogToFile() {
+void USFLogObject::WritePositionLogToFile() {
 	if (!USFGameInstance::Get() || !USFGameInstance::Get()->GetLogObject())
 	{
 		return;
@@ -73,14 +73,14 @@ void USFLogObject::LoggingLoopsLogToFile() {
 		if (ComponentLoggingInfo.LogNextTick == true) {
 			ComponentLoggingInfo.LogNextTick = false;
 			//When starting in Debug-Mode (i.e. not through the HUD) no condition is defined. 
-			FString currentCondition = USFGameInstance::Get()->GetParticipant()->GetCurrentCondition() ?
+			FString CurrentCondition = USFGameInstance::Get()->GetParticipant()->GetCurrentCondition() ?
 				USFGameInstance::Get()->GetParticipant()->GetCurrentCondition()->UniqueName :
 				FString("Debug");
 			// NOTE: When changing output, update header row (see above)
 
 			FString out = USFGameInstance::Get()->GetParticipant()->GetCurrentTime() +
 				"\t" + ComponentLoggingInfo.LogName +
-				"\t" + currentCondition +
+				"\t" + CurrentCondition +
 				"\t" + FString::Printf(TEXT("%.3f"), ComponentLoggingInfo.ComponentToLog->GetComponentLocation().X) +
 				"\t" + FString::Printf(TEXT("%.3f"), ComponentLoggingInfo.ComponentToLog->GetComponentLocation().Y) +
 				"\t" + FString::Printf(TEXT("%.3f"), ComponentLoggingInfo.ComponentToLog->GetComponentLocation().Z) +
@@ -99,6 +99,45 @@ void USFLogObject::LoggingLoopsLogToFile() {
 	}
 }
 
+// NOTE: When changing header row, update output (see below)
+void USFLogObject::WriteGazeTrackingLogHeaderRow() {
+	FString GazeTrackingLogHeader = FString("ElapsedTime") +
+		"\t" + FString("Condition") +
+		"\t" + FString("TrackingEyes") +
+		"\t" + FString("GazeTarget") +
+		"\t" + FString("Gaze-Origin-X-Y-Z") +
+		"\t" + FString("Gaze-Direction-X-Y-Z");
+	UniLog.Log(GazeTrackingLogHeader, "GazeTrackingLog");
+}
+
+void USFLogObject::WriteGazeTrackingLogToFile() {
+	if (!USFGameInstance::Get() || !USFGameInstance::Get()->GetGazeTracker())
+	{
+		return;
+	}
+	USFGazeTracker* GazeTracker = USFGameInstance::Get()->GetGazeTracker();
+	FString GazeTarget = GazeTracker->GetCurrentGazeTarget() == "" ? "-" : GazeTracker->GetCurrentGazeTarget();
+	//When starting in Debug-Mode (i.e. not through the HUD) no condition is defined. 
+	FString CurrentCondition = USFGameInstance::Get()->GetParticipant()->GetCurrentCondition() ?
+								USFGameInstance::Get()->GetParticipant()->GetCurrentCondition()->UniqueName :
+								FString("Debug");
+	FString isTrackingEyes = USFGameInstance::Get()->GetGazeTracker()->IsTrackingEyes() ? "1" : "0";
+	// NOTE: When changing output, update header row (see above)
+	FString out = USFGameInstance::Get()->GetParticipant()->GetCurrentTime() +
+		"\t" + CurrentCondition +
+		"\t" + isTrackingEyes +
+		"\t" + GazeTarget +
+		"\t" + FString::Printf(TEXT("%.3f"), GazeTracker->GetWorldGazeDirection().Origin.X) +
+		"\t" + FString::Printf(TEXT("%.3f"), GazeTracker->GetWorldGazeDirection().Origin.Y) +
+		"\t" + FString::Printf(TEXT("%.3f"), GazeTracker->GetWorldGazeDirection().Origin.Z) +
+		"\t" + FString::Printf(TEXT("%.3f"), GazeTracker->GetWorldGazeDirection().Direction.X) +
+		"\t" + FString::Printf(TEXT("%.3f"), GazeTracker->GetWorldGazeDirection().Direction.Y) +
+		"\t" + FString::Printf(TEXT("%.3f"), GazeTracker->GetWorldGazeDirection().Direction.Z);
+	if (UniLog.GetLogStream("GazeTrackingLog"))
+	{
+		UniLog.Log(out, "GazeTrackingLog");
+	}
+}
 
 void USFLogObject::SetLoggingLoopsActive(bool LoggingLoopsActive) {
 	bLoggingLoopsActive = LoggingLoopsActive;
diff --git a/Source/StudyFrameworkPlugin/Private/Logging/SFLoggingUtils.cpp b/Source/StudyFrameworkPlugin/Private/Logging/SFLoggingUtils.cpp
index 902807a42a747de67fa0b9c5f3bad2f08bad91eb..0968565382b0eadade7454220cd06ec46b712070 100644
--- a/Source/StudyFrameworkPlugin/Private/Logging/SFLoggingUtils.cpp
+++ b/Source/StudyFrameworkPlugin/Private/Logging/SFLoggingUtils.cpp
@@ -34,7 +34,7 @@ void FSFLoggingUtils::SetupLoggingStreams()
 	ILogStream* SFLog = UniLog.NewLogStream("SFLog", "StudyFramework/DebuggingLogs", "SFLog.txt", false);
 	SFLog->SetLogToDefaultLog(true);
 
-	//ParticipantLog, PositionLog are set up in Participant init function
+	//ParticipantLog, PositionLog, GazeTrackingLog are set up in SFParticipant::SetupLoggingStreams() function
 
 	ILogStream* SFErrorLog = UniLog.NewLogStream("SFErrorLog", "StudyFramework/DebuggingLogs", "SFLog.txt", false);
 	SFErrorLog->SetLogToDefaultLog(true);
diff --git a/Source/StudyFrameworkPlugin/Private/SFGameInstance.cpp b/Source/StudyFrameworkPlugin/Private/SFGameInstance.cpp
index 544162630c1c918571bf89d29101e9c3c2d54f62..830f7a03da55920beed38316fd09d01eb58c58ea 100644
--- a/Source/StudyFrameworkPlugin/Private/SFGameInstance.cpp
+++ b/Source/StudyFrameworkPlugin/Private/SFGameInstance.cpp
@@ -131,10 +131,14 @@ void USFGameInstance::RestoreLastParticipantForDebugStart(USFCondition* InStartC
 	const int ParticipantID = USFParticipant::GetLastParticipantId();
 	Participant = NewObject<USFParticipant>(this,
 	                                        FName(TEXT("Participant_") + FString::FromInt(ParticipantID)));
+	
+	StudySetup = USFParticipant::GetLastParticipantSetup();
+
 	Participant->Initialize(ParticipantID);
+	Participant->SetupLoggingStreams(StudySetup->UseGazeTracker != EGazeTrackerMode::NotTracking);
 	Participant->LoadConditionsFromJson();
 
-	StudySetup = USFParticipant::GetLastParticipantSetup();
+	
 	InitFadeHandler(StudySetup->FadeConfig);
 
 	StartCondition = InStartCondition;
@@ -240,6 +244,7 @@ void USFGameInstance::PrepareWithStudySetup(ASFStudySetup* Setup)
 	Participant = NewObject<USFParticipant>(this,
 	                                        FName(TEXT("Participant_") + FString::FromInt(ParticipantID)));
 	Participant->Initialize(ParticipantID);
+	Participant->SetupLoggingStreams(StudySetup->UseGazeTracker != EGazeTrackerMode::NotTracking);
 	Participant->SetStudyConditions(Conditions);
 
 	if (bRecoverParticipantData)
@@ -531,7 +536,8 @@ USFParticipant* USFGameInstance::GetParticipant() const
 bool USFGameInstance::LogTick(float DeltaSeconds)
 {
 	if (LogObject->bLoggingLoopsActive){
-		LogObject->LoggingLoopsLogToFile();
+		LogObject->WritePositionLogToFile();
+		LogObject->WriteGazeTrackingLogToFile();
 	}	
 	return true;
 }
diff --git a/Source/StudyFrameworkPlugin/Private/SFParticipant.cpp b/Source/StudyFrameworkPlugin/Private/SFParticipant.cpp
index fe59cf900641b3b4955a1573547a99e87f7838c8..96a4a2465fb94d82b8676faa78e1b53f40dfdb06 100644
--- a/Source/StudyFrameworkPlugin/Private/SFParticipant.cpp
+++ b/Source/StudyFrameworkPlugin/Private/SFParticipant.cpp
@@ -18,30 +18,37 @@ USFParticipant::~USFParticipant()
 {
 }
 
-bool USFParticipant::Initialize(int Participant, bool bSetIdOnly /*= false*/)
+bool USFParticipant::Initialize(int Participant)
 {
 	ParticipantID = Participant;
-	if(bSetIdOnly)
-	{
-		return true;
-	}
 
+	StartTime = FPlatformTime::Seconds();
+
+	return true;
+}
 
+void USFParticipant::SetupLoggingStreams(bool bGazeTracking)
+{
 	const FString Timestamp = FDateTime::Now().ToString();
 	const FString Filename = "LogParticipant-" + FString::FromInt(ParticipantID) + "_" + Timestamp + ".txt";
 	ILogStream* ParticipantLog = UniLog.NewLogStream("ParticipantLog", "StudyFramework/StudyLogs/ParticipantLogs",
-	                                                 Filename, false);
+		Filename, false);
 	ILogStream* PositionLog = UniLog.NewLogStream("PositionLog", "StudyFramework/StudyLogs/PositionLogs",
-		"Position"+Filename, false);
+		"Position" + Filename, false);
+	if (bGazeTracking)
+	{
+		ILogStream* GazeTrackingLog = UniLog.NewLogStream("GazeTrackingLog", "StudyFramework/StudyLogs/GazeTrackingLogs",
+			"GazeTracking" + Filename, false);
+	}
 	if (USFGameInstance::Get())
 	{
-		USFGameInstance::Get()->GetLogObject()->LogHeaderRows();
+		USFGameInstance::Get()->GetLogObject()->WritePositionLogHeaderRow();
+		USFGameInstance::Get()->GetLogObject()->WriteGazeTrackingLogHeaderRow();
 	}
 	else
 	{
 		FSFLoggingUtils::Log("GameInstance not set up yet, no header rows are written to participant logs.");
 	}
-	return true;
 }
 
 void USFParticipant::SetStudyConditions(TArray<USFCondition*> NewConditions)
diff --git a/Source/StudyFrameworkPlugin/Private/SFStudySetup.cpp b/Source/StudyFrameworkPlugin/Private/SFStudySetup.cpp
index 5ac661fa18e6d8431ae03a6e26d00904fe871686..684c0af6f4d8f3405be0d22dc3c387ca2a9fb390 100644
--- a/Source/StudyFrameworkPlugin/Private/SFStudySetup.cpp
+++ b/Source/StudyFrameworkPlugin/Private/SFStudySetup.cpp
@@ -148,7 +148,7 @@ void ASFStudySetup::GenerateTestStudyRuns() const
 	{
 		const TArray<USFCondition*> Conditions = GetAllConditionsForRun(ParticipantID);
 		USFParticipant* TmpParticipant = NewObject<USFParticipant>();
-		TmpParticipant->Initialize(ParticipantID, true);
+		TmpParticipant->Initialize(ParticipantID);
 		TmpParticipant->SetStudyConditions(Conditions); //this also saves it to json
 	}
 }
diff --git a/Source/StudyFrameworkPlugin/Public/GazeTracking/SFGazeTracker.h b/Source/StudyFrameworkPlugin/Public/GazeTracking/SFGazeTracker.h
index 96b9bc0ef29e28a141b06435086a33987bef0ae0..0aee44bfbe668752aa01845d6a2f379aae629704 100644
--- a/Source/StudyFrameworkPlugin/Public/GazeTracking/SFGazeTracker.h
+++ b/Source/StudyFrameworkPlugin/Public/GazeTracking/SFGazeTracker.h
@@ -30,20 +30,28 @@ class STUDYFRAMEWORKPLUGIN_API USFGazeTracker : public UObject
 public:
 	void Init(EGazeTrackerMode Mode);
 
-	//returns pair of Origin and Direction, relative to the head!
+	//returns pair of Origin and Direction, in world coordinates
 	UFUNCTION(BlueprintCallable)
-	FGazeRay GetGazeDirection();
+	FGazeRay GetWorldGazeDirection();
 
 	//returns the name of the gaze target or empty string if none found or not tracking
 	UFUNCTION(BlueprintCallable)
 	FString GetCurrentGazeTarget();
 
+	//returns pair of Origin and Direction, relative to the head!
+	UFUNCTION(BlueprintCallable)
+	FGazeRay GetLocalGazeDirection();
+
 	UFUNCTION(BlueprintCallable)
 	void LaunchCalibration();
 
+	//whether currently the eyes are tracked, otherwise head-forward is used (this can change during execution if the HMD is taken off etc.)
 	UFUNCTION(BlueprintCallable)
 	bool IsTrackingEyes();
 
+	UPROPERTY(BlueprintReadWrite)
+	bool bDebugRenderRayTraces = false;
+
 private:
 
 	bool bEyeTrackingStarted = false;
diff --git a/Source/StudyFrameworkPlugin/Public/HUD/SFMasterHUD.h b/Source/StudyFrameworkPlugin/Public/HUD/SFMasterHUD.h
index a674f7537717505955c1b1a9d61631183c3adac9..5ab2e32cf670d73bab12c9c5c73d77758c8ece43 100644
--- a/Source/StudyFrameworkPlugin/Public/HUD/SFMasterHUD.h
+++ b/Source/StudyFrameworkPlugin/Public/HUD/SFMasterHUD.h
@@ -61,6 +61,8 @@ public:
 	UFUNCTION()
 	void OnShowConditionsButtonPressed();
 
+	const ASFHMDSpectatorHUDHelp* GetHUDHelper();
+
 protected:
 	UPROPERTY(VisibleAnywhere)
 	USFHUDWidget* HUDWidget;
diff --git a/Source/StudyFrameworkPlugin/Public/Logging/SFLogObject.h b/Source/StudyFrameworkPlugin/Public/Logging/SFLogObject.h
index d96088d7a5af7ca54e58d08f23db9ee89f8ae309..b44a2bbb8106acfc012ca459078870c6579211a6 100644
--- a/Source/StudyFrameworkPlugin/Public/Logging/SFLogObject.h
+++ b/Source/StudyFrameworkPlugin/Public/Logging/SFLogObject.h
@@ -65,7 +65,14 @@ public:
 	UFUNCTION()
 	bool GetLoggingLoopsActive();
 	UFUNCTION()
-		static void LogHeaderRows();
+		static void WritePositionLogHeaderRow();
 	UFUNCTION()
-		static void LoggingLoopsLogToFile();
+		static void WritePositionLogToFile();
+
+	UFUNCTION()
+		static void WriteGazeTrackingLogHeaderRow();
+
+	UFUNCTION()
+		static void WriteGazeTrackingLogToFile();
+
 };
diff --git a/Source/StudyFrameworkPlugin/Public/SFParticipant.h b/Source/StudyFrameworkPlugin/Public/SFParticipant.h
index 6294d62d61c37c228a487f016ea520db31d4048e..6a0f89e5c958aa848d5fa53aadad54a2782c71c6 100644
--- a/Source/StudyFrameworkPlugin/Public/SFParticipant.h
+++ b/Source/StudyFrameworkPlugin/Public/SFParticipant.h
@@ -28,7 +28,8 @@ public:
 	USFParticipant();
 	~USFParticipant();
 
-	bool Initialize(int Participant, bool bSetIdOnly = false);
+	bool Initialize(int Participant);
+	void SetupLoggingStreams(bool bGazeTracking);
 	void SetStudyConditions(TArray<USFCondition*> NewConditions);
 
 	bool StartStudy();