Hi everyone.
I have this UI object in world space. It’s essentially a description of a collectible object that will hover over it when the player is looking at it. Similar to this:
The problem is, I can’t get it to face the camera. I have both an aim constraint and tell it to LookAt the camera, but it still doesn’t. Here’s my script:
[SerializeField] private AudioClip collectionSound; // sound player when collected
[SerializeField] private int maxInventoryStack; // max amount this item can stack
[SerializeField] private int addToInventory; // how much to add to the slot
[SerializeField] private string item; // the item to add
private List<int> qtys = new List<int>(); // list containing the quantities of the slots containing this item
private List<int> indexes = new List<int>(); // slots containing this item
private AudioSource collect; // AudioSource reference
private Look player; // player script reference
private int slot; // the slot to add to
public bool isInteractible = false;
private ConstraintSource constraint;
[SerializeField] private GameObject label;
void Start()
{
player = GameObject.Find("Player").GetComponent<Look>();
collect = GetComponent<AudioSource>();
constraint.sourceTransform = transform.Find("Player/Camera");
label.GetComponent<AimConstraint>().AddSource(constraint);
}//Start
private void Update()
{
label.SetActive(isInteractible);
label.transform.LookAt(transform.Find("Player/Camera"));
}//Update
Also, as a side note, Kurt-Dekker told me never to use GameObject.Find, so how could I replace it in this script? I can’t use a serializable dropbox as collectible items can spawn at runtime.
using UnityEngine;
public class UIFacesPlayer : MonoBehaviour
{
private Camera mainCamera;
void Start()
{
mainCamera = Camera.main;
}
void LateUpdate()
{
transform.LookAt(transform.position + mainCamera.transform.rotation * Vector3.forward, mainCamera.transform.rotation * Vector3.up);
}
}
This code works well, also, it’s not bad to use GameObject.Find
as long as you do it outside of loops, but if you still want to replace it, you can use GameObject.FindWithTag
Is FindWithTag less demanding than Find?
Begin all performance-related questions with the profiler:
Window → Analysis → Profiler.
Anything else is likely just hearsay.
Keep in mind that using GetComponent() and its kin (in Children, in Parent, plural, etc) to try and tease out Components at runtime is definitely deep into super-duper-uber-crazy-Ninja advanced stuff.
Here’s the bare minimum of stuff you absolutely MUST keep track of if you insist on using these crazy Ninja methods:
- what you’re looking for:
→ one particular thing?
→ many things?
- where it might be located (what GameObject?)
- where the Get/Find command will look:
→ on one GameObject? Which one? Do you have a reference to it?
→ on every GameObject?
→ on a subset of GameObjects?
- what criteria must be met for something to be found (enabled, named, etc.)
- if your code expects one and later you have many, does it handle it?
If you are missing knowledge about even ONE of the things above, your call is likely to FAIL.
This sort of coding is to be avoided at all costs unless you know exactly what you are doing.
Botched attempts at using Get- and Find- are responsible for more crashes than useful code, IMNSHO.
If you run into an issue with any of these calls, start with the documentation to understand why.
There is a clear set of extremely-well-defined conditions required for each of these calls to work, as well as definitions of what will and will not be returned.
In the case of collections of Components, the order will NEVER be guaranteed, even if you happen to notice it is always in a particular order on your machine.
It is ALWAYS better to go The Unity Way™ and make dedicated public fields and drag in the references you want.