I Dug Myself Into a Big Hole And Need Some Help, Please and Thank You

Ok, I am working on a project that is very complex (To me, I haven’t been doing game development for very long) in how I have it set up. And for the main menu I want the player to be able to push around the buttons, but because of how things were set up I cant seem to get it to work. and any help would be very appreciated because I have been working on this for five days now.

Here is what is going on. I have a camera projecting to a UI raw image at a lower resolution to get a cool pixelated look that makes things look like they are already partially animated without me having to to anything crazy. and in order to make the UI buttons interactable with the player object I needed to have a world canvas that they could be on but, if the button are on the world canvas I cannot click them, I have tried to make the UI canvas not interactable but that didn’t work. So I then separated the buttons form the player interactable boxes in the world canvas and put them into the UI canvas where they were now interactable to the mouse, but don’t move with the player interactable boxes. So I tried a parent constraint component that made them move when the player interactable boxes moved but in all the wrong ways that I cant even try to explain. So I finally tried to make a script that would do what it needs to do, move with the interactable boxes whilst also moving the proper distance (relative to the scaled raw image that the player sees). And I got it to almost work perfectly. It does everything it needs to except be consistent. now the buttons change where they are depending on the size of screen that the scene starts in. so for my 24’’ screen it is only slightly off set, but for my 15’’ laptop screen it is extremely off set.

24’’ screen

15’’ screen

Script I made


public class script: MonoBehaviour
{
    public GameObject parent;
    public GameObject child;
    public Vector3 origChildPos;
    public Vector3 origParentPos;
    public Vector2 refRes = new(608, 342);
    public float multiplier = 1.85f;

    void Start()
    {
        origChildPos = child.transform.position;
        origParentPos = parent.transform.position;

       //Debug.Log($"{Screen.width} x {Screen.height}");
    }

    void Update()
    {
        child.transform.eulerAngles = parent.transform.eulerAngles;

        child.transform.position = (parent.transform.position * 38) - (origParentPos * 38) + origChildPos;

        Vector3 cPos = child.transform.position;

        child.transform.position = new Vector3(cPos.x * (Screen.width / (refRes.x * multiplier)), cPos.y * (Screen.height / (refRes.y * multiplier)));

    }
}

Sorry that this is such a niche situation and I had to explain a lot, but all the help I can get would be great. Thank you in advance and if you still need more info I can try my best to explain.

I’m not going to be able to solve your exact issue but “you’re doing it wrong” is an important lesson to learn. If it were me I’d break the problem down into small parts. Get a part working and scale up again from there.

Real quick: don’t name your script, “script”. These are C# classes and that is a horrible name. It isn’t the cause of your issues but it will become one of them in time.

Don’t recalculate “everything” in the Update method. Is anything changing such that the positions need recalculating and reassigning?

I don’t exactly know what effect you’re looking for but if the grayish things are button and the words are supposed to be atop them consider designing “a button” that looks like you want with properties that can be changed, i.e. the text and position.

If you can’t click them and output “start clicked” to the console you should probably solve that before you work on the positioning.

Make reusable, working parts and then reuse them.

3 Likes

That sounds odd. Perhaps you have a fullscreen or other canvas overlaying the button’s canvas.

Moving UGUI elements with their RectTransform is not anywhere as simple and straightforward as other GameObjects. Keep in mind these UI elements are still adhering to canvas layouting, anchoring, and so on. This is very likely why your elements are offset depending on the screen size.

From the looks of it, you set them to absolute positions (relative to lower left corner) so that’s where they’ll be at regardless of the screen size. If you want UI elements to adjust to screen size, you must not set absolute positions.

I do know not to name a script ‘script’ but the name it was previously was just a dumb one that only I would have understood so I changed it before posting the discussion. I also feel as though I haven’t quite explained what is happening enough.

The text that I am trying to position on the gray boxes are the buttons. when they are in the world canvas where the boxes are and are children to the boxes they move as they should, but they are not interactable. when I moved them to the screen overlay canvas I can interact with the buttons but they don’t move with the gray boxes.

When I start the scene it looks like this and I can reposition it to align properly, but that is only for one sized monitor

,

But if I keep it to be aligned here for my 24’’ monitor then start the scene on my 15’’ monitor it does this

and the reason that I need to constantly be repositioning the text is because the boxes they are aligned to move around like this when the player hits them (they are on spring joints and can move left and right as well.)

I hope that clears some things up and I thank you for trying to help me with this. tell me if you are still confused on what the situation is and I will try to clear it up.

I got it to work, but it finnaly does what it should, thanks for trying to help. Here is the functional script.


public class LongDistanceParenting: MonoBehaviour
{
    [Header("Game Objects:")]
    public GameObject parent;
    public GameObject child;
    [Space(10)]

    [Header("Positions:")]
    public Vector3 origChildPos;
    public Vector3 origParentPos;
    [Space(10)]

    [Header("Sizing:")]
    public Vector2 refRes = new(608, 342);
    public float multiplier = 1.85f;
    

    void Start()
    {
        origChildPos = child.transform.position;
        origParentPos = parent.transform.position;

        Vector2 screenSize = new(Screen.width, Screen.height);
        multiplier = (screenSize.x / refRes.x);
    }

    void Update()
    {
        child.transform.eulerAngles = parent.transform.eulerAngles;
        child.transform.position = (parent.transform.position * 38) - (origParentPos * 38) + origChildPos;

        Vector3 cPos = child.transform.position;
        child.transform.position = new Vector3(cPos.x * (Screen.width / (refRes.x * multiplier)), cPos.y * (Screen.height / (refRes.y * multiplier)));
    }
}