unity3d 实现UI界面上渲染多个3D模型


在查找如何ui显示3d模型发现Camera的TargetTexture挺简便的,可惜一直没找导如何去渲染多个3D模型,用多个camera去做效果不是理想,于是自己写了个,但是有上限限制,还有更好的方法请大家指正
对于还不会使用camera去实现的可以用以下链接

设计思路:将所有模型放在固定位置上用一个C amera,记录下一个key,TargetTexture 导在一张Texture上,通过key值去裁切RawImage 的UVRect,得到相应的图


CameraManger 处理模型添加,及位置摆放
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 3d模型展示添加管理
/// </summary>
public class CameraManger : MonoBehaviour
{
    [Tooltip("横向模型显示数量")]
    public int numberWidth = 5;
    [Tooltip("纵向模型显示数量")]
    public int numberHeight = 5;

    static GameObject gameRuning = null;
    public static CameraManger Instance
    {
        get
        {
            if (gameRuning == null)
            {
                return null;
            }
            return gameRuning.GetComponent<CameraManger>();
        }
    }

    private void Awake()
    {
        gameRuning = gameObject;
        GameObject obj = GameObject.Instantiate(Resources.Load("Model3d/Cat_Warrior") as GameObject);
        m_Object = obj;
        m_Object.SetActive(false);

    }

    GameObject m_Object;

    //位置坐标
    Dictionary<int, Vector3> m_Vector3List = new Dictionary<int, Vector3>();
    //位置是否被使用
    Dictionary<int, bool> m_Pos = new Dictionary<int, bool>();
    //位置对应的3d模型
    Dictionary<int, Transform> m_Trans = new Dictionary<int, Transform>();

    private void Start()
    {
        //初始化位置信息(模型以底部中心原点)

        //你设置的Camera size大小
        float _size = 6f;

        //模型对应镜头位置存储下来
        for (int i = 0; i < numberHeight; i++)
        {
            for (int j = 0; j < numberWidth; j++)
            {
                float _x = -_size+(_size*2/(numberWidth))*(j+0.5f);
                float _y = -_size + (_size * 2 / (numberHeight)) * (i);
                Vector3 _ve3 = new Vector3(_x, _y, 12f);
                m_Vector3List.Add((i* numberWidth + j + 1), _ve3);
                m_Pos.Add((i * numberWidth + j + 1), true);
            }
        }

        GameObject obj = GameObject.Instantiate(Resources.Load("Model3d/UI") as GameObject);

    }

    /// <summary>
    /// 添加3d模型展示
    /// </summary>
    public int Add3DModel()
    {
        foreach (var var in m_Pos)
        {
            if (var.Value)
            {
                Vector3 vector3 = m_Vector3List[var.Key];
                m_Pos[var.Key] = false;
                GameObject gameyouz = GameObject.Instantiate(m_Object);
                gameyouz.SetActive(true);
                gameyouz.transform.SetParent(transform);
                gameyouz.transform.localPosition = vector3;
                gameyouz.transform.rotation = Quaternion.Euler(0f, 180f, 0f);
                m_Trans.Add(var.Key, gameyouz.transform);
                gameyouz.name = var.Key.ToString();

                return var.Key;
            }
        }
        return 0;
    }

    /// <summary>
    /// 获取模型
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public Transform Get3DModel(int key)
    {
        return m_Trans[key];
    }

    /// <summary>
    /// 删除模型展示
    /// </summary>
    /// <param name="key">模型key</param>
    public void Remove3DModel(int key)
    {
        Transform game = m_Trans[key];
        m_Trans.Remove(key);
        m_Pos[key] = true;
        GameObject.Destroy(game.gameObject);
    }
}
TextureRotate 生成Texture进行裁切
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 模型ui显示
/// </summary>
public class TextureRotate : MonoBehaviour {
    Transform m_Horse;
    RawImage m_rawImage;
    public int m_key=-1;        //模型代表key
    private void Start()
    {
        Init();
    }
    private void Init()
    {
        EventTriggerListener.Get(transform).onDown += (go) =>
        {
            m_xz = true;
            m_FrontPoint = Input.mousePosition;
            m_NewPoint = Input.mousePosition;
        };
        EventTriggerListener.Get(transform).onUp += (go) =>
        {
            m_xz = false;
        };

    }

    /// <summary>
    /// 显示3d模型
    /// </summary>
    public void Show3DModel()
    {
        m_key = CameraManger.Instance.Add3DModel();
        m_Horse = CameraManger.Instance.Get3DModel(m_key);
        m_rawImage = transform.GetComponent<RawImage>();

        //图片截取
        float _w = CameraManger.Instance.numberWidth;
        float _h = CameraManger.Instance.numberHeight;
        float y = (int)((m_key - 1) / _w) / _h;
        float x = (m_key - 1) % _w / _w;
        Rect r = new Rect(x, y, 1f / _w, 1f / _h);
        m_rawImage.uvRect = r;
        m_rawImage.SetNativeSize();
    }

    private void OnEnable()
    {
        if (m_key == -1)
        {
            m_xz = false;
            m_key = CameraManger.Instance.Add3DModel();
            m_Horse = CameraManger.Instance.Get3DModel(m_key);
            m_rawImage = transform.GetComponent<RawImage>();
            //图片截取
            float _w = CameraManger.Instance.numberWidth;
            float _h = CameraManger.Instance.numberHeight;
            float y = (int)((m_key - 1) / _w)  / _h;
            float x = (m_key - 1) % _w / _w;
            Rect r = new Rect(x, y, 1f / _w, 1f / _h);
            m_rawImage.uvRect = r;
            m_rawImage.SetNativeSize();
        }
    }

    private void OnDisable()
    {
        if (CameraManger.Instance!=null&& m_key!=-1)
        {
            CameraManger.Instance.Remove3DModel(m_key);
            m_key = -1;
            //m_horseData = null;
        }
    }

    public RaycastHit hit;
    //Vector3 m_StartPoint = new Vector3();   //上一帧位置
    Vector3 m_FrontPoint = new Vector3();   //上一帧位置
    Vector3 m_NewPoint = new Vector3();   //当前帧位置
    bool m_xz = false;                      //是否进入旋转
    float _chazhi = 0f;
    void Update()
    {
        if (m_xz && Input.GetMouseButton(0))
        {
            m_FrontPoint = m_NewPoint;
            m_NewPoint = Input.mousePosition;
            float dt = m_NewPoint.x - m_FrontPoint.x;
            _chazhi += Mathf.Abs(dt);
            m_Horse.Rotate(0, -dt, 0);
        }
    }
}
UI监听检测
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
/*
 * 自定义按钮回掉事件 例如        EventTriggerListener.Get(gameobject).onUp += (go) =>{ };
 */
public class EventTriggerListener : UnityEngine.EventSystems.EventTrigger
{
    public delegate void VoidDelegate(GameObject go);
    public delegate void BoolDelegate(GameObject go, bool state);
    public delegate void FloatDelegate(GameObject go, float delta);
    public delegate void IntDelegate(GameObject go, int delta);
    public delegate void VectorDelegate(GameObject go, Vector2 delta);
    public delegate void ObjectDelegate(GameObject go, GameObject obj);
    public delegate void KeyCodeDelegate(GameObject go, KeyCode key);
    public delegate void ParamsDelegate(GameObject go, params object[] os);
    public VoidDelegate onClick;
    public VoidDelegate onDown;
    public VoidDelegate onEnter;
    public VoidDelegate onExit;
    public VoidDelegate onUp;
    public VoidDelegate onSelect;
    public VoidDelegate onUpdateSelect;
    public VoidDelegate onDrag;
    public IntDelegate onClickInt;
    public IntDelegate onDownInt;
    public ParamsDelegate onClickParams;
    public ParamsDelegate onDownParams;
    static public EventTriggerListener Get(GameObject go)
    {
        EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
        if (listener == null) listener = go.AddComponent<EventTriggerListener>();
        return listener;
    }

    static public EventTriggerListener Get(Transform transform)
    {
        EventTriggerListener listener = transform.GetComponent<EventTriggerListener>();
        if (listener == null) listener = transform.gameObject.AddComponent<EventTriggerListener>();
        return listener;
    }


    int m_data;
    static public EventTriggerListener Get(GameObject go,int delta)
    {
        EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
        if (listener == null) listener = go.AddComponent<EventTriggerListener>();
        listener.m_data = delta;
        return listener;
    }

    object[] m_paramsObj;
    static public  EventTriggerListener Getobject(GameObject go, params object[] os)
    {
        EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
        if (listener == null) listener = go.AddComponent<EventTriggerListener>();
        listener.m_paramsObj = os;
        return listener;
    }

    public override void OnPointerClick(PointerEventData eventData)
    {
        if (onClick != null) onClick(gameObject);
        if (onClickInt != null) onClickInt(gameObject, m_data);
        if (onClickParams != null) onClickParams(gameObject, m_paramsObj);
    }
    public override void OnPointerDown(PointerEventData eventData)
    {
        if (onDown != null) onDown(gameObject);
        if (onDownInt != null) onDownInt(gameObject, m_data);
        if (onDownParams != null) onDownParams(gameObject, m_paramsObj);
    }
    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (onEnter != null) onEnter(gameObject);
    }
    public override void OnPointerExit(PointerEventData eventData)
    {
        if (onExit != null) onExit(gameObject);
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        if (onUp != null) onUp(gameObject);
    }
    public override void OnSelect(BaseEventData eventData)
    {
        if (onSelect != null) onSelect(gameObject);
    }
    public override void OnUpdateSelected(BaseEventData eventData)
    {
        if (onUpdateSelect != null) onUpdateSelect(gameObject);
    }
    public override void OnDrag(PointerEventData eventData)
    {
        if (onDrag != null) onDrag(gameObject);
    }
}


猜你喜欢

转载自blog.csdn.net/weixin_41843959/article/details/80944478
今日推荐