Heavy Performance adjustments, mainly by switching all async functions to Unitask tasks
This commit is contained in:
@@ -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
@@ -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,29 +153,14 @@ namespace GhostSystem
|
|||||||
sceneIdReady = false;
|
sceneIdReady = false;
|
||||||
OnStopRecord?.Invoke();
|
OnStopRecord?.Invoke();
|
||||||
Debug.Log($"Stop recording: {SceneId}");
|
Debug.Log($"Stop recording: {SceneId}");
|
||||||
|
|
||||||
|
if (doorCount > 0 && TrackedObjects.Count >= doorCount)
|
||||||
|
{
|
||||||
TrackedObjects.RemoveRange(TrackedObjects.Count - doorCount, doorCount);
|
TrackedObjects.RemoveRange(TrackedObjects.Count - doorCount, doorCount);
|
||||||
|
}
|
||||||
|
|
||||||
doorCount = 0;
|
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
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ TagManager:
|
|||||||
- Default
|
- Default
|
||||||
- TransparentFX
|
- TransparentFX
|
||||||
- Ignore Raycast
|
- Ignore Raycast
|
||||||
-
|
- Overlay UI
|
||||||
- Water
|
- Water
|
||||||
- UI
|
- UI
|
||||||
- Player
|
- Player
|
||||||
|
|||||||
Reference in New Issue
Block a user