ue3d使用Unity制作飞行模拟器相机系统

使用Unity制作飞行模拟器相机系统

分类:
ue3d - 使用Unity制作飞行模拟器相机系统

在本文中3D天堂将向你提供一个如何在Unity中创建飞行模拟器相机系统的学习知识,首先我们需要创建一个摄像机。

创建摄像机

将在飞船驾驶舱中创建一个 pov 摄像机,并将其放置在想要的位置,Pov 摄像机需要是游戏对象的子对象,将其添加到驾驶舱内。

ue3d - 使用Unity制作飞行模拟器相机系统

这个过程中,会在船后添加第三个人跟随相机。

ue3d - 使用Unity制作飞行模拟器相机系统

缓存摄像机

这里需要在虚拟相机之间进行切换,因此创建此变量并缓存虚拟相机。

public class CameraManager : MonoBehaviour
{
    [serializeField]
    private CinemachineVirtualCamera[] _cameras;
    [serializeField]
    private int _currentCameraIndex;
    [serializeField]
    private bool _isCurrentCameraActive;

    [serializeField]
    private GameObject[]_shipviews;

    private CinemachineVirtualCamera _currentCamera;

    private void Awake()
{
        foreach (var _VirtualCamera in _cameras)
        {
           _currentCamera = _VirtualCamera.GetComponent<CinemachineVirtualCamera>();

        }
}

设置相机的优先级

游戏开始时,将要重置当前的相机索引和虚拟相机的优先级值,然后设置当前相机,然后再将 bool 变量设置为 true。

void Start()
{

    _currentCameraIndex = 0;
     
    SetPriorityDefault();
    SetCurrentCamera();
    _isCurrentCameraActive = true;
}

这是实现 SetPriorityDefault 的方法,这个方法的说明很少,没有检查当前的相机索引,因为想重置所有相机优先级值,然后将 bool 设置为 false。

注意:这里为什么要把这个 bool 设置为 false,因为要重置所有的摄像头,这意味着不再打算将之前的摄像头作为当前摄像头,看到输入逻辑你就会明白了。

public void SetPriorityDefault()
{
    Debug.Log("what is the problem");
        _currentCamera.Priority = 10;
        _currentCamera.Priority = 10;
    _isCurrentCameraActive = false;
}

在 SetCurrentCamera 中,需要确保为特定相机分配优先级值,设置相机优先级值后,需将 bool 设置为 true 以确保调用此方法一次以节省性能成本。

public void SetCurrentCamera()
{
    switch (_currentCameraIndex)
    {
        case 0:
            _cameras[_currentCameraIndex].Priority =15;
            _isCurrentCameraActive = true;
            break;
        case 1:
            _cameras[_currentCameraIndex].Priority =15;
            _isCurrentCameraActive = true;
            Debug.Log("Third Person Camera");
            break;
    }
}

添加逻辑

现在将向更新添加逻辑,先要检查键代码是否被按下,然后检查 iscurrentcamera 是否为真,因此需要增加 currentCamera 索引,然后重置所有摄像机优先级,以确保即使有 5 个摄像机,在分配当前摄像机时也不会出现摄像机渲染冲突。

这里会有疑问吧?为什么会发生冲突?因此第一个虚拟摄像头将接管主摄像头,因此如果没有将它们全部重置并赋予当前摄像头最高优先级,那么如果当前摄像头不是列表中较高的,则当前摄像头将不会接管主摄像头与以前的相机相比的层次结构。

注意:现在正在检查当前相机索引是否超出相机数组长度,如果超出绑定,则将重置当前相机索引。

void Update()
{
    if (Input.GetKeyDown(KeyCode.R) &&_isCurrentCameraActive == true)
    {   
        _currentCameraIndex++;
        SetPriorityDefault();

        if (_currentCameraIndex >=_cameras.Length)
        {
           _currentCameraIndex = 0;
        }  
        SetCurrentCamera();
    }
}

这是在虚拟相机之间交换的结果。

ue3d - 使用Unity制作飞行模拟器相机系统

当在 pov 摄像机中时想禁用一件事,这艘船将在第三人称视角摄像机中禁用驾驶舱,所以添加了 ship and cockpit 和 on-ship views 数组变量。然后,当为特定的船舶部件设置当前相机时,需要启用其中之一。

ue3d - 使用Unity制作飞行模拟器相机系统
public void SetCurrentCamera()
{
    switch (_currentCameraIndex)
    {
        case 0:
            _shipViews[_currentCameraIndex].SetActive(true);
            _cameras[_currentCameraindex].Priority =15;
            _isCurrentCameraActive = true;
            break;
        case 1:
            _shipViews[_currentCameraIndex].SetActive(true);
            _cameras[_currentCameraIndex].Priority = 15;
            _isCurrentCameraActive = true;
            Debug.Log("Third Person Camera");
            break;
    }
}

这是用于启用和禁用船舶部分的代码,以避免网格在彼此之上闪烁。

然后想在按下 R 时禁用前一部分,如果 currentcameraActive 为真,在增量之前这样做是为了确保不会关闭当前的相机船视图部分。

void Update()
{
    if (Input.GetKeyDown(KeyCode.R)&& _isCurrentCameraActive == true)
    {
        _shipviews[_currentCameraIndex].SetActive(false);
        _currentCameraIndex++;
        SetPriorityDefault();
       
        if (_currentCameraIndex >= _cameras.Length)
        {
            _currentCameraIndex= 0;
        }
        SetcurrentCamera();
    }
}

例如下面的效果:

ue3d - 使用Unity制作飞行模拟器相机系统

如果不想向玩家展示已经禁用了整艘船,要解决这个问题,需要更改虚拟相机之间的主相机混合状态。

请选择主摄像机,然后选择 Inspector → Cinemachine Brain → Custom Blend List,在这里单击显示创建资产的按钮。然后点击加号按钮添加拥有的摄像机数量,然后选择过渡类型。

由于想要隐藏禁用飞船,因此解决方案是选择剪切混合。

ue3d - 使用Unity制作飞行模拟器相机系统

例如下面的效果:

ue3d - 使用Unity制作飞行模拟器相机系统

创建电影序列

3D天堂将创建五个不同类型的虚拟摄像机,然后将它们添加到时间轴中以制作序列。

ue3d - 使用Unity制作飞行模拟器相机系统

电影摄影机的逻辑

要检查玩家是否有 5 秒没有移动鼠标或者玩家是否有 5 秒没有按下任何按钮。

因此需要创建一个 vector3 变量来存储鼠标位置,然后将此变量分配给 Input to mouse position ins start 的方法,然后将创建 if 语句来检查时间过去了,如果玩家没有移动鼠标 5 秒,或者如果玩家在 5 秒内没有按下任何按钮。

注意:如果鼠标位置在同一个位置5秒表示玩家没有移动鼠标

ue3d - 使用Unity制作飞行模拟器相机系统
void Start()
{
    _currentCameraIndex = 0;
    SetPriorityDefault();
    SetCurrentCamera();
     isCurrentCameraActive = true;
    _temporaryMousePos = Input.mousePosition;
}
if (_temporaryMousePos == Input.mousePosition && Time.time >_canPlayCinematicCamera
|| !Input.anyKeyDown && Time.time > _canPlayCinematicCamera)

现在在上面的 if 条件之后要定义另一个 3 变量。

private float _canPlayCinematicCamera = 10.0f;
private float _timeRate = 10.of;
[SerializeField]
private PlayableDirector _cameracinematicDirector;

如果不想再次播放,只需进入 if condition 检查过场动画是否播放,然后添加时间以播放返回,如果希望它继续播放,需要返回。

在 else 语句中需要激活过场动画,然后播放和更新时间。

if (_cameracinematicDirector.state == PlayState.playing)
{
    _canPlayCinematicCamera = Time.time + _timeRate;
    return;
else
{
    _cameracinematicDirector.gameObject.SetActive(true);
    _cameracinematicDirector.Play();
    _canPlayCinematicCamera = Time.time + _timeRate;
    Debug.Log("Play Director: ");
}

想在玩家移动鼠标或按下任意键然后更新时间时禁用导演。

if (_temporaryMousePos != Input.mousePosition || Input.anyKeyDown)
{
    _cameracinematicDirector.gameObject.SetActive(false);
    _temporaryMousePos = Input.mousePosition;
    _canPlayCinematicCamera = Time.time + _timeRate;
}
//when player hasnot moved the mouse
//or pressed a key within 5 seconds
//have cinematic camera

当玩过场动画时,希望船处于全视野而不是显示驾驶舱,所以在这里将禁用第一个全船视图。

else
{
   _cameracinematicDirector.gameObject.SetActive(true);
   _shipViews[0].SetActive(true);
   _cameracinematicDirector.Play();
   _canPlayCinematicCamera = Time.time + _timeRate;
   Debug.Log("Play Director: ");
}

例如下面的最终效果:

ue3d - 使用Unity制作飞行模拟器相机系统

以上是3D天堂关于制作飞行模拟器相机系统的全部内容,如果你有任何反馈,请随时在本页面下方留言。

相关信息

  • 类型:知识
  • 字数: 1176
  • 字符:6219
  • 适用软件:Unity
  • 说明:无
  • 编号:150493

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!