所以我想在左边最远的物体左侧对齐2个物体。所以我将勾勒出一个场景:
板上随机位置有2个图像。您可以选择两个图像(使用已制作的选择工具)而不是单击:“将对象向左对齐”距离RIGHT最远的图像应该捕捉到左侧边缘的相同位置。另一个图像。因此,当单击按钮时,我的代码应该计算图像位置的左侧(左侧图像的边缘),而不是检查画布上最右侧的哪一个,并将该一个移动到相同的X.轴作为另一个图像。
这样最终结果将是图像将在完全相同的X轴上。因此,如果图像1在-73上并且图像2在-50上,则图像2应该也移动到-73,而不管任一图像的旋转。
目前我只能找到如何找到图像的中间位置,我的代码看起来像这个atm:
using com.company.program.core.pageObjects;
using com.company.program.ui.colorPicker;
using UnityEngine;
namespace com.company.program.core.SelectionManager
{
public static class SelectionAlignment
{
public static void AlignLeft(PageObjectBase pageObject)
{
Debug.Log("Let's check if this is a group first!");
if (pageObject is PageObjectGroup)
Debug.Log("Now we can AlignLeft!");
PageObjectGroup group = (PageObjectGroup)pageObject;
foreach (PageObjectBase objectBase in group.Children)
{
//objectBase.transform.position
Debug.Log("Position is now" + objectBase.transform.position);
Debug.Log("Left Position is" + objectBase.transform.position + -objectBase.transform.right);
}
}
}
}
}
注意:我还没有移动功能,因为我首先试图弄清楚图像最左侧的位置是什么。第一个Debug.log工作并显示正常位置(图像的中间点)。第二个不起作用,并显示相同。两个图像都在运行时进行实例化。
希望这是足够的信息,我是一个很长一段时间潜伏,但从来没有发布任何东西,所以如果我忘了添加信息,请对我温柔。
根据您的问题,left
表示较小的X值。
因此,一般来说,图像的左边缘(假设PageObjectBase
以某种方式继承自MonoBehaviour
,而你正在谈论来自Unity Image
的UI
成分与RectTransform
)是图像所有四个角中最左边的。你可以使用GetWorldCorners
获得所有四个角落
private float GetLeftEdge(PageObjectBase obj)
{
RectTransform rectTransformComponent = obj.gameObject.GetComponent<RectTransform>();
if(!rectTransformComponent)
{
Debug.LogError("No Image component found", this);
return 0;
}
Vector3[] v = new Vector3[4];
rectTransformComponent.GetWorldCorners(v);
float mostLeftCorner = float.MaxValue;
foreach(var pos in v)
{
mostLeftCorner = Mathf.Min(mostLeftCorner, pos.x);
}
return mostLeftCorner;
}
如果图像旋转,这也应该有效。
如果你不使用RectTransform
,你必须以某种方式获得宽度,但其余的保持不变。
在你的循环中,你首先必须得到最小的(最左边)边缘,所以我将它分成两个循环:
// Start with the max float value so any other value should be smaller
float mostLeftEdge = float.MaxValue;
PageObjectBase referenceToMostLeftObject;
// Get the most left position and object reference
foreach (PageObjectBase objectBase in group.Children)
{
float leftEdge = GetLeftEdge(objectBase);
if(leftEdge < mostLeftEdge)
{
referenceToMostLeftObject = objectBase;
mostLeftEdge = leftEdge;
}
}
// Now you have the most left edge value and the object which is your reference
// Just a little safety skip to not move to strange values
if(referenceToMostLeftObject == null || Mathf.Approximately(mostLeftEdge, float.MaxValue))
{
Debug.LogError("Ups, I think something went wrong getting the mostLeftEdge", this);
return;
}
// Move the other objects to match with that edge
foreach (PageObjectBase objectBase in group.Children)
{
// Skip the reference object
if(objectBase == referenceToMostLeftObject) continue;
// First get the difference
float leftEdge = GetLeftEdge(objectBase);
// Should always be negative
float difference = mostLeftEdge - leftEdge;
// Than move it there
var current = objectBase.transform.position;
// Since difference should be negative
// Adding it to the current position should result in the wanted position
var newPosition = new Vector3(current.x + difference, current.y, current.z);
objectBase.transform.position = newPosition;
}