获取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了。

原文地址:https://www.cnblogs.com/luxishi/p/7641733.html