实现模型拖拽体积改变功能算法:
public Transform crossLeft; public Transform cro***ight; public Transform arrowUp; public Transform arrowDown; //模型结构子对象 public Transform legLeftUp; public Transform legRightUp; public Transform legLeftDown; public Transform legRightDown; public Transform arrow; /// /// 传动带模型MeshFilter /// public MeshFilter conveyorMeshFilter; /// /// 传送带边沿护栏模型MeshFilter /// public MeshFilter guardBarMeshFilter; public BoxCollider BoxCollider; //Mesh保存 private Dictionary conveyorMeshLeftVertices; private Dictionary conveyorMeshRightVertices; private Dictionary conveyorMeshUpVertices; private Dictionary conveyorMeshDownVertices; private Dictionary guardBarMeshLeftVertices; private Dictionary guardBarMeshRightVertices; private Dictionary guardBarMeshUpVertices; private Dictionary guardBarMeshDownVertices; //交互所用变量 private float firstdistancetoOtherCross; private Vector3 NowInputMousePosition; float enddistance; private Transform otherCross; private Vector3 otherCrossScreenPostion; private Vector3 lastInputMousePoistion;
核心方法:
//初始化 void Init() { conveyorMeshLeftVertices = FiltrateVertices(conveyorMeshFilter.mesh, VecticeDir.Left); conveyorMeshRightVertices = FiltrateVertices(conveyorMeshFilter.mesh, VecticeDir.Right); conveyorMeshUpVertices = FiltrateVertices(conveyorMeshFilter.mesh, VecticeDir.Up); conveyorMeshDownVertices = FiltrateVertices(conveyorMeshFilter.mesh, VecticeDir.Down); guardBarMeshLeftVertices = FiltrateVertices(guardBarMeshFilter.mesh, VecticeDir.Left); guardBarMeshRightVertices = FiltrateVertices(guardBarMeshFilter.mesh, VecticeDir.Right); guardBarMeshUpVertices = FiltrateVertices(guardBarMeshFilter.mesh, VecticeDir.Up); guardBarMeshDownVertices = FiltrateVertices(guardBarMeshFilter.mesh, VecticeDir.Down); //length = 1; //heigth = 1; BoxCollider = gameObject.GetComponent(); if (name.Contains("left")) { otherCross = converyEntityMediator.converyEntityView.cro***ight; isLeft = true; } else { otherCross = converyEntityMediator.converyEntityView.crossLeft; isLeft = false; } } /// /// 筛选顶点,分成左右两堆 /// /// 顶点方向 Dictionary FiltrateVertices(Mesh mesh, VecticeDir dir) { Dictionary result = new Dictionary(); for (int i = 0; i < mesh.vertices.Length; i++) { switch (dir) { case VecticeDir.Left: if (mesh.vertices[i].z > 0) { result.Add(i, mesh.vertices[i]); } break; case VecticeDir.Up: if (mesh.vertices[i].x > 0) { result.Add(i, mesh.vertices[i]); } break; case VecticeDir.Right: if (mesh.vertices[i].z < 0) { result.Add(i, mesh.vertices[i]); } break; case VecticeDir.Down: if (mesh.vertices[i].x < 0) { result.Add(i, mesh.vertices[i]); } break; } } return result; } //宽度 public void ChangeWidth(float width,Vector3 dir, bool isUp) { List conveyorMeshVertices = new List(conveyorMeshFilter.mesh.vertices); List guardBarMeshVertices = new List(guardBarMeshFilter.mesh.vertices); float halfWidth = width / 2; transform.position += halfWidth * (transform.rotation * dir).normalized; //this.length += length; //改变板和边栏的长度 foreach (keyvaluePair item in conveyorMeshUpVertices) { conveyorMeshVertices[item.Key] += Vector3.right * halfWidth; } foreach (keyvaluePair item in conveyorMeshDownVertices) { conveyorMeshVertices[item.Key] -= Vector3.right * halfWidth; } foreach (keyvaluePair item in guardBarMeshUpVertices) { guardBarMeshVertices[item.Key] += Vector3.right * halfWidth; } foreach (keyvaluePair item in guardBarMeshDownVertices) { guardBarMeshVertices[item.Key] -= Vector3.right * halfWidth; } if (isUp) { //设置子物体的位置 legLeftUp.localPosition += halfWidth * dir; legRightUp.localPosition += halfWidth * dir; legLeftDown.localPosition -= halfWidth * dir; legRightDown.localPosition -= halfWidth * dir; arrowUp.localPosition += halfWidth * dir; arrowDown.localPosition -= halfWidth * dir; } else { //设置子物体的位置 legLeftUp.localPosition -= halfWidth * dir; legRightUp.localPosition -= halfWidth * dir; legLeftDown.localPosition += halfWidth * dir; legRightDown.localPosition += halfWidth * dir; arrowUp.localPosition -= halfWidth * dir; arrowDown.localPosition += halfWidth * dir; } float arrowScale = Mathf.Clamp(((ConveyorEntity)entity).conveyorProperty.Width * 2f, 0.2f, 1); arrow.localScale = new Vector3(arrowScale, 1, arrowScale); conveyorMeshFilter.mesh.SetVertices(conveyorMeshVertices); guardBarMeshFilter.mesh.SetVertices(guardBarMeshVertices); //设置collider BoxCollider.size += Vector3.right * width; } /// 改变传送带长度 /// /// 传送带长度 /// 是否选择的左边移动 public void ChangeLength(float length, Vector3 dir,bool isChoiceLeft = false) { List conveyorMeshVertices = new List(conveyorMeshFilter.mesh.vertices); List guardBarMeshVertices = new List(guardBarMeshFilter.mesh.vertices); float halfLength = length / 2; transform.position += halfLength *( transform.rotation * dir).normalized; //改变板和边栏的长度 foreach (keyvaluePair item in conveyorMeshLeftVertices) { conveyorMeshVertices[item.Key] += Vector3.forward * halfLength; } foreach (keyvaluePair item in guardBarMeshLeftVertices) { guardBarMeshVertices[item.Key] += Vector3.forward * halfLength; } foreach (keyvaluePair item in conveyorMeshRightVertices) { conveyorMeshVertices[item.Key] -= Vector3.forward * halfLength; } foreach (keyvaluePair item in guardBarMeshRightVertices) { guardBarMeshVertices[item.Key] -= Vector3.forward * halfLength; } if (isChoiceLeft) { //设置子物体的位置 legLeftUp.localPosition += halfLength * dir; legRightUp.localPosition -= halfLength * dir; legLeftDown.localPosition += halfLength * dir; legRightDown.localPosition -= halfLength * dir; crossLeft.localPosition += halfLength * dir; cro***ight.localPosition -= halfLength * dir; } else { //设置子物体的位置 legLeftUp.localPosition -= halfLength * dir; legRightUp.localPosition += halfLength * dir; legLeftDown.localPosition -= halfLength * dir; legRightDown.localPosition += halfLength * dir; crossLeft.localPosition -= halfLength * dir; cro***ight.localPosition += halfLength * dir; } //float arrowScale = Mathf.Clamp(((ConveyorEntity)entity).conveyorProperty.Length * 2f, 0.2f, 1); //arrow.localScale = new Vector3(arrowScale, 1, arrowScale); conveyorMeshFilter.mesh.SetVertices(conveyorMeshVertices); guardBarMeshFilter.mesh.SetVertices(guardBarMeshVertices); //设置collider BoxCollider.size += Vector3.forward * length; ChangeBounds(100);//拉伸mesh会导致原bound不在摄像机视角下,造成传送带不渲染 (Frustum Culling) } private void ChangeBounds(float boundLength) { Vector3 bound = new Vector3(boundLength, boundLength, boundLength); conveyorMeshFilter.mesh.bounds = new Bounds(transform.position, bound); guardBarMeshFilter.mesh.bounds = new Bounds(transform.position, bound); }
交互输入:
private void OnMouseDown() { endAdddistance = 0; otherArrowScreenPostion = Camera.main.WorldToScreenPoint(otherArrow.position); lastInputMousePoistion = Input.mousePosition; lastdistancetoOtherCross = Vector2.distance(otherArrowScreenPostion, lastInputMousePoistion); } private void OnMouseDrag() { NowInputMousePosition = Input.mousePosition; float distance = Vector2.distance(NowInputMousePosition, lastInputMousePoistion) * 0.1f; float otherdistacetoNowInputMousePosition = Vector2.distance(otherArrowScreenPostion, NowInputMousePosition); //减少宽度 if (lastdistancetoOtherCross > otherdistacetoNowInputMousePosition) { endAdddistance -= distance; ChangeWidth(-distance, (transform.localPosition - otherArrow.localPosition).normalized, isUp); } //增加宽带 else if (lastdistancetoOtherCross < otherdistacetoNowInputMousePosition) { endAdddistance += distance; ChangeWidth(distance, (transform.localPosition - otherArrow.localPosition).normalized, isUp); } if (otherdistacetoNowInputMousePosition otherdistacetoNowInputMousePosition) { if (Vector3.distance(transform.localPosition, otherCross.localPosition) Vector3.distance(transform.localPosition, otherCross.localPosition)) { return; } enddistance -= distance; converyEntityMediator.ChangeLength(-distance, (transform.localPosition - otherCross.localPosition).normalized, isLeft); } //增加长度 else if (firstdistancetoOtherCross < otherdistacetoNowInputMousePosition) { enddistance += distance; converyEntityMediator.ChangeLength(distance, (transform.localPosition - otherCross.localPosition).normalized, isLeft); } lastInputMousePoistion = Input.mousePosition; lastdistancetoOtherCross = Vector2.distance(otherArrowScreenPostion, lastInputMousePoistion); } private void onmouseup() { if (endAdddistance != 0) { ChangeWidth(-endAdddistance, (transform.localPosition - otherArrow.localPosition).normalized, isUp); ChangeLength(-enddistance, (transform.localPosition - otherCross.localPosition).normalized, isLeft); } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。