- 유니티 App 으로 3D 모델의 '블렌드쉐입' 을 움직이고, 그 화면을 동영상화 하여 저장.
- 1-1) 블렌드쉐입 제어
- 우연히... 샘플로 받은 "곰.FBX & 곰.tga" 를 assets 에 추가해서 보다가, BlendShapes 속성을 발견!
- 해당 값을 Player.cs 코드으로~ 적절한 fps 으로 제어하니 잘 되었다.
- (다른 샘플들은... assets 에 추가하면, 너무 복잡하게 관련 리소스가 다 딸려와 혼란;;;)
-
using System.Collections; using UnityEngine; using System.IO; using System.Collections.Generic; public class MyPlayer : MonoBehaviour { SkinnedMeshRenderer skinnedMeshRenderer; Mesh skinnedMesh; void Awake() { Debug.Log("Awake()"); skinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>(); skinnedMesh = GetComponent<SkinnedMeshRenderer>().sharedMesh; } int blendShapeCount; int[] weightArray; void Start() { Debug.Log("Start()"); Application.targetFrameRate = 25; blendShapeCount = skinnedMesh.blendShapeCount; weightArray = new int[blendShapeCount]; for (int i = 0; i < blendShapeCount; ++i) { weightArray[i] = 0; } } public float speed = 10; void Update() { Debug.Log("Update()"); // 키보드 지원 float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); Vector3 vector = new Vector3(horizontal, vertical, 0); transform.position += vector * speed * Time.deltaTime; frameTime += Time.deltaTime; if (frameTime > (1/25)) { frameTime = 0; return; } for (int i = 0; i < blendShapeCount; ++i) { skinnedMeshRenderer.SetBlendShapeWeight(i, weightArray[i]); weightArray[i] = (weightArray[i] + Random.Range(0, 2)); if (weightArray[i] > 100) { weightArray[i] = 100; } } } }
- 1-2) 화면 동영상화 및 저장
- 당연히(?) 유니티 문서봄. (https://docs.unity3d.com/2022.1/Documentation/Manual/com.unity.recorder.html)
- https://docs.unity3d.com/Packages/com.unity.recorder@3.0/manual/index.html
- https://blog.yucchiy.com/2020/03/controling-unity-recorder-from-script
- "Manual" : Package Manager -> Unity Registry -> Unity Recoder 으로 설치 안내.
- (주의 : You can only use the Recorder in the Unity Editor. It does not work in standalone Unity Players or builds.)
- (이 말이 어떤 의미인지... 몰랏다...)
- "Scripting API" : UnityEditor 네임스페이스 하위에... 각종 클래스들이 제공 되네...
- 막연히 해보다가... 'UnityEditor' 는 말그대로~ 개발환경에서 툴로써 제공는 개념인거 같았다.
- 즉, 'UnityEditor' 관련 코드는 실제 빌드환경에서는 돌아가지 않고! 개발툴에서 테스트 할때만 돌아가는 코드;;;
- if (!Application.isEditor) {...}
- 왜? Unity 차원에서 자신의 화면을 녹화하는 기능을 안제공 하는것인가? 못찾은 뿐인것인가?
- (~ 삽질후 ~)
- 래퍼런스 찾아봄
- https://github.com/getsocial-im/getsocial-capture // (영상 인코딩 없이) 간단히 GIF 으로 만드는거 같음...
- https://evereal.com/products/video-capture-pro-unity-plugin // 뭐 돈내고 쓰면... 정말 될까? ㅎㅎ
- https://github.com/keijiro/FFmpegOut // 해당 설치하고 -> 테스트 됬는데! -> 끝네...실패18 (블루틴트 등등등 이슈)
- (~ 개빡후 ~)
- FFMPEG 라이브러리 찾아봄
- https://www.nuget.org/packages?q=ffmpeg
- http://accord-framework.net/docs/html/T_Accord_Video_FFMPEG_VideoFileWriter.htm
- // 또또또 뭔가 C# 호환성(?) 이 잘 맞지않아... 끄끄끝네 또 실패181818
- (~ 맨붕후 ~)
- 스크린캡쳐 & FFMPEG 인코딩 아이디어
- 기본으로 돌아가... Unity 차원에서 스크린캡쳐는 버젓이 있자나!!!
- https://docs.unity3d.com/Manual/ExecutionOrder.html
- https://docs.unity3d.com/2022.1/Documentation/ScriptReference/ScreenCapture.html
- 무식하게라도(?) 25 fps 으로 저장만 할 수 있으면 된다...
- https://dhkvmf88.tistory.com/8
- https://gist.github.com/DashW/74d726293c0d3aeb53f4
- 위 코드를 참고적으로, (헤드리스 에서도) 특정 카메라 으로부터~ texture 를 뽑아오도록 한다.
-
using System.Collections; using UnityEngine; using System.IO; using System.Collections.Generic; public class MyCamara : MonoBehaviour { ... public Camera cam; // 유니티 툴에서 수동으로 카메라 대입해줌! public int count = 0; public byte[] buffer = new byte[100*1000*1000]; // 100MB public int offset = 0; public void LateUpdate() { Debug.Log("LateUpdate()"); StartCoroutine(RecordFrame()); } IEnumerator RecordFrame() { Debug.Log("RecordFrame()"); //헤드리스 모드에서 직접 texture 뽑아보기 RenderTexture rt = new RenderTexture(1920, 1080, 24); cam.targetTexture = rt; cam.Render(); yield return new WaitForEndOfFrame(); //Texture2D texture = ScreenCapture.CaptureScreenshotAsTexture(); RenderTexture.active = cam.targetTexture; Texture2D texture = new Texture2D(cam.targetTexture.width, cam.targetTexture.height, TextureFormat.RGB24, false); texture.ReadPixels(new Rect(0, 0, cam.targetTexture.width, cam.targetTexture.height), 0, 0); texture.Apply(); byte[] bytes = texture.EncodeToPNG(); // 1안 : 디스크 프로세팅 var path = "/경로/" + string.Format("{0:D4}", count) + ".png"; File.WriteAllBytes(path, bytes); count++; // 2안 : 메모리 프로세싱 System.Array.Copy(bytes, 0, buffer, offset, bytes.Length); offset += bytes.Length; if (조건) { using (StreamWriter sw = new StreamWriter(@"/경로/mypipe")) { sw.BaseStream.Write(buffer, 0, offset); } } Object.Destroy(rt); Object.Destroy(texture); } }
- 1-3) 서버에서 운영
- 처음에 제일 헷갈렷던 부분은... 유니티는 게임이고, 게임은 클라이언트 App이라는 것이다.
- 그래서 서버에서 유니티 빌드된 App으로 -> 동영상을 생성하는것이 자연스러운지? 의문...
- 그런데 '헤드리스 모드' 라는 개념이 있었다. (서버에서 랜더링 화면을 띄우지않고 동작을 하는방식)
- https://docs.unity3d.com/kr/2020.3/Manual/BuildSettingsStandalone.html
- https://docs.unity3d.com/kr/2020.3/Manual/CommandLineArguments.html
- 즉, 서버에서 일일이 프레임을 직접 그리지 않고 계산만 할수있어서~ 딱 원하는 배치방식의 동작을 할 수 있었다.
- (빌드시 'Server Build' 를 하거나, 실행시 "-batchmode" 옵션을 주면 됨. "-nographics" 옵션까지 주면... 아예 안그리는듯.)
- 1-1) 블렌드쉐입 제어
- ...
-끝-
'게임' 카테고리의 다른 글
unity3 (0) | 2023.03.15 |
---|---|
Live2D Cubism SDK (0) | 2022.10.28 |
Live2D Cubism (0) | 2022.08.28 |
Ready Player ME (0) | 2022.08.27 |
unity2 (0) | 2022.08.08 |