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