Billboard with strange offset

Hi all, I’ve created a Canvas which is a direct child of my Character. That canvas has a X offset of 0.5 and the its scale is set to 0.1 for XYZ.

I’ve then created the most basic billboard script that could ever exist:

    private void LateUpdate() {
        if (MainCamera == null) {
            MainCamera = Camera.main;
        }

        transform.LookAt(transform.position + MainCamera.transform.forward);
    }

It works okay, however when I rotate the camera the canvas gets displaced. It looks like it’s rotating around the wrong pivot? Here’s a video

3npqav

And here’s a video of what I’m trying to achieve:

e0g961

How could I get it working like the second video? Thanks in advance!

I think your canvas center just isn’t really at the graphics center you’re pivoting around, but rather offset from the player’s center a bit.

EDIT: to prove it, disable this script and then just spin the thing you’re currently spinning in the inspector… does it swim around the same way?

EDIT2: maybe your player isn’t centered on their own pivot!

Do you think this is a canvas only issue or could it be from the camera rotation as well?

If it’s only from the canvas, how could I assert the problem is that one you mentioned?

The code is open-source, if you’d like to take a look:

The canvas transform values are as following

I could observe that if I change the Z to be something different than 0, let’s say 4, when I rotate the camera, the UI rotates around the player

See above first edit: spin it by hand, see if it swims around.

Okay, if I disable the script and rotate the Y by hand, it stays at the bottom of the players and only spins.

The player hierarchy is set up this way:

And inside Body we have the many layers of sprite renderer a character may have

Edit: video for clarity.
el3swp

Edit2: The character is a sprite renderer with some turnarounds images, we calculate the camera’s rotation and determines which direction it is facing and replace the image on the renderers, therefore the impression of a 3d object

Keep in mind there’s more than one way to skin a simple billboard.

  1. the way you’re doing (pure camera-look… this does tilt the billboard AWAY from you)

  2. the way you’re doing but flatten out the Y component of the camera.forward (pure Y rotation, no tilt back)

  3. make it actually look away from the camera, not just away from the camera’s facing. This would use the delta from camera position to billboard position, so billboards would array in a curved shape facing you

Probably other ways too…

Do you have any resources on these other billboard methods?

method 2 sort of explains itself, method 3 obviously uses the delta between object and camera, and I suppose you could also flatten that in the Y plane (or any plane really).

I’m not sure what else you mean besides just googling it for yourself. You know the principle behind “keep yourself faced at the camera,” but there’s just a lot of ways to interpret that, each one with visual implications and possibly even computational expense implications, although with only a few items the computation probably doesn’t matter.

EDIT: all of this obviously supposes you have the anchoring correct in the canvas itself. It could be just as simple as something spilling out the side of the canvas due to mis-anchoring or mis-pivoting. Just press Pause and wiggle stuff around in the scene, it is probably pretty simple to see where the offset might be coming from and reason if it is code or setup.

I am feeling kinda dumb at this moment, we’ve talked about this at the beginning of this thread and I simply ignored the fact the SpriteRenderer is actually offset by (0.5, 0.4, 0.5)… After I removed that offset from the renderer and removed the one from the Canvas it rotates in place…

I could workaround that offset by offsetting the map instead, I still have to compare against the official game to see if both characters are at the same place or not, but either way I shouldn’t be playing with the positioning of the renderers in that way, right?

Anyways, thank you for your time!