- Home /
how I can create an sprite that always look at the camera?
how I can create an object that always look at the camera?
Like this tree:
Thanks in advance!
Answer by DaveA · Mar 16, 2011 at 08:47 PM
using UnityEngine;
public class Billboard : MonoBehaviour { void Update() { transform.LookAt(Camera.main.transform.position, -Vector3.up); } }
Call it Billboard.cs and drop it on any object you want to be a billboard and/or make a prefab.
No prob. Note: you may need to not negate Vector3.up depending on your mesh. I used a simple quad I made in Blender that might have been backward. So if you don't see anything, it's probably facing the wrong direction, so take that - sign out.
I think I'm having this problem but removing the $$anonymous$$us sign didn't fix the issue.
Any other suggestions?
Note: I'm using a Sprite Renderer just in case that makes a difference.
Yup, I needed to do that. $$anonymous$$ost likely for others too, just remove the negation on the Vector3.up
Shouldn't that be put in LateUpdate? Otherwise your billboard might flicker slightly depending on if and how you move it.
Try this for those wanting the billboards to stay 'upright' on the y axis.
public class CameraBillboard : $$anonymous$$onoBehaviour
{
private void LateUpdate()
{
transform.forward = new Vector3(Camera.main.transform.forward.x, transform.forward.y, Camera.main.transform.forward.z);
}
}
Answer by JustinReinhart · Jul 08, 2016 at 02:21 PM
I spent some time researching the issue of billboard sprites. I personally believe that the correct course of action is not to just perform a Transform.LookAt, but to actually align all billboard sprites to point the same direction that the camera is pointing. If you simply have each sprite look at the camera, multiple billboards across your screen will create a curve around your camera and they jut into each other if they overlap; This is because each billboard sprite would exist in 3D space at slightly different angles. Worse still, objects on the edge of the screen get warped like a funhouse mirror. Therefor aligning seems to be the way to go.
MyTransform.forward = MyCameraTransform.forward;
I also agree with marsbear that there may be a benefit to putting the code in LateUpdate.
Pictures and reference code available here: http://www.justinreinhart.com/2016/07/08/pixel-perfect-billboard-sprites/
Or just:
myTransform.forward = -myCameraTransform.forward;
Great optimization tanoshimi! I'm actually using $$anonymous$$yTransform.forward = $$anonymous$$yCameraTransform.forward; now specifically because the negative value was flipping the sprites.
In general I'm not sure this is what you want to do. This makes the sprite face the same direction as the camera which isn't the same as towards the camera. If look around especially with the sprite as the edge of the view window, it will seems like it's rotating ins$$anonymous$$d of fixed towards the viewer.
There is a subtle issue with this approach. If the camera is close to the billboard but it's not pointing at it (but still in the field view), you would see the billboard is not 100% facing the camera. It's facing the camera like 80%. To make it 100% facing camera, use LookAt() method.
There are generally those two billboarding techniques used in games. $$anonymous$$ost billboards actually use this approach (for example Quake3 for any particles / sprites like explosions, smoke, plasma. Also Source engine HL2). This is usually the cheapest solution as only the camera direction is required. This is especially useful for shader billboarding solutions.
The second approach is actually let the object face the position of the camera. This is also used in Quake 3 for the rail gun beam (the rotation around the beam direction).
Both techniques have advantages and disadvantages.
Cam forward
pro: usually the fastest
pro: It's insensitive to player movement.
con: When you rotate the camera you will notice that the billboard object rotates with you which can look weird at certain angles. However when used for fast moving objects you usually can't notice it.
Cam lookAt
pro: It's insensitive to camera rotation. It's best used for distant objects where the player never gets too close.
con: It's sensitive to camera / player motion. This can look also quite weird when you closely run past a billboard object its rotation is quite noticable depending on the camera field of view.
Which technique is better depends on how long is the object visible and what kind of movement does happen more often, camera rotation or camera movement.
The point of a billboard is not to "make it face the camera", but to give the illusion of an actual object, even it is just a flat sprite. The cam forward vector method does not change the appearance when you just walk by such a billboard object. But it looks strange when you rotate the camera.
Well, DaveA's code didn't work for me but your code in the link worked out the box, which is exactly what I like to see as a total noob just trying to figure this stuff out. So thanks. :D
Edit: Ah, one issue: The sprite tilts backwards and forwards towards the ground if I get close to it and look up and down, so it kinda looks like it's trying to lie down. lol Is there I way I can stop it doing that?
@impurekind To get the object to stop laying down: First, the reason it is laying down is because it is copying the camera's rotation exactly. If the player looks down they are rotating the camera to look down. So the object will rotate to match. Theoretical solution: After the line of code that copies the 'transform.forward' of the camera to the object, in the next line of code you need to immediately set the object's rotation so that it is not tilted on an axis that allows it to lay down. Basically, between frames that the player can see, you would be setting the rotation a second time. First a copy. Then a slight adjustment so it is standing up. And then the next frame is drawn.
Alternatively, but still the same concept, it sounds like what you want is for the objects to only rotate around the Y axis (to turn left and right around a vertical pole, but never tilt forward or backwards.) You would want to replace my code with a line of code that only copies the Y rotation of the camera but does not attempt to copy or change the rotation on any other axis. I'll leave that up to you to figure out cause it should be a fairly simple exercise for a self-described beginner. (thumbs up) Have fun.
Well, thanks for the tip but the entire point is I cannot figure this out because I simply do not understand c# (or any of Unity's specific variations/uses of it). It is beyond confusing, convoluted and unintuitive to me (as is much of Unity). And it's counter-productive to take multiple hours to try and fix every single tiny issue that comes up when it could be more effectively solved in a few $$anonymous$$utes via some actual implementable suggestion from people who inevitably know better due to many more years of experience (with both Unity and C#).
I spent three hours on this one little issue last night, trying multiple different potential solutions I found online (ones provided to other people covering this general issue), as well as looking up Unity's documentation and watching various YouTube examples, and nothing I tried worked. Every single thing I tried myself just made the sprite appear to disappear entirely. And the whole point was in getting someone to provide me a solution to the issue now rather than wasting further hours/days on me trying to figure it out blindly for no good reason when the solution exists and other people in the community already know it.
I can't go wasting hours on every issue that could be solved in $$anonymous$$utes if someone who know's the solutions could help me resolve them properly there and then (which will usually be the case because they have far more experience and understanding of both Unity and C#), and if they could simply provide me with a simple working suggestion then I will then implement it, and, because it actually works, I can trust it's not just me faffing around in the dark co$$anonymous$$g up with bad methods to solve the issues and learn from it for next time.
Basically, whenever I try my own "solutions", they do not work--I simply do not understand enough to fix these issues myself, and it's dumb of me to spend years learning Unity and C#, stalling any current progress until then, to fix this (and every other of the $$anonymous$$ANY issues that come up daily) years down the line when it could be fixed right now--and you guys have the solution right now. All I'm asking is for someone to provide that solution, which I will then implement now and also learn better from it because I'm doing it correctly.
PS. It's strange to me how people say "have fun" with stuff like this--because coding is the least fun thing I can imagine. This is not fun for me--at all. I literally hate coding; but it's something that unfortunately needs to be done to get my game to even work.
$$anonymous$$aybe you can tell I'm not having fun here--and it would simply be nice to reduce the amount of frustration and stress as much as possible really.
Answer by idbrii · Apr 04, 2018 at 11:24 PM
If you want your billboard to stay upright so it doesn't tilt back to look up at the camera when it approaches, you need to modify DaveA's solution so your target position has no height changes:
public class Billboard : MonoBehaviour
{
void LateUpdate()
{
var target = Camera.main.transform.position;
target.y = transform.position.y;
transform.LookAt(target);
}
}
DaveA's solution works for me other than tiling back part, but as soon as I try any of your other guy's suggestions, including the various fixes for the sprite not being visible, I can't see the sprite at all.
Do you have any idea why this is and how to fix it?
Note: I'm using a Sprite Renderer if that's important here.
@impurekind: I'd guess because your sprites are backwards and you're seeing the backface. Try moving the scene camera around to the other side and see if you can see it from there.
Flipping the sprite is what DaveA's -Vector3.up was doing.
Simplified to 1 line of code, modification of Justin's code above.
public class CameraBillboard : $$anonymous$$onoBehaviour
{
private void LateUpdate()
{
transform.forward = new Vector3(Camera.main.transform.forward.x, transform.forward.y, Camera.main.transform.forward.z);
}
}
Answer by eppz · Sep 21, 2018 at 12:05 PM
Just use the quaternion rotation of the camera for orienting sprite.
As simple as:
sprite.transform.rotation = Camera.main.transform.rotation;
Answer by Meltdown · Mar 16, 2011 at 07:31 PM
The technique you are referring to is known as 'billboarding' On the Unity terrain editor you can create trees and set their billboarding settings.
Your answer
![](https://koobas.hobune.stream/wayback/20220613113225im_/https://answers.unity.com/themes/thub/images/avi.jpg)