Unity物体Mesh(网格)合并,添加BoxCollider,修改Rotation

最近刚接触Unity,并且要实战到项目当中,压力是有点大。

先说一下项目需求:

1.在网页上运行。

2.跟随鼠标旋转

3.鼠标点击弹出该物体信息

乍一看其实挺简单的,

首先unity提供了WebGL,第一条就算解决了。跟随鼠标旋转的其实也就是一段代码,如下:

复制代码

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 
 5 
 6 public class MouseView : MonoBehaviour
 7 {
 8 
 9     public enum RotationAxes
10     {
11         MouseXAndY = 0,
12         MouseX = 1,
13         MouseY = 2
14     }
15 
16     public RotationAxes m_axes = RotationAxes.MouseXAndY;
17     public float m_sensitivityX = 10f;
18     public float m_sensitivityY = 10f;
19 
20     // 水平方向的 镜头转向
21     public float m_minimumX = -360f;
22     public float m_maximumX = 360f;
23     // 垂直方向的 镜头转向 (这里给个限度 最大仰角为25°)
24     public float m_minimumY = -25f;
25     public float m_maximumY = 25f;
26 
27     float m_rotationY = 0f;
28 
29 
30     // Use this for initialization
31     void Start()
32     {
33         // 防止 刚体影响 镜头旋转
34         if (GetComponent<Rigidbody>())
35         {
36             GetComponent<Rigidbody>().freezeRotation = true;
37         }
38     }
39 
40     // Update is called once per frame
41     void Update()
42     {
43         if (Input.GetMouseButton(0))
44         { 
45             if (m_axes == RotationAxes.MouseXAndY)
46             {
47                 float m_rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * m_sensitivityX;
48                 m_rotationY += Input.GetAxis("Mouse Y") * m_sensitivityY;
49                 m_rotationY = Mathf.Clamp(m_rotationY, m_minimumY, m_maximumY);
50 
51                 transform.localEulerAngles = new Vector3(-m_rotationY, m_rotationX, 0);
52             }
53             else if (m_axes == RotationAxes.MouseX)
54             {
55                 transform.Rotate(0, Input.GetAxis("Mouse X") * m_sensitivityX, 0);
56             }
57             else
58             {
59                 m_rotationY += Input.GetAxis("Mouse Y") * m_sensitivityY;
60                 m_rotationY = Mathf.Clamp(m_rotationY, m_minimumY, m_maximumY);
61 
62                 transform.localEulerAngles = new Vector3(-m_rotationY, transform.localEulerAngles.y, 0);
63             }
64         }
65     }
66 }

复制代码

第三个点击弹出信息,由于刚开始不了解里面的机制(现在也不是很懂)在这里跌了一个跟头,首先点击事件很简单,但是要弹出窗口就突然找不到思路了,在网上找了一大圈得到以下解决方法

复制代码

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 
 5 public class click001 : MonoBehaviour {
 6     public bool WindowShow = false;
 7     private Rect rect = new Rect(30, 40, 150, 150);
 8 
 9     public Renderer rend;
10 
11     public int fontSize;
12     public FontStyle fontStyle;
13     public RectOffset margin;
14     public RectOffset padding;
15 
16     void Start()
17     {
18         //获取renderer组件
19         rend = GetComponent<Renderer>();
20     }
21 
22     
23     void OnGUI()
24     {
25         //窗口id  窗口大小  窗口回调(定义窗口内视图) 窗口标题
26         if (WindowShow)
27         {
28             //项目需要,这是我自己添加的条件
29             if (gameObject.tag == "xxx")
30             {
31                 GUI.Window(0, rect, onWindowOne, "xxxx");
32             }
33         }
34         
35     }
36 
37 
38     void onWindowOne(int winId)
39     {
40         //项目需要,这是我自己添加的条件
41         if (gameObject.tag == "xxxx")
42         {
43             GUI.Label(new Rect(10, 10, 140, 40), "当前窗口是xxxxx");
44         }
45 
46         //GUI.Label(new Rect(10, 10, 140, 40), "当前窗口id是" + winId);
47         if (GUI.Button(new Rect(10, 30, 80, 30), "按钮1"))
48         {
49             Debug.Log("当前窗口id" + winId);
50         }
51         //定义窗体可以活动的范围
52         //GUI.DragWindow(new Rect(0, 0, 10000, 10000));
53     }
54 
55     void OnMouseDown()
56     {
57         if (WindowShow)
58         {
59             WindowShow = false;
60         }
61         else
62         {
63             WindowShow = true;
64         }
65         
66     }
67 }      

复制代码

到这里一切搞定,可惜高兴的不是时候,当我在页面打开的时候,发现中文字体全部消失了,原来unity默认的字体是Arial,我们只需要替换成支持中文的字体即可,在脚本里加上以下代码

 1 public Font font; 

当然,需要在用到字体的位置调用改变量,比如我在这两个位置有用到

1 GUI.skin.window.font = font;//GUI的弹出窗口

2 GUI.skin.label.font = font;//这个也是GUI弹出窗口里面的内容,但是不这样用,就没有效果,不知道为什么 

然后这些总算是解决了,不过新的问题又出现了,就是点击事件需要Collider支持,那就添加吧,再添加的过程中我发现这样实在是耗时费力,而且还不精确,然后我就请教了大神,大神一语道破其中的问题所在!

原来我是把我需要组成一组的元素都放在了一个空Game Object里,如果给它添加BoxCollider,会很麻烦,可以说根本就不适合添加,因为它没有Mesh,也就是网格,所以就需要添加网格,既然它是组合成的一个组,

所以需要动态的添加网格,当然也需要动态添加BoxCollider,然后当运行以后,我发现物体的位置发生了变化,好吧,那就再控制一下位置,保持和Scene里看到的一致即可,下面是代码

复制代码

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class Combine_Test : MonoBehaviour
 5 {
 6 
 7     // Use this for initialization
 8     void Start()
 9     {
10         //---------------- 先获取材质 -------------------------
11         //获取自身和所有子物体中所有MeshRenderer组件
12         MeshRenderer[] meshRenderers = GetComponentsInChildren<MeshRenderer>();
13         //新建材质球数组
14         Material[] mats = new Material[meshRenderers.Length];
15         for (int i = 0; i < meshRenderers.Length; i++)
16         {
17             //生成材质球数组 
18             mats[i] = meshRenderers[i].sharedMaterial;
19         }
20         //---------------- 合并 Mesh -------------------------
21         //获取自身和所有子物体中所有MeshFilter组件
22         MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
23         CombineInstance[] combine = new CombineInstance[meshFilters.Length];
24         for (int i = 0; i < meshFilters.Length; i++)
25         {
26             combine[i].mesh = meshFilters[i].sharedMesh;
27             //矩阵(Matrix)自身空间坐标的点转换成世界空间坐标的点 
28             combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
29             meshFilters[i].gameObject.SetActive(false);
30         }
31         //为新的整体新建一个mesh
32         transform.GetComponent<MeshFilter>().mesh = new Mesh();
33         //合并Mesh. 第二个false参数, 表示并不合并为一个网格, 而是一个子网格列表
34         transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine, false);
35         transform.gameObject.SetActive(true);
36 
37         //为合并后的新Mesh指定材质 ------------------------------
38         transform.GetComponent<MeshRenderer>().sharedMaterials = mats;
39         //为合并后的新的整体添加BoxCollider ------------------------------
40         BoxCollider bc = gameObject.AddComponent<BoxCollider>();
41         //为合并后的新的整体修改rotation ------------------------------
42         transform.localEulerAngles = new Vector3(0, 0, 0);
43     }
44 
45     // Update is called once per frame
46     void Update()
47     {
48 
49     }
50 }

复制代码

好的到这里问题基本上都解决了,不过还有一个弹出窗口的问题没有解决,就是没有实现当我点击其他物体或空白处时,窗口消失,这确实是一个不大不小的问题,以后会进一步完善。

希望路过的大佬能留下您的建议,也希望这篇博文能帮助那些像我一样在网上疯狂找资料的小伙伴

来源:https://www.cnblogs.com/caoxen/p/9523662.html

http://yyk.familydoctor.com.cn/content_21206_979932.html

http://yyk.familydoctor.com.cn/content_21206_979937.html

http://yyk.familydoctor.com.cn/content_21206_979903.html

http://yyk.familydoctor.com.cn/content_21206_979883.html

猜你喜欢

转载自blog.csdn.net/qq_42606051/article/details/82016807