Skip to content

Instantly share code, notes, and snippets.

@nekomimi-daimao
Created July 18, 2020 21:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nekomimi-daimao/a7794671214778008942f8d22d681b83 to your computer and use it in GitHub Desktop.
Save nekomimi-daimao/a7794671214778008942f8d22d681b83 to your computer and use it in GitHub Desktop.
HumanRanch of VRM
using System;
using System.Collections.Generic;
using System.IO;
using Cysharp.Threading.Tasks;
using UnityEngine;
using VRM;
public class HumanRanch : MonoBehaviour
{
private void Start()
{
InitializeCage().ContinueWith(Rearing);
}
#region Ranch
[SerializeField]
private Transform[] _cage;
[SerializeField]
private RuntimeAnimatorController _animator;
private VRMImporterContext[] _liveStocks;
private async UniTask InitializeCage()
{
// wait for first update
await UniTask.Yield(PlayerLoopTiming.Update);
_liveStocks = new VRMImporterContext[_cage.Length];
}
private const float ProductionCycle = 3f;
private readonly Vector3 CageGap = new Vector3(0, -1, 0);
private async UniTask Rearing()
{
var token = this.GetCancellationTokenOnDestroy();
while (!token.IsCancellationRequested)
{
var changeIndex = UnityEngine.Random.Range(0, _liveStocks.Length);
if (_liveStocks[changeIndex] == null)
{
var context = await LoadVRM();
var avatar = context.Root;
avatar.GetComponent<Animator>().runtimeAnimatorController = _animator;
avatar.transform.SetPositionAndRotation(
_cage[changeIndex].position + CageGap,
_cage[changeIndex].rotation
);
_liveStocks[changeIndex] = context;
context.ShowMeshes();
}
else
{
_liveStocks[changeIndex]?.Dispose();
_liveStocks[changeIndex] = null;
}
await UniTask.Delay(TimeSpan.FromSeconds(ProductionCycle), cancellationToken: token);
}
}
#endregion
#region LoadVRM
private readonly Dictionary<string, byte[]> _VRMBufferCache = new Dictionary<string, byte[]>();
private string[] _VRMFullPaths = null;
private static string[] SearchStreamingAssetsVRM()
{
var dirPath = Path.Combine(Application.streamingAssetsPath, "vrm");
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
return Directory.GetFiles(dirPath, "*.vrm");
}
private async UniTask<VRMImporterContext> LoadVRM()
{
if (_VRMFullPaths == null)
{
_VRMFullPaths = SearchStreamingAssetsVRM();
}
var path = _VRMFullPaths[UnityEngine.Random.Range(0, _VRMFullPaths.Length)];
if (!_VRMBufferCache.ContainsKey(path))
{
await UniTask.SwitchToThreadPool();
var buffer = File.ReadAllBytes(path);
await UniTask.SwitchToMainThread();
_VRMBufferCache[path] = buffer;
}
var context = await LoadVRMFromBuffer(_VRMBufferCache[path]);
return context;
}
private static async UniTask<VRMImporterContext> LoadVRMFromBuffer(byte[] buffer)
{
var context = new VRMImporterContext();
context.ParseGlb(buffer);
await context.LoadAsyncTask();
return context;
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment