Record and Play를 사용하여 Unity 게임 객체의 움직임을 기기에서 저장 및 재생
소개
소위 vTuber처럼 아바타를 VR 내에서 움직일 때 움직임을 저장하고 나중에 재생하고 싶은 경우가 많습니다. 이러한 장면 내 모션 캡처를 위한 유니티 에셋은 이미 몇 개 공개되어 있지만, 유니티 에디터 내에서만 캡처한 데이터를 저장할 수 있다는 문제가 있었습니다.
이에 대해 이번에 소개하는 Record and Play는 빌드한 앱 내에서 게임 오브젝트의 움직임을 기록하여 데이터 파일을 생성하고 저장할 수 있습니다. Vive Focus Plus 내에서 모션 캡처를 테스트했지만 무사히 장치의 폴더에 기록 파일을 저장할 수있었습니다.
이번에는 그 방법을 소개합니다. 덧붙여 이하의 내용은 극히 기본적인 것뿐이므로, 보다 자세한 것은 공식 페이지 .를 참고해 주세요.
기록을 찍다
녹음을 하려면 먼저 Recorder라는 Scriptable Object를 생성합니다. 스크립트에서도 만들 수 있습니다만, 나는 에디터내의 메뉴(Create->RecordAndPlay->Recorder)로 만들고 있습니다.
그런 다음 만든 Recorder에 대해 추적하려는 게임 객체를 지정합니다. 아래 예제와 같이 객체를 List로 지정하고 SubjectBehaviour.Build를 사용하여 하나씩 레코드에 등록합니다. VR 모션 캡처라면 HMD나 컨트롤러에 해당하는 것을 지정하면 됩니다.
RecorderManager.csusing System.Collections.Generic;
using UnityEngine;
using EliCDavis.RecordAndPlay.Record;
using EliCDavis.RecordAndPlay;
using EliCDavis.RecordAndPlay.IO;
using EliCDavis.RecordAndPlay.Playback;
public class RecorderManager : MonoBehaviour, IActorBuilder
{
[SerializeField] private Recorder recorder;
[SerializeField] List<GameObject> trackedObjects;
void Start(){
foreach (var obj in trackedObjects)
{
SubjectBehavior.Build(obj, recorder);
}
}
}
녹화를 수행할 때는 recorder.Start();
로 시작하고, 종료할 때는 Recording myRecording = recorder.Finish();
에서 녹음 결과를 Recording 유형의 변수에 저장합니다. 파일에 저장할 때 스트림을 만들고 Packager.Package
메서드로 저장합니다. 예를 들면, 이런 느낌입니다.
RecorderManager.cs//上に追加
public void StartRecording()
{
recorder.Start();
}
public void StopRecording()
{
Recording myRecording = recorder.Finish();
var fileName = string.Format("{0}/demo.rap", Application.persistentDataPath);
using (FileStream fs = File.Create(fileName))
{
myRecording.RecordingName = "Demo";
Packager.Package(fs, myRecording);
}
}
기록을 읽고 재생
파일에서 레코드를 읽을 때는 Unpackager.Unpackage
메서드를 사용합니다. 아래에서는 recording
라는 변수에 읽은 데이터를 저장합니다. 그런 다음 PlaybackBehaviour.Build를 사용하여 재생을 위한 변수myPlaybackBehavior
를 준비합니다. 이 때, Unpackage한 것을 저장하고 있는 recording, actor builder를 가지는 클래스, Custom Event handler를 가지는 클래스, 루프의 유무를 지정합니다.
actor builder라고 하는 것은, 보존한 게임 오브젝트의 움직임을 재현하는 Actor를 만들기 위한 클래스로, IActorBuilder를 상속해, Build라고 하는 메소드를 구현하고 있을 필요가 있습니다. Build 메소드는, Actor 를 인스턴스화할 때에 사용하므로, 나중에 이 클래스내에서 정의하므로 this
로 했습니다. Custom Event handler에 대해서는, 이번은 사용하지 않기 때문에 null
로 했습니다.
RecorderManager.cs//上に追加
void LoadRecording(){
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
var recording = Unpackager.Unpackage(fs)[0];
myPlaybackBehavior = PlaybackBehavior.Build(recording,this,null,false);
}
이제 Build 메소드를 지정합니다. 이것은, 기록된 게임 오브젝트에 대응하는 Actor 를 지정하기 위해서 불려 갑니다. 그 때, 기록된 게임 오브젝트의 이름등이 메소드에 건네지므로, 이하의 예에서는 그것을 최초로 지정한 트랙킹 대상의 게임 오브젝트의 이름과 비교해, 일치하고 있으면 new Actor()
로 Actor 를 인스턴스화하여 참조를 반환 값으로 전달합니다.
RecorderManager.cs//上に追加
public Actor Build(int subjectId, string subjectName, Dictionary<string, string> metadata)
{
foreach(var ob in trackedObjects)
{
if (subjectName == ob.name)
{
var actor = new Actor(ob);
return actor;
}
}
throw new System.Exception("subject for actor not found");
}
지금까지 준비가 되면, 나머지는 myPlaybackBehavior.Play()
재생하기만 하면 됩니다. Actor를 만들 때 지정한 게임 오브젝트가 PLAYBACK OBJECT라는 게임 오브젝트 아래에 생성(또는 이동)되어 기록한 대로 움직입니다.
RecorderManager.cs//上に追加
public void PlayRecording()
{
myPlaybackBehavior.Play();
}
Reference
이 문제에 관하여(Record and Play를 사용하여 Unity 게임 객체의 움직임을 기기에서 저장 및 재생), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yanosen_jp/items/ee90ae6f7e9345d325e5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
녹음을 하려면 먼저 Recorder라는 Scriptable Object를 생성합니다. 스크립트에서도 만들 수 있습니다만, 나는 에디터내의 메뉴(Create->RecordAndPlay->Recorder)로 만들고 있습니다.
그런 다음 만든 Recorder에 대해 추적하려는 게임 객체를 지정합니다. 아래 예제와 같이 객체를 List로 지정하고 SubjectBehaviour.Build를 사용하여 하나씩 레코드에 등록합니다. VR 모션 캡처라면 HMD나 컨트롤러에 해당하는 것을 지정하면 됩니다.
RecorderManager.cs
using System.Collections.Generic;
using UnityEngine;
using EliCDavis.RecordAndPlay.Record;
using EliCDavis.RecordAndPlay;
using EliCDavis.RecordAndPlay.IO;
using EliCDavis.RecordAndPlay.Playback;
public class RecorderManager : MonoBehaviour, IActorBuilder
{
[SerializeField] private Recorder recorder;
[SerializeField] List<GameObject> trackedObjects;
void Start(){
foreach (var obj in trackedObjects)
{
SubjectBehavior.Build(obj, recorder);
}
}
}
녹화를 수행할 때는
recorder.Start();
로 시작하고, 종료할 때는 Recording myRecording = recorder.Finish();
에서 녹음 결과를 Recording 유형의 변수에 저장합니다. 파일에 저장할 때 스트림을 만들고 Packager.Package
메서드로 저장합니다. 예를 들면, 이런 느낌입니다.RecorderManager.cs
//上に追加
public void StartRecording()
{
recorder.Start();
}
public void StopRecording()
{
Recording myRecording = recorder.Finish();
var fileName = string.Format("{0}/demo.rap", Application.persistentDataPath);
using (FileStream fs = File.Create(fileName))
{
myRecording.RecordingName = "Demo";
Packager.Package(fs, myRecording);
}
}
기록을 읽고 재생
파일에서 레코드를 읽을 때는 Unpackager.Unpackage
메서드를 사용합니다. 아래에서는 recording
라는 변수에 읽은 데이터를 저장합니다. 그런 다음 PlaybackBehaviour.Build를 사용하여 재생을 위한 변수myPlaybackBehavior
를 준비합니다. 이 때, Unpackage한 것을 저장하고 있는 recording, actor builder를 가지는 클래스, Custom Event handler를 가지는 클래스, 루프의 유무를 지정합니다.
actor builder라고 하는 것은, 보존한 게임 오브젝트의 움직임을 재현하는 Actor를 만들기 위한 클래스로, IActorBuilder를 상속해, Build라고 하는 메소드를 구현하고 있을 필요가 있습니다. Build 메소드는, Actor 를 인스턴스화할 때에 사용하므로, 나중에 이 클래스내에서 정의하므로 this
로 했습니다. Custom Event handler에 대해서는, 이번은 사용하지 않기 때문에 null
로 했습니다.
RecorderManager.cs//上に追加
void LoadRecording(){
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
var recording = Unpackager.Unpackage(fs)[0];
myPlaybackBehavior = PlaybackBehavior.Build(recording,this,null,false);
}
이제 Build 메소드를 지정합니다. 이것은, 기록된 게임 오브젝트에 대응하는 Actor 를 지정하기 위해서 불려 갑니다. 그 때, 기록된 게임 오브젝트의 이름등이 메소드에 건네지므로, 이하의 예에서는 그것을 최초로 지정한 트랙킹 대상의 게임 오브젝트의 이름과 비교해, 일치하고 있으면 new Actor()
로 Actor 를 인스턴스화하여 참조를 반환 값으로 전달합니다.
RecorderManager.cs//上に追加
public Actor Build(int subjectId, string subjectName, Dictionary<string, string> metadata)
{
foreach(var ob in trackedObjects)
{
if (subjectName == ob.name)
{
var actor = new Actor(ob);
return actor;
}
}
throw new System.Exception("subject for actor not found");
}
지금까지 준비가 되면, 나머지는 myPlaybackBehavior.Play()
재생하기만 하면 됩니다. Actor를 만들 때 지정한 게임 오브젝트가 PLAYBACK OBJECT라는 게임 오브젝트 아래에 생성(또는 이동)되어 기록한 대로 움직입니다.
RecorderManager.cs//上に追加
public void PlayRecording()
{
myPlaybackBehavior.Play();
}
Reference
이 문제에 관하여(Record and Play를 사용하여 Unity 게임 객체의 움직임을 기기에서 저장 및 재생), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yanosen_jp/items/ee90ae6f7e9345d325e5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
//上に追加
void LoadRecording(){
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
var recording = Unpackager.Unpackage(fs)[0];
myPlaybackBehavior = PlaybackBehavior.Build(recording,this,null,false);
}
//上に追加
public Actor Build(int subjectId, string subjectName, Dictionary<string, string> metadata)
{
foreach(var ob in trackedObjects)
{
if (subjectName == ob.name)
{
var actor = new Actor(ob);
return actor;
}
}
throw new System.Exception("subject for actor not found");
}
//上に追加
public void PlayRecording()
{
myPlaybackBehavior.Play();
}
Reference
이 문제에 관하여(Record and Play를 사용하여 Unity 게임 객체의 움직임을 기기에서 저장 및 재생), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yanosen_jp/items/ee90ae6f7e9345d325e5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)