Unity 3D模型动画导出为帧序列

问题:将用于Unity的3D模型改成2D图片。
思路:把3D动画播放一遍,逐帧对模型截图。

代码说明:

1.要引用的命名空间

using System.IO;
using UnityEngine;
using System.Collections.Generic;
using System.Collections;

2.截取当前屏幕,保存为Texture2D对象,存入文件名-图片字典中。存入字典会占用较高的内存,但会使截屏的过程看着比较舒服。

public Dictionary<string, Texture2D> outTxt2D = new Dictionary<string, Texture2D>();
public void ScreenShot(string fileName)
    {
        fileName = pathOutput + fileName + ".png";
        Camera m_mainCam = Camera.main;
        RenderTexture rt = new RenderTexture(Screen.width, Screen.height, 24);
        m_mainCam.targetTexture = rt;
        m_mainCam.Render();
        RenderTexture.active = rt;
        Texture2D tex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, true);
        tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
        tex.Apply();
        RenderTexture.active = null;
        m_mainCam.targetTexture = null;
        Destroy(rt);
        if (outTxt2D == null)
        {
            outTxt2D = new Dictionary<string, Texture2D>();
        }
        outTxt2D.Add(fileName, tex);
    }

3.播放多个动画片段,进行逐帧截屏

	public AnimationClip[] animations;
    public Animation legacyPlayer;
    IEnumerator MutiAniamtion()
    {
        Time.timeScale = 2f;
        for (int i = 0; i < animations.Length; i++)
        {
            legacyPlayer.Play(animations[i].name, PlayMode.StopAll);
            float timer = 0f;
            int index = 0;
            while (timer < animations[i].length)
            {
                yield return null;
                timer += Time.deltaTime;
                index++;
                ScreenShot(animations[i].name + index.ToString());
            }
        }
        Time.timeScale = 1f;
        ExportTxt2Ds();
    }

4.将outTxt2D 中保存的图片信息,导出成文件

	private static string pathOutput
    {
        get
        {
            string pathStr = "E:\\素材\\模型导出\\";
            if (!Directory.Exists(pathStr))
            {
                Directory.CreateDirectory(pathStr);
            }
            return pathStr;
        }
    }
	private void ExportTxt2Ds()
    {
        foreach (var item in outTxt2D)
        {
            if (File.Exists(item.Key))
            {
                File.Delete(item.Key);
            }
            FileInfo fileInfo = new FileInfo(item.Key);
            File.WriteAllBytes(fileInfo.FullName, item.Value.EncodeToPNG());
            Debug.Log("图片导出-" + fileInfo.Name);
        }
    }

5.键盘操作

	void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            StartCoroutine(MutiAniamtion());
        }
    }

使用

(此过程有点像给模特照相)

  1. 新建场景,将模型、灯光、摄像机摆好,摆成帧序列需要的样子。
    Unity 3D模型动画导出为帧序列_第1张图片
  2. 设置摄像机的Clear Flags 为Solid Color,视图为正交,调整视口尺寸,使模型做动作时也要完全包含在摄像机的范围内。
    Unity 3D模型动画导出为帧序列_第2张图片
  3. 设置动画片段
    编写包含上述代码方法的脚本挂在任意物体上,将要导出的动画片段拖到脚本中的animations数组中。
    模型身上若没有Animation组件,则添加Animation组件,将要导出的动画片段再拖进Animation组件的Animations数组中。指定脚本的legacyPlayer为模型的Animation组件。
    Unity 3D模型动画导出为帧序列_第3张图片
    4.运行场景,按S键即可开始输出帧序列。

缺陷

  1. 输出不稳定,有时两个动画片段之间会有重叠的帧,输出之后还要检查一遍。
  2. 如果动画片段多的话,需要等待较长的时间。
  3. 仅限Legacy动画,如果是其他类型的Animation组件无法播放。

你可能感兴趣的:(unity备忘,unity,c#,游戏开发)