zoukankan      html  css  js  c++  java
  • 为Unity的新版ugui的Prefab生成预览图

    2018.3版本的unity有新的嵌套预制体功能,现在预览图很不方便。可以生成一个。

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    using System.IO;

    [CustomPreview(typeof(GameObject))]
    public class UIPreview : ObjectPreview
    {
    Texture preview;

    const string cachePreviewPath = "CachePreviews";

    public override bool HasPreviewGUI()
    {
    return true;
    }


    public override void OnPreviewGUI(Rect r, GUIStyle background)
    {
    base.OnPreviewGUI(r, background);
    if (target == null)
    return;

    var targetGameObject = target as GameObject;

    if (targetGameObject == null)
    return;


    GUI.Label(r, target.name + " is being previewed");
    preview = AssetPreview.GetAssetPreview(target);


    if (preview == null)
    {
    string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetGameObject));

    string pathname = Path.Combine(cachePreviewPath, guid + ".png");
    preview = AssetDatabase.LoadAssetAtPath<Texture2D>(Path.Combine("Assets",pathname));
    if (preview == null)
    {
    preview = GetAssetPreview(targetGameObject);

    if (SaveTexture2D(preview as Texture2D, Path.Combine(Application.dataPath, pathname)))
    {
    AssetDatabase.ImportAsset(pathname);
    AssetDatabase.Refresh();
    Debug.Log("SaveTextureToPNG " + pathname);
    }
    }
    }

    GUI.DrawTexture(r, preview);
    }

    public static Texture GetAssetPreview(GameObject obj)
    {
    GameObject canvas_obj = null;
    GameObject clone = GameObject.Instantiate(obj);
    Transform cloneTransform = clone.transform;

    GameObject cameraObj = new GameObject("render camera");
    Camera renderCamera = cameraObj.AddComponent<Camera>();
    renderCamera.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 1f);
    renderCamera.clearFlags = CameraClearFlags.Color;
    renderCamera.cameraType = CameraType.SceneView;
    renderCamera.cullingMask = 1 << 21;
    renderCamera.nearClipPlane = -100;
    renderCamera.farClipPlane = 100;

    bool isUINode = false;
    if (cloneTransform is RectTransform)
    {
    //如果是UGUI节点的话就要把它们放在Canvas下了
    canvas_obj = new GameObject("render canvas", typeof(Canvas));
    Canvas canvas = canvas_obj.GetComponent<Canvas>();
    cloneTransform.parent = canvas_obj.transform;
    cloneTransform.localPosition = Vector3.zero;
    //canvas_obj.transform.position = new Vector3(-1000, -1000, -1000);
    canvas_obj.layer = 21;//放在21层,摄像机也只渲染此层的,避免混入了奇怪的东西
    canvas.renderMode = RenderMode.ScreenSpaceCamera;
    canvas.worldCamera = renderCamera;

    isUINode = true;
    }
    else
    cloneTransform.position = new Vector3(-1000, -1000, -1000);

    Transform[] all = clone.GetComponentsInChildren<Transform>();
    foreach (Transform trans in all)
    {
    trans.gameObject.layer = 21;
    }

    Bounds bounds = GetBounds(clone);
    Vector3 Min = bounds.min;
    Vector3 Max = bounds.max;



    if (isUINode)
    {
    cameraObj.transform.position = new Vector3(0, 0, -10);
    //Vector3 center = new Vector3(cloneTransform.position.x, (Max.y + Min.y) / 2f, cloneTransform.position.z);
    cameraObj.transform.LookAt(Vector3.zero);

    renderCamera.orthographic = true;
    float width = Max.x - Min.x;
    float height = Max.y - Min.y;
    float max_camera_size = width > height ? width : height;
    renderCamera.orthographicSize = max_camera_size / 2;//预览图要尽量少点空白
    }
    else
    {
    cameraObj.transform.position = new Vector3((Max.x + Min.x) / 2f, (Max.y + Min.y) / 2f, Max.z + (Max.z - Min.z));
    Vector3 center = new Vector3(cloneTransform.position.x, (Max.y + Min.y) / 2f, cloneTransform.position.z);
    cameraObj.transform.LookAt(center);

    int angle = (int)(Mathf.Atan2((Max.y - Min.y) / 2, (Max.z - Min.z)) * 180 / 3.1415f * 2);
    renderCamera.fieldOfView = angle;
    }
    RenderTexture texture = new RenderTexture(128, 128, 0, RenderTextureFormat.Default);
    renderCamera.targetTexture = texture;

    var tex = RTImage(renderCamera);

    Object.DestroyImmediate(canvas_obj);
    Object.DestroyImmediate(cameraObj);


    return tex;
    }

    static Texture2D RTImage(Camera camera)
    {
    // The Render Texture in RenderTexture.active is the one
    // that will be read by ReadPixels.
    var currentRT = RenderTexture.active;
    RenderTexture.active = camera.targetTexture;

    // Render the camera's view.
    //camera.Render();

    camera.Render();
    // Make a new texture and read the active Render Texture into it.
    Texture2D image = new Texture2D(camera.targetTexture.width, camera.targetTexture.height);
    image.ReadPixels(new Rect(0, 0, camera.targetTexture.width, camera.targetTexture.height), 0, 0);
    image.Apply();

    // Replace the original active Render Texture.
    RenderTexture.active = currentRT;
    return image;
    }

    public static Bounds GetBounds(GameObject obj)
    {
    Vector3 Min = new Vector3(99999, 99999, 99999);
    Vector3 Max = new Vector3(-99999, -99999, -99999);
    MeshRenderer[] renders = obj.GetComponentsInChildren<MeshRenderer>();
    if (renders.Length > 0)
    {
    for (int i = 0; i < renders.Length; i++)
    {
    if (renders[i].bounds.min.x < Min.x)
    Min.x = renders[i].bounds.min.x;
    if (renders[i].bounds.min.y < Min.y)
    Min.y = renders[i].bounds.min.y;
    if (renders[i].bounds.min.z < Min.z)
    Min.z = renders[i].bounds.min.z;

    if (renders[i].bounds.max.x > Max.x)
    Max.x = renders[i].bounds.max.x;
    if (renders[i].bounds.max.y > Max.y)
    Max.y = renders[i].bounds.max.y;
    if (renders[i].bounds.max.z > Max.z)
    Max.z = renders[i].bounds.max.z;
    }
    }
    else
    {
    RectTransform[] rectTrans = obj.GetComponentsInChildren<RectTransform>();
    Vector3[] corner = new Vector3[4];
    for (int i = 0; i < rectTrans.Length; i++)
    {
    //获取节点的四个角的世界坐标,分别按顺序为左下左上,右上右下
    rectTrans[i].GetWorldCorners(corner);
    if (corner[0].x < Min.x)
    Min.x = corner[0].x;
    if (corner[0].y < Min.y)
    Min.y = corner[0].y;
    if (corner[0].z < Min.z)
    Min.z = corner[0].z;

    if (corner[2].x > Max.x)
    Max.x = corner[2].x;
    if (corner[2].y > Max.y)
    Max.y = corner[2].y;
    if (corner[2].z > Max.z)
    Max.z = corner[2].z;
    }
    }

    Vector3 center = (Min + Max) / 2;
    Vector3 size = new Vector3(Max.x - Min.x, Max.y - Min.y, Max.z - Min.z);
    return new Bounds(center, size);
    }

    public static bool SaveTextureToPNG(Texture inputTex, string save_file_name)
    {
    RenderTexture temp = RenderTexture.GetTemporary(inputTex.width, inputTex.height, 0, RenderTextureFormat.ARGB32);
    Graphics.Blit(inputTex, temp);
    bool ret = SaveRenderTextureToPNG(temp, save_file_name);
    RenderTexture.ReleaseTemporary(temp);
    return ret;
    }

    public static bool SaveTexture2D(Texture2D png, string save_file_name)
    {
    byte[] bytes = png.EncodeToPNG();
    string directory = Path.GetDirectoryName(save_file_name);
    if (!Directory.Exists(directory))
    Directory.CreateDirectory(directory);
    FileStream file = File.Open(save_file_name, FileMode.Create);
    BinaryWriter writer = new BinaryWriter(file);
    writer.Write(bytes);
    file.Close();

    return true;
    }

    //将RenderTexture保存成一张png图片
    public static bool SaveRenderTextureToPNG(RenderTexture rt, string save_file_name)
    {
    RenderTexture prev = RenderTexture.active;
    RenderTexture.active = rt;
    Texture2D png = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false);
    png.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
    byte[] bytes = png.EncodeToPNG();
    string directory = Path.GetDirectoryName(save_file_name);
    if (!Directory.Exists(directory))
    Directory.CreateDirectory(directory);
    FileStream file = File.Open(save_file_name, FileMode.Create);
    BinaryWriter writer = new BinaryWriter(file);
    writer.Write(bytes);
    file.Close(http://www.my516.com);
    Texture2D.DestroyImmediate(png);
    png = null;
    RenderTexture.active = prev;
    return true;
    }


    }
    --------------------- 

  • 相关阅读:
    单例模式(Singleton)的6种实现
    深入浅出单实例Singleton设计模式
    Singleton单例模式
    面试中的Singleton
    海量数据存储之Key-Value存储简介
    大数据时代的 9 大Key-Value存储数据库
    python 多线程两种实现方式,Python多线程下的_strptime问题,
    pycURL的内存问题
    百万级访问网站前期的技术准备
    IPv6 tutorial – Part 6: Site-local addresses and link-local addresses
  • 原文地址:https://www.cnblogs.com/ly570/p/10989753.html
Copyright © 2011-2022 走看看