简体   繁体   中英

Find position of left side of object

So i want to align 2 objects together on the left side of the object that is the furthest to the left. So i'll sketch out a scenario:

There are 2 images on random positions on the board. You select both images(with a selection tool that has been made) and you than click: "Align objects to the left" The image that is the furthest to the RIGHT should than snap to the same position of the edge on the left side of the other image. So when clicking the button, my code should calculate both left sides(the edge of the image on the left) of the images position, than check which one if the furthest to the right on the canvas, and move that one to the same X axis as the other image.

This way the end result will be the images will be on the exact same X axis. So if image 1 is on -73 & Image 2 is on -50, image 2 should than also move to -73, regardless of the rotation of either images.

Currently i can only find out how to find the middle position of the image, my code looks like this 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);
                }
            }
        }
    }
}

Note: I have no moving function yet as im first trying to figure out what the position of the most left side of the image is. The first Debug.log works and displays the normal position(middle point of image). The second one doesn't work, and displays the same. Both images get instantiated during runtime.

Hopefully this is enough information, i'm a long time lurker but have never posted anything myself, so be gentle on me if i forgot to add information.

From your question left means a smaller X value.

So in general the left edge of an image (assuming PageObjectBase somehow inherits from MonoBehaviour and you are speaking about Image component from Unity UI with a RectTransform ) is the most left of all four corners of the image. You can get all four corners by using 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;  
}

This should also work if the images are rotated.

If you are not using RectTransform you have to get the width another way somehow but the rest stays the same.

Than in your loop you first have to get the smallest (most left) edge so I would split it in two loops:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM