C# 如何得到孩子';s在网格布局中的世界位置团结一致?
我有一个滚动视图,在它的内容对象中有一个GridLayoutGroup组件(内容对象有自己的位置和比例,而不是(0,0,0)或(1,1,1)),它下面有几个图像。在运行期间,我希望取出一个图像并将其父对象设置为其他UI对象,但我希望图像保持其在屏幕上的位置 然而,我尝试了以下所有方法,结果都是屏幕上的位置错误(图像有时甚至在屏幕外移动) 1对图像对象使用SetParent方法(尝试将True或false作为第二个参数): 2以第1种方式使用SetParent方法,然后手动为图像指定位置,但id不会出现在鼠标位置(此代码适用于不在layoutgroup中的其他对象): 3调用SetParent后,将位置设置为其原始值C# 如何得到孩子';s在网格布局中的世界位置团结一致?,c#,unity3d,unity5,C#,Unity3d,Unity5,我有一个滚动视图,在它的内容对象中有一个GridLayoutGroup组件(内容对象有自己的位置和比例,而不是(0,0,0)或(1,1,1)),它下面有几个图像。在运行期间,我希望取出一个图像并将其父对象设置为其他UI对象,但我希望图像保持其在屏幕上的位置 然而,我尝试了以下所有方法,结果都是屏幕上的位置错误(图像有时甚至在屏幕外移动) 1对图像对象使用SetParent方法(尝试将True或false作为第二个参数): 2以第1种方式使用SetParent方法,然后手动为图像指定位置,但id不
var p = imageObject.transform.position;
imageObject.transform.SetParent(otherObj, True);
imageObject.transform.position = new Vector3(p.x, p.y, 0);
4不要使用任何代码,但在编辑器中运行时,手动将图像拖出到目标父对象。但它的立场还是改变了
5不要使用任何代码,但在编辑器中运行时,手动取消选中GridLayoutGroup以禁用它。图像位置仍然会改变
为什么第三条路不起作用?我想可能是图像对象的transform.position没有被使用,所以该值没有被使用,所以该值不在屏幕上的位置,或者在帧结束时发生了一些事情,所以我对该位置的重置是无用的
更多信息:我的画布渲染模式设置为“屏幕空间摄影机”。但即使将其更改为覆盖,结果仍然相同。画布缩放器模式为“随屏幕大小缩放”,屏幕匹配模式为“扩展”
那么,我应该怎么做才能将图像从GridLayoutGroup中取出,但让它保持在屏幕上的位置呢?谢谢 好的,我做了一个测试项目。没有完全解决您的问题,但我让位于
0,0,0
的GridLayoutGroup的家长更改工作:rectcransform.anchoredPosition
获取中的相对位置
GridLayoutGroup
李>
RectTransform
设置新的anchoredPosition
李>
1,1,1
然后相应地除以/乘以坐标(除以2表示0.5,
0.5,0.5
)(0,0,0)
中,您可能还需要
一些路线)经过几次测试,我发现调用
SetParent(objParent,True)后的位置代码>是正确的;但是由于与GridLayoutGroup相关的原因,在这之后和帧结束之前,位置会发生变化。所以,记录下这个位置,在其他帧中做你需要的任何事情
例如:
在主线程中:
imageObject.transform.SetParent(otherObj, True);
originalPosition = imageObject.transform.position;
imageObject.SetObjectActive(false); // If not do this, the image might flicker at it's position before put it into the GridLayoutGroup. My guess is that it gets rendered before the AdjustTransInTheEndOfFrame method is executed.
StartCoroutine(AdjustTransInTheEndOfFrame(imageObject));
private IEnumerator AdjustTransInTheEndOfFrame(GameObject obj)
{
yield return new WaitForEndOfFrame();
obj.transform.position = originalPosition;
obj.SetObjectActive(true);
}
我使用此功能:
public Vector2 GetChildLocalPosition(RectTransform rectTransformGrid, RectTransform rectTransformChild)
{
var localPositionGrid = (Vector2)rectTransformGrid.localPosition;
var sizeDeltaGrid = rectTransformGrid.sizeDelta;
var deltaGridFromCenterToLeftTop = new Vector2(-0.5f * sizeDeltaGrid.x, 0.5f * sizeDeltaGrid.y);
var anchoredPositionChild = rectTransformChild.anchoredPosition;
var childPosition = localPositionGrid + anchoredPositionChild + deltaGridFromCenterToLeftTop;
return childPosition;
}
如果需要,请更新GridLayoutGroup,如下所示:
public void UpdateGrid(LayoutGroup gridLayoutGroup)
{
gridLayoutGroup.CalculateLayoutInputHorizontal();
gridLayoutGroup.CalculateLayoutInputVertical();
gridLayoutGroup.SetLayoutHorizontal();
gridLayoutGroup.SetLayoutVertical();
}
我认为在例3中,您应该在设置父项之前存储位置。@obywan感谢您的回复。这是个错误,只是编辑了一下。我在代码中做得很好。谢谢,为什么要等到框架结束呢?我过去只使用示例中显示的简单方法,并使其工作,但我有一段时间没有进行测试,最近在我的项目中更改了太多代码和结构。现在我不能再像以前那样让它工作了:(关于WaitForEndOfFrame-如果你在更改父项后立即设置锚点,它将保持不变。不确定确切原因,可能是因为执行顺序。是的,WaitForEndOfFrame在打断我的头后为我做了这件事,解释了为什么我无法获得该职位。谢谢!!
public Vector2 GetChildLocalPosition(RectTransform rectTransformGrid, RectTransform rectTransformChild)
{
var localPositionGrid = (Vector2)rectTransformGrid.localPosition;
var sizeDeltaGrid = rectTransformGrid.sizeDelta;
var deltaGridFromCenterToLeftTop = new Vector2(-0.5f * sizeDeltaGrid.x, 0.5f * sizeDeltaGrid.y);
var anchoredPositionChild = rectTransformChild.anchoredPosition;
var childPosition = localPositionGrid + anchoredPositionChild + deltaGridFromCenterToLeftTop;
return childPosition;
}
public void UpdateGrid(LayoutGroup gridLayoutGroup)
{
gridLayoutGroup.CalculateLayoutInputHorizontal();
gridLayoutGroup.CalculateLayoutInputVertical();
gridLayoutGroup.SetLayoutHorizontal();
gridLayoutGroup.SetLayoutVertical();
}