I have two camera with "MainCamera" tag in a scene.
using this line of code
camera.main.transform.name
I am getting camera name but the problem is, it is only showing one camera name (which is fine) No matter what is depth or order of both main cameras in hierarchy.
How to get only second camera instead the one it is showing!
I only want to use camera.main property and nothing else option.
Camera is nothing but a GameObject with a Camera component attached. So it is very simple to get all instances of the camera:
var cameras = FindObjectsOfType(typeof(Camera));
foreach (Camera camera in cameras)
Debug.Log (camera.name);
In case you want to access the camera inside a rendering method (OnPreRender, OnPostRender, ...), you can access the camera currently rendering via Camera.current.
Other than that, there is no way to get a "second main" camera. Camera.main, will always return the first enabled main camera. You have to go with David's solution.
Related
I'm using Unity 2020.3.21f1, Universal Render Pipeline
Hi, I'm new to this, I'm adding a second camera to my scene through using 'Don't Destroy on load'
The Previous scene (Scene1) Has this:
void Start()
{
SceneManager.LoadSceneAsync(LoadingData.sceneToLoad);
//Static script called
}
And the menu and camera items in this scene have this attached:
void Start()
{
DontDestroyOnLoad(gameObject);
}
So when Scene2 loads, there will be a main camera, and Scene1's Camera. However, in the game mode, when I rollover the (Scene2) main camera's stack, it says it cannot detect an overlay camera, even though the Scene1's overlay camera is in the Scene2 Hierarchy?
When I manually copy over the Scene1 Overlay camera to Scene2, the stack can detect it, and everything works perfect. It is only when using don't destroy on load that it cannot detect a camera?
This might be unrelated, but I am trying to use:
public void CheckForCamera()
{
var cameraData = GetComponent<Camera>().GetUniversalAdditionalCameraData();
cameraData.cameraStack.Add(OverlayCamera);
}
To add the camera, but even with this, when I roll over the main camera stack, it says overlay camera cannot be detected, so I'm guessing I need to figure out why it can't be detected first before this script can be tested.
I have also made sure their tags are different. Scene1 Camera has the tag 'HUDCamera' and Scene2 Main Camera has the tag main camera
Scene1 Camera (HUD Menu Script contains just don't destroy on load):
Scene 1 Camera Inspector Details
Scene2 Camera (Camera Controller Script follows player around)
Scene2 Camera Inspector Details
I've been stuck on this for ages, someone please help!
I'm having trouble setting an image behind a gameobject in unity. I saw a lot of similar questions but none solved my problem. So basically I need to have the image as a child of the object to be able to do what I'm to do. I added an image of my unity view.
You can likely cheat this by using multiple cameras and layers. Set your container GameObject to its one layer (say "GameObjectLayer",) and set your image's GameObject to another layer (say "ImageUILayer".)
Then, create two cameras, and set the following properties:
Camera 1:
Depth = 0
Culling Mask = "GameObjectLayer"
Clear Flags & Background = (whatever you want the main camera background to be)
Camera 2:
Depth = 1
Culling Mask = "ImageUILayer"
Clear Flags = Depth only (this keeps the camera from drawing a background at all)
Each camera renders in turn, starting with the lowest depth and working up from there. Thus, Camera 1 renders everything in the "GameObjectLayer" first; then, Camera 2 renders everything in the "ImageUILayer" over top of that.
It's an extremely useful workaround when you're trying to mix 2D sprites with 3D objects, and it will never give you any flicker or other z-positioning weirdness, because the cameras each render all their layers in turn.
You can use more than two cameras if you need more than two layers of 3D/2D objects; I'm currently using a total of seven cameras with no ill effects.
in your case I suggest you use the(right click and choose)>2D > Sprites and put the sprites behind of the Gameobject
Ran into a U.I problem that I am struggling to solve (UI is always an issue for me). Gist of the project is that I have an array of spawn points (Positions[i]), an array composed of enemy prefabs(Enemies[j]) and just a UI panel prefab with a text component (EnemyHUD). When I pass string names through a certain function, as long as there is a prefab with the same name and position available to it, it will load in the enemy. Now, for every enemy prefab loaded in, I would like a "EnemyHUD" prefab to instantiate at at the enemy positions and with text displaying the name of the enemy.
GameObject HUD = Instantiate(EnemyHUB, Positions[i].position, Positions[i].rotation);
This line spawns the EnemyHUD prefab at the right location but its Instantiates them outside of the canvas so they show up as red x's. So I added this:
HUD.transform.SetParent(GameObject.Find("Canvas").transform, false);
This fixes the issue of Instantiating outside of the canvas but also (irritatingly)resets the Instantiate position and embarrassingly, I'm not sure how to set it back while making sure it stays a child of the Canvas. Have not event touched the name change part yet.
I have been working on this this since last night and while I got a lot of different results experimenting, none have been the one that I want. Very much still a novice, so I am sure it is looking me in the face so please help me find it.
First of all I would strongly recommend to avoid Find whenever possible! Rather already reference the according Canvas and store its reference. Especially the i lets assume you are doing this in a loop so using Find repeatedly is extremely inefficient!
// Drag you Canvas object into this field via the Inspector in Unity
[SerializeField] private Canvas _parentCanvas;
private void Awake()
{
// use this only as fallback an only ONCE
if(!_parentCanvas) _parentCanvas = GameObject.Find("Canvas");
if(!_parentCanvas) Debug.LogError("Could not get Canvas!", this);
}
Well and then the second parameter of Transform.SetParent is called
worldPositionStaysIf true, the parent-relative position, scale and rotation are modified such that the object keeps the same world space position, rotation and scale as before.
And
The default value of worldPositionStays argument is true.
Simply either leave it out like
HUD.transform.SetParent(_parentCanvas);
// this equals
//HUD.transform.SetParent(_parentCanvas, true);
or you could even do it in one single go already in Object.Instantiate which takes an additional parameter
parent Parent that will be assigned to the new object.
// This directly instantiates the new hud as child of _parentCanvas
// while still taking the position and rotation in absolute worldspace
GameObject HUD = Instantiate(EnemyHUB, Positions[i].position, Positions[i].rotation, _parentCanvas);
I spawn the prefab in a gameobject and that gameobject is a child of UI Image what I'm trying to accomplish is display the prefab infront of a UI Image. I've tried making z position of gameobject to negative but nothing happens. I can't place the sorting layer of UI Image cause it doesn't exist. What should I do? Is this even possible?
Update
Tried adding second camera. I made gameobject layer to SecondCam. Change settings of second camera to depth only and it's culling mask to SecondCam only then it's layer to SecondCam also. Change settings of main camera culling mask to everything except SecondCam. But this doesn't work, Have I done something wrong?
Second Camera settings
Main Camera settings
If your Gameobject is not one of the UI components you may need to give it another layer and render it with another camera with depth property higher than the UI camera.
You can change the sorting layer on prefabs or any object created on runtime.
If your UI canvas is set to screen overlay, then it with ALWAYS render on top. You have to use a screen space or world space UI, along with Dave's answer.
I have two cameras,
why I have two cameras?
because I want some game object in front of the Canvas so that it could move around, maybe could have some particles if it feels happy etc.. So:
I set up the main Camera with mask option UI and make it in charge of all the UI stuff, and to make sure it does not overlap everything I set the canvas mode "Screen-Space Camera"
I set up another camera and make it capture everything else except the UI stuff.
set their depth so that the main Camera with UI will behind the other Camera.
things go well now, I could see the game object before the UI stuff. Cheers!
But in some case I what to convert the UI element to the point in the world space, So that I could generate some gameObject near the UI element and maybe Tween it to move to another UI Element, let's take collecting Gems as an example.
Usually, I could just do that with following code:
GameObject go = Instantiate(eff_gem);
go.transform.position = Camera.main.ScreenToWorldPoint(p1.GetComponent<RectTransform>().position);
go.transform.DoMove(p2.GetComponent<RectTransform>().position, 1f).OnComplete(()=>{
Destory(go, 1f);
});
The main idea is to instantiate a gem near a button and make it fly to the count panel.
But since I make the canvas "Screen Space Camera" instead of "Screen Space Overlay", all the above code will be a mess. furthermore, I think I have to convert the screen point of the canvas element to the world space by the other camera, But I can't even get the actual pixel position of the canvas element by
p1.GetComponent<RectTransform>().position now.
So How Can I do that?
I have made a demo project to demonstrate the issue.
var p1R = p1.GetComponent<RectTransform>();
Vector3 p1WorldPos = p1R.TransformPoint(p1R.rect.center);
//use p1WorldPos in your other camera