【原】Unity3D 窗口裁剪
实现效果 拖动readplane 当包围盒最小点超出bluePlane的最小点时(仅做了左边裁剪),对超出部分裁剪,当全部超出隐藏readPlane 当readPlane包围盒的最大坐标点大于bluePlane的最小点时,显示readPlane;
阅读此文时,读者最好具备世界坐标 本地坐标 bounds 等之类的知识!
collider.bounds、render.bounds的min max是世界坐标,size是大小 mesh.bounds是本地坐标。mesh.vertices对线框顶点坐标更改。
public Transform readPlane; public Transform bluePlane; Bounds readBoundPlane; Bounds blueBoundPlane; Vector3 blueBoundMin; Vector3 blueBoundMax; Mesh mesh; void Start() { mesh=readPlane.GetComponent<MeshFilter>().mesh; Vector3[] ve=mesh.vertices; print(ve[1]+"\\"+ve[3]);//readPlane最左边两个点 blueBoundPlane=bluePlane.gameObject.collider.bounds; blueBoundMin=blueBoundPlane.min; blueBoundMax=blueBoundPlane.max; print(blueBoundMin+"||||"+blueBoundMax+"|||"+blueBoundPlane.size+"|||||"+blueBoundPlane.center); } void Update() { if(Input.GetMouseButton(0)) { readBoundPlane=readPlane.GetComponent<BoxCollider>().bounds; if(readBoundPlane.min.x<blueBoundMin.x)//包围盒最小坐标x超出blue的最小坐标开始裁剪 { Vector3[] vec3=mesh.vertices; Vector3 vec3local=(readPlane.worldToLocalMatrix*new Vector3(readBoundPlane.min.x-blueBoundMin.x,0,0));//因为collider.bounds.min是世界坐标,mesh.vertices是本地坐标所以需要世界到本地的转化 vec3[1]=new Vector3(mesh.bounds.min.x-vec3local.x,vec3[1].y,vec3[1].z); vec3[3]=new Vector3(mesh.bounds.min.x-vec3local.x,vec3[3].y,vec3[3].z); Vector2[] uvs=new Vector2[vec3.Length]; for(int i=0;i<vec3.Length;i++) { if(i%2!=0) { uvs[i]=new Vector2(((readBoundPlane.min.x-blueBoundMin.x)+readBoundPlane.size.x)/readBoundPlane.size.x,mesh.uv[i].y);//更新UV } else { uvs[i]=new Vector2(mesh.uv[i].x,mesh.uv[i].y); } } mesh.uv=uvs; mesh.vertices=vec3; } if(readBoundPlane.max.x<=blueBoundMin.x) { readPlane.GetComponent<MeshRenderer>().enabled=false; } if(readBoundPlane.max.x>blueBoundMin.x) { readPlane.GetComponent<MeshRenderer>().enabled=true; } float x=Input.GetAxis("Mouse X"); float y=Input.GetAxis("Mouse Y"); readPlane.position+=new Vector3(x,y,0); } }
最终效果图: