实现模型拖拽体积改变功能算法:

        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);            }                    }


©著作权归作者所有:来自51CTO博客作者洞悉ONE的原创作品,如需转载,请注明出处,否则将追究法律责任

你的鼓励让我更有动力

赞赏

0人进行了赞赏支持

更多相关文章

  1. 制作一幅带有天地图底图的研究区位图(附练习数据下载)
  2. Windows Terminal将在下个版本提供设置GUI
  3. Pycharm 查看代码引用时,想跳回到上一步 设置
  4. <JVM下篇:性能监控与调优篇>04-JVM运行时参数
  5. win10怎么设置定时关机计划任务
  6. 2.3 Matplotlib 设置坐标轴
  7. 03-Vue_样式设置
  8. RocketMQ入门到入土(七 )为什么同一个消费组设置不同tag会出现奇
  9. 小白前端入门笔记(10),怎么设置网站内部的超链接?

随机推荐

  1. android复制数据库到SD卡(网上搜集,未经验
  2. Android中通过Intent 调用图片、视频、音
  3. [Android]PhoneGap源码分析——CallbackS
  4. Android(安卓)异步获取网络图片并处理图
  5. Android四大基本组件介绍与生命周期
  6. android 横屏重启的解决方案
  7. Android 强制设置横屏或竖屏 设置全屏
  8. android之ListView和SimpleAdapter的组合
  9. android各种提示Dialog 弹出框
  10. 系出名门Android(7) - 控件(View)