当前位置:   article > 正文

Unity中如何通过UI显示3D模型解决方案?_unity中ui上的3d模型展示

unity中ui上的3d模型展示

需求:实现将3D模型显示在2DUI上面,实现王者荣耀英雄商城之中英雄展示功能,3D模型可以旋转,添加特效等正常3D功能。

使用RenderTexture 和RawImage做相机映射

效果:

那些黑圈圈就是例子特效哦。

 实现:

  1. Project面板创建一个RawImage
  2. 创建一个Camera,通过设置渲染模式控制模型显示的
  3. 创建一个RenderTexture
  4. 创建一个Cube,设置Layer为指定的布局,比如Model
  5. 将c创建的RenderTexture拖到a创建的RawImage的Texture属性里面
  6. 将c创建的RenderTexture拖到b创建的Camera的Target Texture属性里面
  7. 设置b创建的Camera的Clear Flags 为Solid Color,设置Background属性透明度为0
  8. 之后可以在Canvas里面设置a创建的RawImage的布局和大小来调整相应3D模型

优点:

       可以多模型渲染,可以渲染包括粒子在内的各种3D模型,如果需要显示粒子特效,需要针对性开发对应Shader控制渲染混合方式(如:Blend One OneMinusSrcAlpha),可以再任何UI需要的地方显示,完全和UI一样,层级顺序,列表中显示模型,裁切等等都很方便。

缺点:

       美术效果上,色差问题,和例子效果问题,局限性太大,模型数量不能太多,如果需要实现交互功能也比较麻烦,不能直接使用UI的交互逻辑,需要其他组件的配合,如果人物身上有一些特殊的效果,比如outline描边这样的,放在RenderTexture上就是达不到效果。

使用Screen Space Camera渲染摄像机

效果:

实现:

  1. 创建Canvas1,用来存放UI资源
  2. 创建Canvas2,用来存放3D模型资源,实现UI交互
  3. 将创建的两个Canvas的Render Mode设置为Screen Space –Camera
  4. 将两个Canvas的Render Camera设为同一个相机
  5. 通过调整Camera的Plane Distance控制哪个在前哪个在后面

优点:

       模型可挂载在Canvas底下,也可以直接在场景中创建,调整大小位置,不影响模型本身的效果显示,和正常3D场景一样,模型本身完全不受限制。

缺点:

       需要去控制Canvas的深度值,有很多问题实现不了,UI上盖模型,模型上盖UI,滑动列表中滑动裁切,需要和场景中模型做分离处理,不然容易混到一块分不清

使用世界空间的UI和模型绑定

实现:

  1. 创建Canvas
  2. 更改Canvas的RenderMode为WorldSpace
  3. 之后更改Canvas的大小和位置调整到3D模型的后面

优点:

UI完全跟3D组件一样,可以摆在任意位置和任意模型之后,自由度很大。

缺点:

        UI交互功能很麻烦,UI无法适配屏幕大小显示,需要创建整体背景UI的时候还需要将新的Canvas设置为Screen Space Camera模式

在这个实现中比较重要的一点是如果透过UI将点击事件穿透下去,让模型也可以接受到点击事件,这时候我们就需要在UI上挂一个脚本,当接受到点击事件的时候调用PassEvent将事件传下去。

  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.EventSystems;
  4. using UnityEngine.UI;
  5. using System.Collections.Generic;
  6. public class Test : MonoBehaviour,IPointerClickHandler ,IPointerDownHandler,IPointerUpHandler
  7. {
  8. //监听按下
  9. public void OnPointerDown(PointerEventData eventData)
  10. {
  11. PassEvent(eventData,ExecuteEvents.pointerDownHandler);
  12. }
  13. //监听抬起
  14. public void OnPointerUp(PointerEventData eventData)
  15. {
  16. PassEvent(eventData,ExecuteEvents.pointerUpHandler);
  17. }
  18. //监听点击
  19. public void OnPointerClick(PointerEventData eventData)
  20. {
  21. PassEvent(eventData,ExecuteEvents.submitHandler);
  22. PassEvent(eventData,ExecuteEvents.pointerClickHandler);
  23. }
  24. //把事件透下去
  25. public void PassEvent<T>(PointerEventData data,ExecuteEvents.EventFunction<T> function)
  26. where T : IEventSystemHandler
  27. {
  28. List<RaycastResult> results = new List<RaycastResult>();
  29. EventSystem.current.RaycastAll(data, results);
  30. GameObject current = data.pointerCurrentRaycast.gameObject ;
  31. for(int i =0; i< results.Count;i++)
  32. {
  33. if(current!= results[i].gameObject)
  34. {
  35. ExecuteEvents.Execute(results[i].gameObject, data,function);
  36. //RaycastAll后ugui会自己排序,如果你只想响应透下去的最近的一个响应,这里ExecuteEvents.Execute后直接break就行。
  37. }
  38. }
  39. }
  40. }

如有不准确之处,欢迎大家批评加改正哈。。。 

参考链接:

Unity3D研究院之将UI的点击事件渗透下去(九十) | 雨松MOMO程序研究院 (xuanyusong.com)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/103444?site
推荐阅读
相关标签
  

闽ICP备14008679号