当前位置:   article > 正文

unity 模型显示在UI上 并交互(点击、旋转、缩放)_unity 3物体显示在ui并鼠标控制

unity 3物体显示在ui并鼠标控制

项目工程:unity模型显示在UI上并交互(点击、旋转、缩放)资源-CSDN文库

1.在Assets创建 Render Texture(下面会用到),根据需要设置Size

2.创建UIRawImage,并把Render Texture赋上

 3.创建相机,如下图:

4.基本UI的准备工作完成,剩下的就是代码了,值得一提:相机我不喜欢单独拿出去管理,就和UI一起就好。如图:

 5.相机控制,直接上代码(添加了一个判断,鼠标必须在rawImage上,其他UI上无效):

  1. /**********************************************************************
  2. 文件信息
  3. 文件名(File Name): CameraController.cs
  4. 作者(Author): TianWenQuan
  5. 创建时间(CreateTime): #CREATETIME#
  6. Unity版本(UnityVersion): #UNITYVERSION#
  7. 项目:
  8. **********************************************************************/
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using UnityEngine;
  12. using UnityEngine.UI;
  13. using UnityEngine.EventSystems;
  14. namespace Twq
  15. {
  16. /// <summary>
  17. /// 该脚本需要挂在摄像机上
  18. /// </summary>
  19. public class CameraController : MonoBehaviour
  20. {
  21. public Transform targetObject;
  22. public Vector3 targetOffset;
  23. public float averageDistance = 5.0f;//初始位置 镜头远近
  24. public float maxDistance = 20;
  25. public float minDistance = .6f;
  26. public float xSpeed = 200.0f;
  27. public float ySpeed = 200.0f;
  28. public int yMinLimit = -80;
  29. public int yMaxLimit = 80;
  30. public int xMinLimit = -80;
  31. public int xMaxLimit = 80;
  32. public int zoomSpeed = 40;
  33. public float panSpeed = 0.3f;
  34. public float zoomDampening = 5.0f;
  35. public float rotateOnOff = 1;
  36. private float xDeg = 0.0f;
  37. private float yDeg = 0.0f;
  38. private float currentDistance;
  39. private float desiredDistance;
  40. private Quaternion currentRotation;
  41. private Quaternion desiredRotation;
  42. private Quaternion rotation;
  43. private Vector3 position;
  44. private float idleTimer = 0.0f;
  45. private float idleSmooth = 0.0f;
  46. void Start() { Init(); }
  47. void OnEnable() { Init(); }
  48. public void Init()
  49. {
  50. tt();
  51. }
  52. public void tt()
  53. {
  54. if (!targetObject)
  55. {
  56. GameObject go = new GameObject("Cam Target");
  57. go.transform.position = transform.position + (transform.forward * averageDistance);
  58. targetObject = go.transform;
  59. }
  60. currentDistance = averageDistance;
  61. desiredDistance = averageDistance;
  62. position = transform.position;
  63. rotation = transform.rotation;
  64. currentRotation = transform.rotation;
  65. desiredRotation = transform.rotation;
  66. xDeg = Vector3.Angle(Vector3.right, transform.right);
  67. yDeg = Vector3.Angle(Vector3.up, transform.up);
  68. position = targetObject.position - (rotation * Vector3.forward * currentDistance + targetOffset);
  69. }
  70. void LateUpdate()
  71. {
  72. if (IsPointerOverGameObject(Input.mousePosition))
  73. {
  74. if (Input.GetMouseButton(2) && Input.GetKey(KeyCode.LeftAlt) && Input.GetKey(KeyCode.LeftControl))
  75. {
  76. desiredDistance -= Input.GetAxis("Mouse Y") * 0.02f * zoomSpeed * 0.125f * Mathf.Abs(desiredDistance);
  77. }
  78. else if (Input.GetMouseButton(0))
  79. {
  80. xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
  81. yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
  82. yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
  83. xDeg = ClampAngle(xDeg, xMinLimit, xMaxLimit);
  84. desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
  85. currentRotation = transform.rotation;
  86. rotation = Quaternion.Lerp(currentRotation, desiredRotation, 0.02f * zoomDampening);
  87. transform.rotation = rotation;
  88. idleTimer = 0;
  89. idleSmooth = 0;
  90. }
  91. else
  92. {
  93. //自动旋转
  94. //idleTimer += 0.02f;
  95. //if (idleTimer > rotateOnOff && rotateOnOff > 0)
  96. //{
  97. // idleSmooth += (0.02f + idleSmooth) * 0.005f;
  98. // idleSmooth = Mathf.Clamp(idleSmooth, 0, 1);
  99. // xDeg += xSpeed * 0.001f * idleSmooth;
  100. //}
  101. //yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
  102. //desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
  103. //currentRotation = transform.rotation;
  104. //rotation = Quaternion.Lerp(currentRotation, desiredRotation, 0.02f * zoomDampening * 2);
  105. //transform.rotation = rotation;
  106. }
  107. desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * 0.02f * zoomSpeed * Mathf.Abs(desiredDistance);
  108. desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
  109. currentDistance = Mathf.Lerp(currentDistance, desiredDistance, 0.02f * zoomDampening);
  110. position = targetObject.position - (rotation * Vector3.forward * currentDistance + targetOffset);
  111. transform.position = position;
  112. }
  113. }
  114. private static float ClampAngle(float angle, float min, float max)
  115. {
  116. if (angle < -360)
  117. angle += 360;
  118. if (angle > 360)
  119. angle -= 360;
  120. return Mathf.Clamp(angle, min, max);
  121. }
  122. /// <summary>
  123. /// 检测是否点击UI
  124. /// </summary>
  125. /// <param name="mousePosition">鼠标位置</param>
  126. /// <returns></returns>
  127. private bool IsPointerOverGameObject(Vector2 mousePosition)
  128. {
  129. //创建一个点击事件
  130. PointerEventData eventData = new PointerEventData(EventSystem.current);
  131. eventData.position = mousePosition;
  132. List<RaycastResult> raycastResults = new List<RaycastResult>();
  133. //向点击位置发射一条射线,检测是否点击UI
  134. EventSystem.current.RaycastAll(eventData, raycastResults);
  135. if (raycastResults.Count > 0)
  136. {
  137. // Debug.Log("raycastResults[0].gameObject.name="+ raycastResults[0].gameObject.name);
  138. if (raycastResults[0].gameObject.name == "RawImage")//判断是否 是 自己要点击的UI
  139. {
  140. return true;
  141. }
  142. else
  143. {
  144. return false;
  145. }
  146. }
  147. else
  148. {
  149. return false;
  150. }
  151. }
  152. /// <summary>
  153. /// 获取鼠标停留处UI
  154. /// </summary>
  155. /// <param name="canvas"></param>
  156. /// <returns></returns>
  157. public string GetOverUI(GameObject canvas)
  158. {
  159. PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
  160. pointerEventData.position = Input.mousePosition;
  161. GraphicRaycaster gr = canvas.GetComponent<GraphicRaycaster>();
  162. List<RaycastResult> results = new List<RaycastResult>();
  163. gr.Raycast(pointerEventData, results);
  164. if (results.Count != 0)
  165. {
  166. Debug.Log("");
  167. return results[0].gameObject.name;
  168. }
  169. return null;
  170. }
  171. }
  172. }

 6.鼠标点击 模型 触发事件

  1. using UnityEngine;
  2. using UnityEngine.EventSystems;
  3. using UnityEngine.UI;
  4. namespace App.UI.Event
  5. {
  6. public class RaycastFromMouse : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler, IDragHandler, IBeginDragHandler, IEndDragHandler
  7. {
  8. public Camera renderCamera;
  9. public RawImage rawImage;
  10. public void OnPointerClick(PointerEventData eventData)
  11. {
  12. if (eventData.button== InputButton.Left)//鼠标左键
  13. {
  14. // 获取鼠标点击位置
  15. Vector2 clickPosition = eventData.position;
  16. // 将屏幕坐标转换为 RawImage 的本地坐标
  17. Vector2 localPoint;
  18. RectTransformUtility.ScreenPointToLocalPointInRectangle(rawImage.rectTransform, clickPosition, eventData.pressEventCamera, out localPoint);
  19. // 将 RawImage 的本地坐标映射到 RenderTexture 的分辨率范围内
  20. Rect rect = rawImage.rectTransform.rect;
  21. Vector2 normalizedPoint = new Vector2((localPoint.x - rect.x) / rect.width, (localPoint.y - rect.y) / rect.height);
  22. // 将转换后的坐标转换为射线
  23. Ray ray = renderCamera.ViewportPointToRay(normalizedPoint);
  24. // 发射射线,检测是否与3D模型交互
  25. RaycastHit hit;
  26. if (Physics.Raycast(ray, out hit))
  27. {
  28. // 获取物体上的 EventTrigger 组件
  29. EventTrigger eventTrigger = hit.collider.gameObject.GetComponent<EventTrigger>();
  30. // 如果组件存在,触发 Pointer Click 事件
  31. if (eventTrigger != null)
  32. {
  33. Debug.Log("hit.name=" + hit.collider.gameObject.name);
  34. YangFangOneManage.Instance.SetZhiWu(hit.collider.gameObject.name);
  35. SetJieShao(hit.collider.gameObject.name);
  36. StepManage.Instance.Toolkit2DItmeEvent_.Invoke(hit.collider.gameObject.name);
  37. }
  38. }
  39. }
  40. }
  41. public void OnPointerClick(PointerEventData eventData)
  42. {
  43. // 获取鼠标点击位置
  44. Vector2 clickPosition = eventData.position;
  45. // 将屏幕坐标转换为 RawImage 的本地坐标
  46. Vector2 localPoint;
  47. RectTransformUtility.ScreenPointToLocalPointInRectangle(rawImage.rectTransform, clickPosition, eventData.pressEventCamera, out localPoint);
  48. // 将 RawImage 的本地坐标映射到 RenderTexture 的分辨率范围内
  49. Rect rect = rawImage.rectTransform.rect;
  50. Vector2 normalizedPoint = new Vector2((localPoint.x - rect.x) / rect.width, (localPoint.y - rect.y) / rect.height);
  51. // 将转换后的坐标转换为射线
  52. Ray ray = renderCamera.ViewportPointToRay(normalizedPoint);
  53. // 发射射线,检测是否与3D模型交互
  54. RaycastHit hit;
  55. if (Physics.Raycast(ray, out hit))
  56. {
  57. // 获取物体上的 EventTrigger 组件
  58. EventTrigger eventTrigger = hit.collider.gameObject.GetComponent<EventTrigger>();
  59. // 如果组件存在,触发 Pointer Click 事件
  60. if (eventTrigger != null)
  61. {
  62. ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.pointerClickHandler);
  63. }
  64. }
  65. }
  66. private GameObject selectedObject;
  67. public void OnPointerDown(PointerEventData eventData)
  68. {
  69. RaycastHit hit;
  70. if (RaycastToRenderTexture(eventData, out hit))
  71. {
  72. EventTrigger eventTrigger = hit.collider.gameObject.GetComponent<EventTrigger>();
  73. if (eventTrigger != null)
  74. {
  75. ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.pointerDownHandler);
  76. selectedObject = eventTrigger.gameObject;
  77. }
  78. }
  79. }
  80. public void OnPointerUp(PointerEventData eventData)
  81. {
  82. if (selectedObject != null)
  83. {
  84. EventTrigger eventTrigger = selectedObject.GetComponent<EventTrigger>();
  85. if (eventTrigger != null)
  86. {
  87. ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.pointerUpHandler);
  88. selectedObject = null;
  89. }
  90. }
  91. }
  92. public void OnBeginDrag(PointerEventData eventData)
  93. {
  94. if (selectedObject != null)
  95. {
  96. EventTrigger eventTrigger = selectedObject.GetComponent<EventTrigger>();
  97. if (eventTrigger != null)
  98. {
  99. ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.beginDragHandler);
  100. }
  101. }
  102. GlobalEvent.Dispatch(UIExecuteEvent.OnBeginDragEvent, eventData);
  103. }
  104. public void OnDrag(PointerEventData eventData)
  105. {
  106. if (selectedObject != null)
  107. {
  108. EventTrigger eventTrigger = selectedObject.GetComponent<EventTrigger>();
  109. if (eventTrigger != null)
  110. {
  111. ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.dragHandler);
  112. }
  113. }
  114. GlobalEvent.Dispatch(UIExecuteEvent.OnDragEvent, eventData);
  115. }
  116. public void OnEndDrag(PointerEventData eventData)
  117. {
  118. if (selectedObject != null)
  119. {
  120. EventTrigger eventTrigger = selectedObject.GetComponent<EventTrigger>();
  121. if (eventTrigger != null)
  122. {
  123. ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.endDragHandler);
  124. }
  125. }
  126. GlobalEvent.Dispatch(UIExecuteEvent.OnEndDragEvent, eventData);
  127. }
  128. private bool RaycastToRenderTexture(PointerEventData eventData, out RaycastHit hit)
  129. {
  130. Vector2 clickPosition = eventData.position;
  131. Vector2 localPoint;
  132. RectTransformUtility.ScreenPointToLocalPointInRectangle(rawImage.rectTransform, clickPosition, eventData.pressEventCamera, out localPoint);
  133. Rect rect = rawImage.rectTransform.rect;
  134. Vector2 normalizedPoint = new Vector2((localPoint.x - rect.x) / rect.width, (localPoint.y - rect.y) / rect.height);
  135. Ray ray = renderCamera.ViewportPointToRay(normalizedPoint);
  136. return Physics.Raycast(ray, out hit);
  137. }
  138. }
  139. }

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

闽ICP备14008679号