136 lines
4.4 KiB
C#
136 lines
4.4 KiB
C#
![]() |
using System;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using System.IO;
|
||
|
using BITKit.Entities;
|
||
|
using BITKit.WorldNode;
|
||
|
using Cysharp.Threading.Tasks;
|
||
|
using Microsoft.Extensions.DependencyInjection;
|
||
|
using Microsoft.Extensions.Logging;
|
||
|
using Unity.Mathematics;
|
||
|
using UnityEngine;
|
||
|
using YamlDotNet.Serialization;
|
||
|
using Object = UnityEngine.Object;
|
||
|
|
||
|
namespace Net.Project.B.World
|
||
|
{
|
||
|
public class UnitySnapshotService : ISnapshotService
|
||
|
{
|
||
|
private readonly IEntitiesService _entitiesService;
|
||
|
|
||
|
private readonly ILogger<UnitySnapshotService> _logger;
|
||
|
|
||
|
private readonly ISerializer _serializer;
|
||
|
private readonly IDeserializer _deserializer;
|
||
|
|
||
|
public UnitySnapshotService(ISerializer serializer, IDeserializer deserializer, ILogger<UnitySnapshotService> logger, IEntitiesService entitiesService)
|
||
|
{
|
||
|
_serializer = serializer;
|
||
|
_deserializer = deserializer;
|
||
|
_logger = logger;
|
||
|
_entitiesService = entitiesService;
|
||
|
}
|
||
|
|
||
|
public string Directory { get; } = Path.Combine(Application.persistentDataPath, "Snapshots").Replace('/', '\\');
|
||
|
|
||
|
public async UniTask<SnapshotData> Snapshot(float3 position, quaternion rotation, int fov)
|
||
|
{
|
||
|
var renderTexture = new RenderTexture(Screen.width, Screen.height, 32);
|
||
|
|
||
|
var camera = Camera.main;
|
||
|
|
||
|
if (!camera) throw new DriveNotFoundException("未找到MainCamera");
|
||
|
|
||
|
camera.targetTexture = renderTexture;
|
||
|
camera.Render();
|
||
|
|
||
|
camera.targetTexture = null;
|
||
|
|
||
|
var screenshot = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGBA32, false);
|
||
|
RenderTexture.active = renderTexture;
|
||
|
screenshot.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
|
||
|
screenshot.Apply();
|
||
|
RenderTexture.active = null;
|
||
|
|
||
|
Object.Destroy(renderTexture);
|
||
|
|
||
|
var bytes = screenshot.EncodeToPNG();
|
||
|
|
||
|
var fileName = DateTime.Now.Ticks;
|
||
|
|
||
|
var path = Path.Combine(Directory, fileName + ".png");
|
||
|
|
||
|
new DirectoryInfo(Directory).Create();
|
||
|
|
||
|
await File.WriteAllBytesAsync(path, bytes);
|
||
|
|
||
|
var data = new SnapshotData
|
||
|
{
|
||
|
FileName = null,
|
||
|
Name = null,
|
||
|
Description = null,
|
||
|
CreateTime = default,
|
||
|
Position = default,
|
||
|
Rotation = default
|
||
|
};
|
||
|
|
||
|
data.FileName = path;
|
||
|
data.Name = "无标题";
|
||
|
data.Description = "无描述";
|
||
|
data.CreateTime = DateTime.Now;
|
||
|
data.Position = camera.transform.position;
|
||
|
data.Rotation = camera.transform.rotation;
|
||
|
|
||
|
|
||
|
if (Physics.Raycast(camera.transform.position, camera.transform.forward, out var hit))
|
||
|
{
|
||
|
if(_entitiesService.Entities.TryGetValue(hit.transform.gameObject.GetInstanceID(),out var hitEntity) && hitEntity.ServiceProvider.GetService<WorldInfoNode>() is {} node)
|
||
|
{
|
||
|
data.Name = node.Name;
|
||
|
data.Description = node.Description;
|
||
|
|
||
|
_logger.LogInformation($"相机命中了:{hit.transform.name}@{node.Name}:{node.Description}");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_logger.LogInformation($"相机命中了:{hit.transform.name},但无有效目标");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var yaml = _serializer.Serialize(data);
|
||
|
|
||
|
await File.WriteAllTextAsync(Path.Combine(Directory, fileName + ".yaml"), yaml);
|
||
|
|
||
|
await UniTask.SwitchToMainThread();
|
||
|
|
||
|
OnSnapshot?.Invoke(data);
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
public async UniTask<IReadOnlyList<SnapshotData>> GetSnapshots()
|
||
|
{
|
||
|
var list = new List<SnapshotData>();
|
||
|
|
||
|
new DirectoryInfo(Directory).Create();
|
||
|
foreach (var fileInfo in new DirectoryInfo(Directory).GetFiles("*.yaml"))
|
||
|
{
|
||
|
var yaml = await File.ReadAllTextAsync(fileInfo.FullName);
|
||
|
var data = _deserializer.Deserialize<SnapshotData>(yaml);
|
||
|
|
||
|
list.Add(data);
|
||
|
}
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
public static event Action<SnapshotData> OnSnapshot;
|
||
|
|
||
|
event Action<SnapshotData> ISnapshotService.OnSnapshot
|
||
|
{
|
||
|
add => OnSnapshot += value;
|
||
|
remove => OnSnapshot -= value;
|
||
|
}
|
||
|
}
|
||
|
}
|