Hey, I was wondering if there was a way to make 3D text always face the camera? I just wanted to display names above the heads of NPCs like you see in some online games, which I accomplished easily by simply attaching a 3D text game object to the NPC, but the problem is the 3D text always faces in one direction, and I wanted to make it always face the camera so it’s always readable, regardless of the angle you view it from.
transform.LookAt(Camera.main.transform)
Correct…plus make it a child object of the camera. So you dont have to do this every frame.
Thanks! That got the text to face the camera like I wanted, but unfortunately the text is now always facing backwards. Any way to fix that?
You need to write the text backwards.
Just kidding…could not resist.
I suggest you change the rotation of the text’s gameobject until it fits. Like:
text.gameobject.transform.localEulerAngles = new Vector3(180, 0, 0)
^Thanks, but that line gives me the following error:
Assets/scripts/face camera.js(5,9): BCE0005: Unknown identifier: ‘text’.
But if I remove the “text.gameobject” part of the line, the error goes away, but the text flips upside down instead of flipping horizontally. However, if I switch the numbers from (180, 0, 0) to (0, 180, 0), it flips correctly, but stops facing the camera. ![]()
I can’t remember how the text mesh is oriented in local space, but in any case, you can orient it however you need to by making the text mesh game object a child of the object that tracks the camera, and then assigning to localEulerAngles as you’re doing currently.
^Yeah, I was able to get it working by just making the 3D text a child of an empty game object, rotating the text 180 degrees within that empty game object, and then making the empty game object face the camera. So it’s actually working pretty well now. However, I think it could work better.
See, I’ve noticed that when I spin the camera around, the axis of the 3D text is sometimes skewed on an angle, and I’d like for it to always remain perfectly parallel with the sides of the screen. That is, I want the text to ignore the Z axis when facing the camera, and only rotate along the X and Y axis. Unfortunately, I have no idea how to accomplish this. Any help?
The problem with 3DText is that it gets smaller the farther away it is. If you look at most games, that’s not what happens: the text stays the same size always, so it’s readable. GUIText would be better: http://www.unifycommunity.com/wiki/index.php?title=ObjectLabel
–Eric
Wow, thanks! That works a lot better than the 3D text method!
But now I’m running into one tiny other issue with the GUI text that wasn’t happening before: if I turn around and face away from the NPC and walk far enough away, the NPC’s name comes around, sliding onto the screen in front of me, even though the NPC himself is still in his original location behind me. Any idea what’s causing this? Cuz’ I obviously can’t have the names flying off NPCs like that. It’d be very distracting when trying to play the game.
This might be necro posting but I figured it out.
if (transform.renderer.isVisible == false) {
transform.GetChild(0).active = false;
} else {
transform.GetChild(0).active = true;
}
Keep in mind that my GuiText element is a child of the NPC that I am having it follow.
ok, now 3d text always face camera, but 3d text flipped !!!
how can correct it ?
I got this solution elsewere, but to make your 3D text face the camera, user lookAt function as usual, passing the camera transform position and the magic here is to change the X scale of your 3D text to -1, so itself is already flipped.
transform.Rotate(Vector3.up - Vector3(0,180,0));
Hi for Text asset this will definitely work as you all wanted
public Camera m_Camera;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.LookAt(transform.position + m_Camera.transform.rotation * Vector3.forward,
m_Camera.transform.rotation * Vector3.up);
}
Thanks for the tip @Jesse_Anders and @anon_26140607 , making the 3D text a child of an empty GameObject and then rotating it by 180°, while making the GameObject face the camera worked.
Is there a way though to make a 3D text ignore the up/down movement of the camera and just turn around the y (z) axis?
Four ways to get your text to face the camera (pick one of 1-4, here 1-3 are commented out):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class ActorScript : MonoBehaviour
{
// Set these in the editor, or in code.
//transforms
public Transform bannerLookTarget;
public Transform bannerDolly;
//banner text component
public TMP_Text tmp_text_banner;
// Start is called before the first frame update
void Start()
{
bannerLookTarget = Camera.main.transform;
}
// Update is called once per frame
void Update()
{
//1
//here a canvas rotated 180 about Y is a child of an empty gameobject (here called bannerDolly), bannerDolly rotates to face camera.
//note: make sure parent gameobject has transform not rect transform
//bannerDolly.transform.LookAt(bannerLookTarget);
//2
//tmp_text_banner.transform.rotation = Quaternion.LookRotation(tmp_text_banner.transform.position - bannerLookTarget.position);
//3
//tmp_text_banner.transform.LookAt(2 * tmp_text_banner.transform.position - bannerLookTarget.position);
//4
//locks up/down (x) rotation/tilt by removing the height difference (y);
Vector3 lookDir = tmp_text_banner.transform.position - bannerLookTarget.position * 2;
lookDir.y = 0;
tmp_text_banner.transform.rotation = Quaternion.LookRotation(lookDir);
}
}
You can put the code into a method instead of update(); calling the method will instantly rotate the transform.
EDIT: I decided to see if I could do something a little less “hard coded” and this actually works perfectly too (use the Camera.main.transform.rotation for the Quaternion in the Instantiate call):
Transform plopDistanceTransform = Instantiate(gameManager.plopDistancePopup, spawnPosition, Camera.main.transform.rotation);
ORIGINAL POST: I was just having this problem in my 3D mobile game where when an object gets hit, I spawn a little “hit distance” popup that spawns at the collision point and then slowly disappears after a couple seconds (I followed this CodeMonkey video on YouTube, mostly:
).
The text was spawning jacked up using my default of Quaternion.identity (the tutorial was for a 2D game, too) so I then tried using Quaternion.LookRotation(Camera.main.transform) but that wasn’t quite right either, though it seemed close.
Finally, I paused my game and went into the Scene view and clicked on the Camera, and copied down the X/Y/Z values for its Rotation.
I then used those values in a Quaternion.Euler() call and that worked perfectly:
Quaternion facingCameraRotation = Quaternion.Euler(new Vector3(30.542f, 275.125f, 1.156f));
Transform plopDistanceTransform = Instantiate(gameManager.plopDistancePopup, spawnPosition, facingCameraRotation);
Side note that my Camera always faces the same direction (it follows a flying game object but stays looking in the same direction), so if yours changes direction/rotation, then this probably won’t work.
I approached the problem where the text appears inverted along the y axis like this:
score++;
GameObject point = Instantiate(PointPrefab, scorePosition + offset, Quaternion.identity);
Destroy(point, 2);
point.transform.LookAt(GameObject.FindGameObjectWithTag(“Player”).transform);
Quaternion q = point.transform.rotation;
point.transform.rotation = Quaternion.Euler(q.eulerAngles.x, q.eulerAngles.y + 180, q.eulerAngles.z);
point.GetComponent().text = score.ToString();