代码之家  ›  专栏  ›  技术社区  ›  Daniel Lip

如何在具有圆高度的绘制圆上更改对象?

  •  0
  • Daniel Lip  · 技术社区  · 6 月前

    我在谷歌上搜索,发现linerenderer高度位置有问题。当更改绘制线的高度位置时,如果我也更改对象的位置,如立方体,则线渲染器线将有一些延迟,并且不会与立方体移动相同的高度。导致立方体更快地上下移动,并且与绘制的线有很大的偏移高度。

    不确定如何减少代码,因为它们都是相互关联的。但代码正在使用复制/粘贴。

    这是绘制的圆圈高度为0时的屏幕截图。立方体在圆上。 这很好。

    cubes on circle

    现在是在检查器中稍微改变高度时的屏幕截图。 立方体向上移动得很快,而圆圈移动得慢得多。

    changed the height value in the inspector the cubes are much higher and moved much faster then the circle

    在CreatePoint方法中,我将y变量设置为高度变量,然后将其设置为圆。这会改变圆的高度。

    void CreatePoints()
    {
        float angleStep = 360f / segments;
        float angle = 0f;
        float y = height; // Fixed height for the circle plane
    
        // Adjust radii based on parent's scale
        Vector3 parentScale = transform.parent ? transform.parent.lossyScale : Vector3.one;
        float adjustedXRadius = xradius / parentScale.x;
        float adjustedYRadius = yradius / parentScale.z;
    
        for (int i = 0; i <= segments; i++) // <= to close the circle
        {
            float x = Mathf.Sin(Mathf.Deg2Rad * angle) * adjustedXRadius;
            float z = Mathf.Cos(Mathf.Deg2Rad * angle) * adjustedYRadius;
    
            line.SetPosition(i, new Vector3(x, y, z));
    
            angle += angleStep;
        }
    }
    

    在方法AdjustPositions中,i根据高度更改立方体在y轴上的位置。

    private void AdjustPositions(int num, Vector3 point, float xRadius, float yRadius)
    {
        if (objects == null || objects.Length == 0 || num <= 0) return;
    
        for (int i = 0; i < objects.Length; i++)
        {
            if (objects[i] == null) continue; // Skip if the object was destroyed
    
            // Distance around the ellipse
            var radians = 2 * Mathf.PI / num * i;
    
            // Calculate the new position on the ellipse
            var x = Mathf.Cos(radians) * xRadius;
            var z = Mathf.Sin(radians) * yRadius;
    
            var spawnPos = point + new Vector3(x, height, z); // Set position on ellipse
    
            // Update object position
            objects[i].transform.position = spawnPos;
    
            // Rotate the object to face the center
            objects[i].transform.LookAt(point);
        }
    }
    

    我试图在代码中将useworldspace设置为true,我将其设置为false,但即使为true,它也不能很好地工作。我试着用lateupdate代替update,但它也没有太大变化。我试图计算自动偏移量并将偏移量添加到圆上,但也不起作用,我想我真的不知道如何自动计算所需的偏移量。

    1 回复  |  直到 6 月前
        1
  •  1
  •   derHugo    6 月前

    如上所述,世界空间与地方空间定位似乎存在不匹配/误解。

    如您当前使用的

    line.useWorldSpace = false;
    

    所有的线点将位于局部空间中,而所有的物体都位于绝对世界空间中

    objects[i].transform.position = spawnPos;
    

    因为你的物体在高处 47.1 该线默认具有此高度,因此会根据场景中对象的位置产生偏移。


    修复在很大程度上取决于你想要的行为。主要是你是否愿意

    • 追求绝对的世界空间

      在这种情况下,您要设置

      line.useWorldSpace = true;
      

      并摆脱 adjustedXRadius adjustedYRadius 而是对绝对世界空间坐标中的线点和对象位置使用完全相同的公式。

    • 或者去当地空间。

      那样的话,我还是会把 调整X射线 调整后的Y半径 。对线点和对象使用完全相同的公式。但是,为了将其应用于对象位置,请额外使用 transform.TransformPoint 以便在局部空间中计算所有,但在世界空间坐标中应用对象位置。

    局部空间的优点:您可以围绕对象自由拖动,以重新定位整个装备的线和对象。


    老实说,就我个人而言,我甚至会更进一步,确保这些对象被放置为对象的子对象,这样你就可以简单地使用 transform.localPosition 并使它们与主对象一起正确缩放和旋转,因为它们都是相对于该根的。你也不必经过 FindGameObjectsWithTag imho总是有点难看,因为你已经有了你的孩子对象。