问题描述
使用多个UI按钮尝试将主摄像机位置更改为不同的视图。我不想改变场景。我正在看一个物体,比如说一辆汽车,我想看到前照灯,我想单击一个按钮来移动主摄像机以看到前照灯,并有一个弹出窗口显示文本“ HeadLights”。然后,我想移至BrakeLights,单击“断灯”按钮,然后主摄像机移至“断灯”区域,并弹出另一个文本,显示“断灯”。每个汽车零件都有多个按钮,我很困惑,而且刚开始寻求帮助。
解决方法
如果我对您的理解正确,则有多个按钮,单击每个按钮会将主摄像机移动到与该按钮相对应的位置。您应该做的是:
-
创建一个脚本,该脚本存储要显示的文本以及相机的位置和旋转。将其附加到每个按钮的游戏对象上。
-
然后,在该脚本中创建一个函数来设置文本和相机的位置/旋转角度。该脚本应如下所示:
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;
}
}
-
返回Unity。在每个按钮的OnClick事件中,订阅(添加)刚创建的功能。 (确保从该按钮所附的脚本中添加功能)
-
将文本更改为所需的文字,然后在按此按钮时将cameraPos和cameraRot设置为希望相机切换到的位置。
这是我做完所有事情的视频:https://youtu.be/L621IcEBAtU
这肯定会起作用,但是每个点之间的过渡是即时的。如果要平稳过渡,可以使用电影机包或更改脚本。
,如果愿意,您可以为每个位置创建两个Vector3
,一个用于您希望照相机所处的位置,另一个用于您希望照相机对面。
public Vector3 cameraPos;
public Vector3 cameraLootAkPos;
public void ChangeCameraTransform()
{
Camera.main.transform.position = cameraPos;
Camera.main.transform.LookAt(cameraLootAkPos);
}
如果您想使用它,我做了自己的版本。上面的版本是一个即时过渡,下面包含的过渡在运行时更平稳。您可以考虑使用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;
}
}
,
作为练习,我试图编写一个简单的C#脚本来完成如上所述的操作。希望这对您自己有所帮助:
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;
}
为了给阵列分配新的“相机点”,请首先在Unity检查器中手动设置“大小”,然后将新的GameObjects /变换从场景“层次结构”窗口拖动到检查器中阵列的各个元素(例如,这些可以只是表示每个“摄影机位置”的摄影机位置的空游戏对象。然后将摄像机目标分配给数组中的每个元素,您希望主摄像机查看每个“摄像机点”(例如,车轮)。最后,为将在GUI按钮上显示的每个元素输入名称。
在此示例中,在“播放模式”中将仅显示一个GUI按钮,该按钮用于切换到阵列中的下一个“位置”。但是您可以轻松地修改脚本,以使相机直接切换到特定元素...
(不确定此网站是否真的是一个很好的问题,因为它是开放式的,因为有很多不同的方法可以为该功能提出可能的解决方案(涉及许多不同领域,例如相机运动控制器,路径插补,GUI等)。
编辑:多个GUI按钮
这是上面脚本的修改版本,它使用多个GUI按钮,每个摄像头一个。可以通过“显示GUI”复选框在检查器中启用/禁用每一个:
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,t);
cam.rotation = Quaternion.Slerp(cam.rotation,roti,t);
t += Time.deltaTime * animSpeed;
}
void OnGUI() {
Rect rect = new Rect(10,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;
}