unity3d 實現UI介面上渲染多個3D模型
阿新 • • 發佈:2019-01-10
在查詢如何ui顯示3d模型發現Camera的TargetTexture挺簡便的,可惜一直沒找導如何去渲染多個3D模型,用多個camera去做效果不是理想,於是自己寫了個,但是有上限限制,還有更好的方法請大家指正對於還不會使用camera去實現的可以用以下連結設計思路:將所有模型放在固定位置上用一個Camera,記錄下一個key,TargetTexture 導在一張Texture上,通過key值去裁切RawImage 的UVRect,得到相應的圖CameraManger 處理模型新增,及位置擺放
TextureRotate 生成Texture進行裁切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); } }
UI監聽檢測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); } } }
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); } }