Heavy Performance adjustments, mainly by switching all async functions to Unitask tasks

This commit is contained in:
Thorbjoern
2025-06-21 00:20:24 +02:00
parent 8566fb5fa2
commit 6d870ef608
6 changed files with 813 additions and 653 deletions
+1 -1
View File
@@ -111,7 +111,7 @@ Material:
- _DstBlend: 0 - _DstBlend: 0
- _DstBlendAlpha: 0 - _DstBlendAlpha: 0
- _EnvironmentReflections: 1 - _EnvironmentReflections: 1
- _FadeColorBlend: 0.004822666 - _FadeColorBlend: 0.004828562
- _ForceEye: 0 - _ForceEye: 0
- _GlossMapScale: 0 - _GlossMapScale: 0
- _Glossiness: 0 - _Glossiness: 0
File diff suppressed because it is too large Load Diff
+24
View File
@@ -28,6 +28,30 @@ namespace GhostSystem
[Column("rotation")] [Column("rotation")]
public string RotationJson { get; set; } // stored as JSONB public string RotationJson { get; set; } // stored as JSONB
public static FrameModel FromGhostFrame(GhostFrame frame)
{
return new FrameModel
{
UserId = SupabaseManager.instance.userId,
SceneId = frame.SceneId,
ObjectId = frame.ObjectId,
Timestamp = frame.Timestamp.ToString("o"), // "o" für ISO 8601
PositionJson = JsonConvert.SerializeObject(new Vector3Serializable
{
x = frame.Position.x,
y = frame.Position.y,
z = frame.Position.z,
}),
RotationJson = JsonConvert.SerializeObject(new QuaternionSerializable
{
x = frame.Rotation.x,
y = frame.Rotation.y,
z = frame.Rotation.z,
w = frame.Rotation.w
})
};
}
[JsonIgnore] [JsonIgnore]
public DateTime TimestampParsed => DateTime.Parse(Timestamp).ToUniversalTime(); public DateTime TimestampParsed => DateTime.Parse(Timestamp).ToUniversalTime();
@@ -1,30 +1,39 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using System.Threading.Tasks; using Cysharp.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using Oculus.Interaction; using Oculus.Interaction;
using System.IO;
namespace GhostSystem namespace GhostSystem
{ {
public class GhostRecorderBatch : MonoBehaviour public class GhostRecorderBatch : MonoBehaviour
{ {
public bool test = false;
public string SceneId; public string SceneId;
public float SampleRate = 0.05f; public float SampleRate = 0.05f;
public int BatchSize = 10;
public float FlushInterval = 2f;
public List<Transform> TrackedObjects; public List<Transform> TrackedObjects;
private int doorCount; private int doorCount;
private float _timer; private float _sampleTimer;
public bool _isRecording; private float _flushTimer;
private bool _isRecording;
private bool supabaseReady = false; private bool supabaseReady = false;
private bool sceneIdReady = false; private bool sceneIdReady = false;
private readonly List<FrameModel> _frameBuffer = new();
private string _offlinePath;
public static event Action OnRecord; public static event Action OnRecord;
public static event Action OnStopRecord; public static event Action OnStopRecord;
private async void OnEnable() private void OnEnable()
{ {
SupabaseManager.OnSuperbaseReady += HandleSupabaseReady; SupabaseManager.OnSuperbaseReady += HandleSupabaseReady;
RoomManager.OnSceneIdReady += HandleSceneIdReady; RoomManager.OnSceneIdReady += HandleSceneIdReady;
@@ -36,6 +45,11 @@ namespace GhostSystem
RoomManager.OnSceneIdReady -= HandleSceneIdReady; RoomManager.OnSceneIdReady -= HandleSceneIdReady;
} }
private void Start()
{
_offlinePath = Path.Combine(Application.persistentDataPath, "offline_log.jsonl");
}
private void HandleSupabaseReady() private void HandleSupabaseReady()
{ {
supabaseReady = true; supabaseReady = true;
@@ -47,57 +61,82 @@ namespace GhostSystem
sceneIdReady = true; sceneIdReady = true;
foreach (GameObject door in doors) foreach (GameObject door in doors)
{ {
TrackedObjects.Add(door.GetComponentInChildren<OneGrabRotateTransformer>().gameObject.transform); var rotator = door.GetComponentInChildren<OneGrabRotateTransformer>();
if (rotator != null)
{
TrackedObjects.Add(rotator.transform);
doorCount++; doorCount++;
} }
} }
}
private async void Update() private void Update()
{ {
if (test) await TestInsert();
if (!_isRecording) return; if (!_isRecording) return;
_timer += Time.deltaTime; _sampleTimer += Time.deltaTime;
if (_timer >= SampleRate) _flushTimer += Time.deltaTime;
if (_sampleTimer >= SampleRate)
{
_sampleTimer = 0f;
RecordSample();
}
if (_frameBuffer.Count >= BatchSize || _flushTimer >= FlushInterval)
{
_flushTimer = 0f;
_ = FlushBatchAsync(); // Fire and forget
}
}
private void RecordSample()
{ {
_timer = 0f;
foreach (var obj in TrackedObjects) foreach (var obj in TrackedObjects)
{ {
var frame = new GhostFrame(SceneId, obj.name, obj.position, obj.rotation); var frame = new GhostFrame(SceneId, obj.name, obj.position, obj.rotation);
await InsertFrame(frame); _frameBuffer.Add(FrameModel.FromGhostFrame(frame));
} }
} }
private async UniTaskVoid FlushBatchAsync()
{
if (_frameBuffer.Count == 0 || !supabaseReady) return;
var batch = new List<FrameModel>(_frameBuffer);
_frameBuffer.Clear();
try
{
var response = await SupabaseManager.instance.supabase.From<FrameModel>().Insert(batch);
if (!response.ResponseMessage.IsSuccessStatusCode)
{
Debug.LogWarning($"Batch insert failed: {response.ResponseMessage.StatusCode}, fallback to offline.");
await FallbackToOfflineAsync(batch);
}
}
catch (Exception ex)
{
Debug.LogWarning($"Insert failed, fallback to offline: {ex.Message}");
await FallbackToOfflineAsync(batch);
}
} }
private async Task InsertFrame(GhostFrame frame) private async UniTask FallbackToOfflineAsync(List<FrameModel> batch)
{ {
var position = new Vector3Serializable try
{ {
x = frame.Position.x, using var writer = new StreamWriter(_offlinePath, append: true);
y = frame.Position.y, foreach (var model in batch)
z = frame.Position.z
};
var rotation = new QuaternionSerializable
{ {
x = frame.Rotation.x, string jsonLine = JsonConvert.SerializeObject(model);
y = frame.Rotation.y, await writer.WriteLineAsync(jsonLine);
z = frame.Rotation.z, }
w = frame.Rotation.w }
}; catch (Exception ex)
var data = new FrameModel
{ {
UserId = SupabaseManager.instance.userId, Debug.LogError($"Offline write failed: {ex.Message}");
SceneId = frame.SceneId, }
ObjectId = frame.ObjectId,
Timestamp = frame.Timestamp.ToString("o"),
PositionJson = JsonConvert.SerializeObject(position),
RotationJson = JsonConvert.SerializeObject(rotation)
};
//Debug.Log($"Insert frame with user_id: {SupabaseManager.instance.userId}");
await SupabaseManager.instance.supabase.From<FrameModel>().Insert(data);
} }
public void StartRecording() public void StartRecording()
@@ -114,28 +153,13 @@ namespace GhostSystem
sceneIdReady = false; sceneIdReady = false;
OnStopRecord?.Invoke(); OnStopRecord?.Invoke();
Debug.Log($"Stop recording: {SceneId}"); Debug.Log($"Stop recording: {SceneId}");
TrackedObjects.RemoveRange( TrackedObjects.Count - doorCount, doorCount );
doorCount = 0; if (doorCount > 0 && TrackedObjects.Count >= doorCount)
{
TrackedObjects.RemoveRange(TrackedObjects.Count - doorCount, doorCount);
} }
private async Task TestInsert() doorCount = 0;
{
var pos = new Vector3Serializable { x = 1f, y = 2f, z = 3f };
var rot = new QuaternionSerializable { x = 0f, y = 0f, z = 0f, w = 1f };
var data = new FrameModel
{
UserId = SupabaseManager.instance.userId,
SceneId = "testScene",
ObjectId = "testObject",
Timestamp = DateTime.UtcNow.ToString("o"),
PositionJson = JsonConvert.SerializeObject(pos),
RotationJson = JsonConvert.SerializeObject(rot)
};
Debug.Log(JsonConvert.SerializeObject(data)); // Schau hier, ob es nur Strings sind.
await SupabaseManager.instance.supabase.From<FrameModel>().Insert(data);
} }
} }
} }
+7 -3
View File
@@ -49,7 +49,7 @@ PlayerSettings:
defaultScreenHeight: 768 defaultScreenHeight: 768
defaultScreenWidthWeb: 960 defaultScreenWidthWeb: 960
defaultScreenHeightWeb: 600 defaultScreenHeightWeb: 600
m_StereoRenderingPath: 0 m_StereoRenderingPath: 2
m_ActiveColorSpace: 1 m_ActiveColorSpace: 1
unsupportedMSAAFallback: 0 unsupportedMSAAFallback: 0
m_SpriteBatchMaxVertexCount: 65535 m_SpriteBatchMaxVertexCount: 65535
@@ -541,8 +541,12 @@ PlayerSettings:
m_SubKind: m_SubKind:
m_BuildTargetBatching: [] m_BuildTargetBatching: []
m_BuildTargetShaderSettings: [] m_BuildTargetShaderSettings: []
m_BuildTargetGraphicsJobs: [] m_BuildTargetGraphicsJobs:
m_BuildTargetGraphicsJobMode: [] - m_BuildTarget: AndroidPlayer
m_GraphicsJobs: 1
m_BuildTargetGraphicsJobMode:
- m_BuildTarget: AndroidPlayer
m_GraphicsJobMode: 1
m_BuildTargetGraphicsAPIs: m_BuildTargetGraphicsAPIs:
- m_BuildTarget: iOSSupport - m_BuildTarget: iOSSupport
m_APIs: 10000000 m_APIs: 10000000
+1 -1
View File
@@ -16,7 +16,7 @@ TagManager:
- Default - Default
- TransparentFX - TransparentFX
- Ignore Raycast - Ignore Raycast
- - Overlay UI
- Water - Water
- UI - UI
- Player - Player