Using multiple UI buttons to try and change main cameras positions to different views. I don't want to change scene. I am looking at one object lets say a car, and I want to see the head lights, I want to click a button to move main camera to see head lights and have a pop up window showing text "HeadLights". Then I want to move to BrakeLights, I click the break lights button and the main camera then moves to the break light area and has another pop up text saying "break lights". There is multiple buttons for each car part, I am stuck and new to unity and looking for help.
-
1Try cinemachine package. If you look for lightweight option, there is a free asset called Fungus with simple camera position switching capabilities. – Aykut Karaca Aug 26 '20 at 21:25
-
I will check it out. I did import it but I will have to play with it to see whats going on. Thank you! – FuzzyShtzuTdyBear Aug 27 '20 at 13:37
3 Answers
If I'm understanding you correctly, you have multiple buttons, and clicking each will move your main camera to a spot corresponding to that button. What you should do is:
Create a script that stores the text you want to show, and the position and rotation of the camera. Attach it to each of the buttons' gameobjects.
Then, create a function in that script to set the text and camera position / rotation. The script should look something like this:
using UnityEngine;
using UnityEngine.UI;
public class CameraSwitch : MonoBehaviour
{
public Text UILabel;
public string text;
public Vector3 cameraPos;
public Vector3 cameraRot;
public void SwitchToHere()
{
Camera.main.transform.position = cameraPos;
Camera.main.transform.rotation = Quaternion.Euler(cameraRot);
UILabel.text = text;
}
}
Go back to Unity. In each of the button's OnClick events, subscribe (add) that function you just created. (Be sure to add the function from the script attached to that button)
Change the text to whatever you want, and set the cameraPos and cameraRot to where you want the camera to switch to when pressing this button.
Here is a video of me doing the whole thing: https://youtu.be/L621IcEBAtU
This will definitely work, but the transition between each spots is instant. If you want a smooth transition, you can either use the cinemachine pack or change the script.

- 349
- 4
- 13
-
Thank you for the help. I have tried this one and it works great. I am going to also try the others mentioned to see what else can be added or improved. I wasn't very specific with my question and thats my mistake but your answer did help. – FuzzyShtzuTdyBear Aug 27 '20 at 13:37
If you would like, for each position you could create two Vector3
's, one for the position you would like the camera to be in, and another you would like the camera to be facing.
public Vector3 cameraPos;
public Vector3 cameraLootAkPos;
public void ChangeCameraTransform()
{
Camera.main.transform.position = cameraPos;
Camera.main.transform.LookAt(cameraLootAkPos);
}
I did my own version of this if you would like to use it. The above version is an instant transition, the one included below transitions more smoothly at runtime. you can consider taking it further with things like Mathf.Lerp
public class ChangeCamera : MonoBehaviour
{
// You can populate each list with the appropriate positions. Making sure they are in order from 0 upward
public List<Vector3> CameraPositions;
public List<Vector3> CameraLookAtPositions;
public Vector3 LookAtTarget;
// to see which camera configuration we should use.
public int CamConfig;
float moveSpeed = .5f;
float rotSpeed = .5f;
public Transform MainCamera;
void Update()
{
if (MainCamera.position != CameraPositions[CamConfig])
{
MainCamera.position = Vector3.MoveTowards(MainCamera.position, CameraPositions[CamConfig], moveSpeed);
}
LookAtTarget = Vector3.MoveTowards(LookAtTarget, CameraLookAtPositions[CamConfig], rotSpeed);
MainCamera.LookAt(LookAtTarget);
}
public void ChangeCameraConfig(int ConfigNo)
{
CamConfig = ConfigNo;
}
}

- 61
- 4
-
I did try this and it helped. I appreciate it and will see if I can build on it more. Thanks again. – FuzzyShtzuTdyBear Aug 27 '20 at 13:38
-
Hi, I included an update of my own working implementation, perhaps it can help you achieve the smoother result you were looking for ;D – Christopher Aug 27 '20 at 14:13
As an exercise I've tried to write a simple C# script to do something like you've described above. I hope this helps as a starting point for your own:
using UnityEngine;
public class CamSwitcher : MonoBehaviour {
public CamSpotInfo[] spots;
[Range(0.1f, 3.0f)] public float anim_speed = 0.3f;
protected int idx = 0;
protected float t_accum = 0.0f;
void Update() {
Transform cam = Camera.main.transform;
cam.position = Vector3.Lerp(cam.position, spots[idx].transform.position, t_accum);
cam.LookAt(spots[idx].target); /* TODO: interpolate target positions */
t_accum += Time.deltaTime * anim_speed;
}
void OnGUI() {
if (GUI.Button(new Rect(10, 70, 200, 30), "next spot: " + spots[idx].name)) {
if (++idx >= spots.Length)
idx = 0;
t_accum = 0.0f;
}
}
}
[System.Serializable]
public class CamSpotInfo {
public Transform transform;
public Transform target;
public string name;
}
In order to assign new "camera spots" to the array, set the "Size" manually in the Unity inspector first and then drag new GameObjects/transforms from the scene Hierarchy window to the individual elements of the array in the Inspector (these can for example just be empty game objects indicating the camera position for each "camera spot"). Then assign camera targets to each element in the array, you want the main camera to look at at each "camera spot" (e.g. wheels). And finally, enter a name for each element that will be displayed on the GUI button.
In this example, there will be only one GUI button displayed in Play Mode, which is used to switch to the next "spot" in the array. But you can easily modify the script to make the camera switch to specific elements directly...
(Not sure if this is really a good question for this site, since it is quite open-ended, since there are so many different ways to come up with possible solutions for such a feature (many different areas involved, like camera motion controller, path interpolation, GUI etc.)).
EDIT: Multiple GUI Buttons
Here is a modified version of the script above, that uses multiple GUI buttons, one for each camera spot. Each one can be enabled/disabled in the inspector via the "Show GUI" checkbox:
using UnityEngine;
public class CamSwitcher : MonoBehaviour {
public CamSpotInfo[] spots;
[Range(0.1f, 3.0f)] public float animSpeed = 0.3f;
protected uint idx = 0;
protected float t = 0.0f;
void Update() {
Transform cam = Camera.main.transform;
Vector3 dir_target = spots[idx].target.position - cam.position;
Quaternion roti = Quaternion.LookRotation(dir_target);
cam.position = Vector3.Lerp(cam.position, spots[idx].transform.position, t);
cam.rotation = Quaternion.Slerp(cam.rotation, roti, t);
t += Time.deltaTime * animSpeed;
}
void OnGUI() {
Rect rect = new Rect(10, 70, 200, 30);
for (uint i=0; i<spots.Length; ++i) {
if (spots[i].showGUI) {
if (GUI.Button(rect, "switch to " + spots[i].name)) {
idx = i;
t = 0.0f;
}
rect.y += rect.height + 5;
}
}
}
}
[System.Serializable]
public class CamSpotInfo {
public Transform transform;
public Transform target;
public string name;
public bool showGUI = true;
}

- 764
- 5
- 18
-
Yeah that was my mistake on the vague question. I had something similar to the empty object that had the camera position I wanted originally and used an if, else if, else for the elements index but thinking on a larger scale I was trying to find other solutions. Basically the idea is, have a gameObject thats a prefab with many children (the individual parts that make up a vehicle). I thought maybe about using a scrolling side bar that has a prefab button and auto populates for each child. When button clicked, main camera swings over to see part and display information. thank you for the help. – FuzzyShtzuTdyBear Aug 27 '20 at 13:29
-
Hi! I've added a version with multiple buttons (but no scrolling nor any other advanced UI stuff). Hope that helps! - If your car object is a prefab, you can still drag the child objects to the array as a camera targets. - To auto-populate the "cam spot array", you could maybe use unity tags, to mark the important parts that should be added to the array with a(nother) script. Or instead, you could add special "marker scripts" to the important parts of the model, that also contain a title, a link to the corresponding camera transform etc. (see: Component.GetComponentsInChildren in the docs). – rel Aug 28 '20 at 00:04