Created
July 18, 2020 21:01
-
-
Save nekomimi-daimao/a7794671214778008942f8d22d681b83 to your computer and use it in GitHub Desktop.
HumanRanch of VRM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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