zoukankan      html  css  js  c++  java
  • 获取unity prefab的预览图像

    官方的api可以直接获取预览图像,如下所示:

    Tex=AssetPreview.GetAssetPreview(Object m)as Texture;

    但是如果prefab是组合体的话(即一个prefab下包含2个或多个子物体),便只返回null。可以算是unity的一个bug吧。

    所以需要自己写函数来实现prefab图像预览。

    思路是将Prefab实例化到场景,并利用RenderTexture进行摄像机截取图像作为预览图像,代码如下:

     1         /// <summary>
     2         /// 获取预览图象
     3         /// </summary>
     4         /// <param name="obj"></param>
     5         /// <returns></returns>
     6         private Texture GetAssetPreview(GameObject obj)
     7         {
     8             GameObject clone = GameObject.Instantiate(obj);
     9             Transform cloneTransform = clone.transform;
    10             cloneTransform.position = new Vector3(-1000, -1000, -1000);
    11             //cloneTransform.localRotation = new Quaternion(0, 0, 0, 1);
    12 
    13             Transform[] all = clone.GetComponentsInChildren<Transform>();
    14             foreach (Transform trans in all)
    15             {
    16                 trans.gameObject.layer = 21;
    17             }
    18 
    19             Bounds bounds = GetBounds(clone);
    20             Vector3 Min = bounds.min;
    21             Vector3 Max = bounds.max;
    22             GameObject cameraObj = new GameObject("render camera");
    23             cameraObj.transform.position = new Vector3(cloneTransform.position.x, (Max.y + Min.y) / 2f, Max.z + (Max.z - Min.z));
    24 
    25             Vector3 center = new Vector3(cloneTransform.position.x, (Max.y + Min.y) / 2f, cloneTransform.position.z);
    26 
    27             cameraObj.transform.LookAt(center);
    28 
    29             Camera renderCamera = cameraObj.AddComponent<Camera>();
    30             renderCamera.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 1f);
    31             renderCamera.clearFlags = CameraClearFlags.Color;
    32             renderCamera.cameraType = CameraType.Preview;
    33             renderCamera.cullingMask = 1 << 21;
    34             int angle = (int)(Mathf.Atan2((Max.y - Min.y) / 2, (Max.z - Min.z)) * 180 / 3.1415f * 2);
    35             renderCamera.fieldOfView = angle;
    36 
    37             RenderTexture texture = new RenderTexture(64, 64, 0, RenderTextureFormat.Default);
    38             renderCamera.targetTexture = texture;
    39 
    40             renderCamera.RenderDontRestore();
    41 
    42             RenderTexture tex = new RenderTexture(64, 64, 0, RenderTextureFormat.Default);
    43             Graphics.Blit(texture, tex);
    44 
    45             Object.DestroyImmediate(clone);
    46             Object.DestroyImmediate(cameraObj);
    47 
    48             return tex;
    49         }
    50         /// <summary>
    51         /// 获得某物体的bounds
    52         /// </summary>
    53         /// <param name="obj"></param>
    54         private Bounds GetBounds(GameObject obj)
    55         {
    56             Vector3 Min = new Vector3(99999, 99999, 99999);
    57             Vector3 Max = new Vector3(-99999, -99999, -99999);
    58             MeshRenderer[] renders = obj.GetComponentsInChildren<MeshRenderer>();
    59             for (int i = 0; i < renders.Length; i++)
    60             {
    61                 if (renders[i].bounds.min.x < Min.x)
    62                     Min.x = renders[i].bounds.min.x;
    63                 if (renders[i].bounds.min.y < Min.y)
    64                     Min.y = renders[i].bounds.min.y;
    65                 if (renders[i].bounds.min.z < Min.z)
    66                     Min.z = renders[i].bounds.min.z;
    67 
    68                 if (renders[i].bounds.max.x > Max.x)
    69                     Max.x = renders[i].bounds.max.x;
    70                 if (renders[i].bounds.max.y > Max.y)
    71                     Max.y = renders[i].bounds.max.y;
    72                 if (renders[i].bounds.max.z > Max.z)
    73                     Max.z = renders[i].bounds.max.z;
    74             }
    75 
    76             Vector3 center = (Min + Max) / 2;
    77             Vector3 size = new Vector3(Max.x - Min.x, Max.y - Min.y, Max.z - Min.z);
    78             return new Bounds(center, size);
    79         }

     后补:unity在2017.2版本已经修复了这个问题,可以放心用Tex=AssetPreview.GetAssetPreview(Object m)as Texture了。

    感谢博友@跳出定向思维的发现,之前的unity旧版本也可以通过给prefab添加标签来解决问题,添加了任意标签后就可以使用自带的获取预览api了。

  • 相关阅读:
    jquery的全选,全不选,反选
    jquery中的on方法绑定动态元素
    IIS服务器不能下载.apk文件的解决方略
    14:堆和堆排序
    虚拟内存
    leetcode28:实现strStr()
    leetcode387:字符串中的第一个唯一字符
    leetcode344:反转字符串
    leetcode198:打家劫舍
    leetcode64:最小路径和
  • 原文地址:https://www.cnblogs.com/luxishi/p/7641733.html
Copyright © 2011-2022 走看看