简书链接:解决缩放完美插入到物体上方的方法探讨
文章字数:1064,阅读全文大约需要4分钟
首先被点击的物品 :
被点击的物品 有的是轴心 有的是 顶部 有的是底部。
如果是底部那么得到的物体y就是底部的需要把被点击物体y+当前物体材质的高度y加上才定位到顶点y,
然后要插入顶点 则直接y等于顶点就行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | /// <summary>       /// 插入一个指定长度的柱子 位于指定的y轴上方        /// </summary>       /// <param name="position"></param>       /// <param name="floatY"></param>       /// <param name="verticalMode">0 代表 底部  1 代表中心 1 代表 顶部</param>       /// <param name="color"></param>       internal static void DebugPrimitiveColorHeightInsertBar(Vector3 position, Vector3 size, float verticalMode, float selfHeight, Color color)       {           GameObject gameObject = GameObject.CreatePrimitive(PrimitiveType.Cube);           gameObject.transform.localScale = new Vector3(0.1f, selfHeight, 0.1f);           gameObject.GetComponent<Renderer>().material.color = color;           float baseY;           if (verticalMode == 0)//轴心为底部 加上自身大小           {               baseY = position.y + size.y;           }           else if (verticalMode == 1)//轴心为中心 加上自身大小的一半           {               baseY = position.y + (size.y / 2f);//轴心Y               gameObject.transform.position = new Vector3(position.x, baseY +(selfHeight == 1 ? 0 : (selfHeight - 1) / 2f), position.z);           }           else           {               baseY = position.y;//轴心为顶部 则不需要加上自身大小               gameObject.transform.position = new Vector3(position.x, baseY + (selfHeight == 1 ? 0 : (selfHeight - 1) / 2f), position.z);           }       }
 
   | 
 
测试
1 2 3
   | DebugPrimitiveColorHeightInsertBar(clickedMaterialGameObject.transform.position, clickedMaterialSize, 1, 3, Color.red);         DebugPrimitiveColorHeightInsertBar(clickedMaterialGameObject.transform.position, clickedMaterialSize, 0, 30, Color.green);
 
   | 
 
输出结果

为了验证是否精确,于是我设置了一个超长缩放的条块

上面的红色平面 是和红色块是一起的,绿色平面在天上了

立方体的轴心是在立方体中心
但是测试的时候发现 还是基于y坐标加材质的高度才能计算出顶点,
但是测试其他不规则物体的时候轴心是底部,但是也是用了被点击物体y坐标+被点击物体的高度材质   + (1-(缩放后的高度)/2) 
关于计算任何轴心的方式我陷入了沉思

上图的黑色 平面是用于输出y坐标轴心 忽略原始轴心的,但是网上这个方法似乎并不好使。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
   |     Vector3 vector3 = CalcModelCenter(clickedMaterialGameObject.transform); DebugPrimitiveColorHeight(clickedMaterialGameObject.transform.position, vector3.y, Color.black);
 
 
        internal static void DebugPrimitiveColorHeight(Vector3 position, float floatY, Color color)         {             GameObject gameObject = GameObject.CreatePrimitive(PrimitiveType.Plane);             gameObject.transform.localScale = new Vector3(0.4f, 1, 0.4f);             gameObject.GetComponent<Renderer>().material.color = color;             gameObject.transform.position = new Vector3(position.x, floatY, position.z);         }
 
 
    /// <summary>         /// 计算模型的中心点         /// </summary>         /// <param name="tran"></param>         /// <returns></returns>         public static Vector3 CalcModelCenter(Transform tran)         {             Vector3 position = tran.position;             Quaternion quaternion = tran.rotation;             Vector3 scale = tran.localScale;             tran.position = Vector3.zero;             tran.rotation = Quaternion.Euler(Vector3.zero);             tran.localScale = Vector3.one;             Vector3 center = Vector3.zero;             Renderer[] renders = tran.GetComponentsInChildren<Renderer>();             foreach (Renderer child in renders)             {                 center += child.bounds.center;             }             center /= tran.GetComponentsInChildren<Renderer>().Length;             Bounds bounds = new Bounds(center, Vector3.zero);             foreach (Renderer item in renders)             {                 bounds.Encapsulate(item.bounds);             }             tran.position = position;             tran.rotation = quaternion;             tran.localScale = scale;             foreach (Transform item in tran)             {                 item.position = item.position - bounds.center;             }             return bounds.center + tran.position;         }
 
   | 
 
所以到底有没有忽略轴心真正得出顶点低点的正确代码呢。关于插入顶点的问题 
在rect  cavans world 有点问题了


 一个是缩放的立方体照样 精准插入头部,另外一个是图表,我加了box mesh 等于图表大小, 缩放了rect size ,显然算得有点偏差了,缩放值越大偏差越大 ,现在我计算得到大小大概是20 ,但是显然中心点算错了,图表偏离那么多
所以各位大佬 到底怎么解决这个问题。
最后我突然发现我有把canvas也缩放过得呢,所以 获取父canvas 获取缩放值,也乘上缩放值 ,进行还原 真实的大小,得到了真实的大小/2就能得到摆放的位置了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
   |            DebugSmartPrimitiveColorHeight(clickedMaterialGameObject.transform, clickedMaterialSize,0,Color.blue);           float parentScale=chartGameObject.GetComponentInParent<Canvas>().transform.localScale.y;           GameUtil.DebugSmallInsertArticleTopBy(clickedMaterialGameObject.transform, clickedMaterialSize, chartGameObject.GetComponentInChildren<Collider>().bounds.size.y* chartGameObject.transform.localScale.y* parentScale, 0,chartGameObject.transform);           GameObject gameObjectTest = GameObject.CreatePrimitive(PrimitiveType.Cube);           gameObjectTest.transform.localScale = new Vector3(0.2f, 30f, 0.2f);           GameUtil.DebugSmallInsertArticleTopBy(clickedMaterialGameObject.transform, clickedMaterialSize, gameObjectTest.transform.localScale.y, 0, gameObjectTest.transform);
 
 
 
 
 
 
       internal static void DebugSmallInsertArticleTopBy(Transform transform, Vector3 size, float selfHeight,float margin, Transform transformInnsert)       {
            float baseY;           Vector3 vector3 = GetCenter(transform);           baseY = vector3.y + size.y+ margin;           transformInnsert.position = new Vector3(transform.position.x, baseY  + (selfHeight == 1 ? 0 : (selfHeight - 1) / 2f), transform.position.z);           Debug.Log("插入" + transform.name + "物体上方,被插入物体:" + transformInnsert.name + ",被插入物体高度:" + selfHeight + ",顶点y:" + baseY + ",插入的物体y:" + transformInnsert.position.y);
        }
 
  /// <summary>       /// 获得中心点       /// </summary>       /// <param name="target"></param>       /// <returns></returns>       public static Vector3 GetCenter(Transform target)       {           Renderer[] mrs = target.GetComponentsInChildren<Renderer>();           Vector3 center = target.transform.position;           if (mrs.Length != 0)           {               Bounds bounds = new Bounds(center, Vector3.zero);               foreach (Renderer item in mrs)               {                   bounds.Encapsulate(item.bounds);               }               center = bounds.center;           }           return center;       }
 
 
  | 
 
至于这个获取被点击物品中心点的应该还是有问题的,我发现得到的可能是底部位置 ,所以我加了被点击物体的高度才得到 顶部位置
最后总结思路:被点击物体的顶点
然后被点击物体的顶部位置 +(被插入的真实大小(需要还原缩放之前的大小)/2)