unity 的Cinemachine组件运用

unity 的Cinemachine组件运用1.第三人称视角控制通过PackageManager安装CineMachine1) 最简单的方法使用freeLook虚拟相机常用的调整为:1.观察目标:将要看的目标放在这里。2输入控制:把你想用来控制的虚拟轴(就是InputManager里的)的名字输入进去就行。默认是填mouse那个输入轴。注意:似乎不支持NewInputSystem。所以在用NewInputSystem时要么用在projectSetting/player里改成both设置。要么自己写脚本去调用这个组件中的

大家好,又见面了,我是你们的朋友全栈君。

1.第三人称视角控制

通过Package Manager 安装CineMachine
1) 最简单的方法使用freeLook虚拟相机

常用的调整为:
1.观察目标:
在这里插入图片描述

将要看的目标放在这里。
2输入控制:
在这里插入图片描述
把你想用来控制的虚拟轴(就是InputManager里的)的名字输入进去就行。默认是填mouse那个输入轴。
注意:似乎不支持New InputSystem。所以在用New InputSystem时要么用在projectSetting/player里改成both设置。
在这里插入图片描述
要么自己写脚本去调用这个组件中的Input Axis Value值

//第三人称相机
public CinemachineFreeLook thridPersonVCam;
…
thridPersonVCam.m_XAxis.m_InputAxisValue = mov.x; //x轴旋转
thridPersonVCam.m_YAxis.m_InputAxisValue = mov.y; //y轴旋转

2) 是我在一个项目中实现的方法:
参考了unity官方视频:https://www.bilibili.com/video/BV1Xa4y1j7iP
就是先让虚拟摄像机看向角色身上的子物体,玩家通过控制子物体的旋转来控制虚拟摄像机的朝向。但是要解决一个问题,就是子物体会随着父物体一起旋转的问题。视频中的解决方法是在移动或射击时强制将角色转向视角方向,同时将视点子物体的yz轴local的旋转值置零。
但是我是想实现个能在移动是也能自由观察的相机,所以采用了一个更简单但可能更耗性能的方法,就是在脚本内部另外保存一个实际子物体应该的世界坐标下的旋转值。在每次的lateUpdate里将子物体的世界坐标的旋转值强制改为这个脚本中的值。实现效果如下:
在这里插入图片描述
实现的主要脚本如下:

public class ViewController : MonoBehaviour
{ 

[Tooltip("相机左右旋转速度")] public float rotSpeedLR = 100f;
//用来给调整灵敏度的UI进行最大最小值的限制
[Tooltip("相机左右旋转最大速度")] public float maxRotSpeedLR = 360f;
[Tooltip("相机左右旋转最小速度")] public float minRotSpeedLR = 90f;
[Tooltip("左右是否反向")] public bool LRInvert;
[Tooltip("相机上下旋转速度")] public float rotSpeedUD = 50f;
//用来给调整灵敏度的UI进行最大最小值的限制
[Tooltip("相机上下旋转最大速度")] public float maxRotSpeedUD = 360f;
[Tooltip("相机上下旋转最小速度")] public float minRotSpeedUD = 90f;
[Tooltip("上下是否反向")] public bool UDInvert = true;
[Tooltip("相机向上限值")] public float upRange = 40f;
[Tooltip("相机向下限值")] public float downRange = -15f;
//视点子物体
public Transform viewPoint;
//实际playerViewPoint的旋转
[SerializeField]private Vector3 playerViewPointRotation;
private void Start()
{ 

//开始时将视角转向同角色方向
playerViewPointRotation = transform.eulerAngles;
}
void LateUpdate()
{ 

TrdViewControl();
}
/// <summary>
/// 第三人称视角控制
/// </summary>
void TrdViewControl()
{ 

//计算实际旋转分量
var rotVector = new Vector3((UDInvert ? 1 : -1) * rotSpeedUD, (LRInvert ? 1 : -1) * rotSpeedLR, 0);
Vector3 rotation = rotVector * viewInput * Time.deltaTime;
playerViewPointRotation += rotation;
var angleX = playerViewPointRotation.x;
//clamp限制垂直方向的角度
if (angleX > upRange)
{ 

angleX = upRange;
}
if (angleX < downRange)
{ 

angleX = downRange;
}
playerViewPointRotation.x = angleX;
//会在lateUpdate里实时地改变视点的方向来改变视角
viewPoint.eulerAngles = playerViewPointRotation;
}
//視角改变量
private Vector2 viewInput;
/// <summary>
/// 视角输入的控制函数
/// </summary>
/// <param name="context"></param>
public void OnViewControl(InputAction.CallbackContext context)
{ 

var tempInput = context.ReadValue<Vector2>();
viewInput = new Vector2(tempInput.y, tempInput.x).normalized;
}
}

与freelook虚拟相机相比:实现上麻烦了许多,但相应的修改自由度就比较高,可以应用于其他的跟随和朝向的算法。

2.锁定相机

是想做一个类似塞尔达旷野之息锁定视角。
在这里插入图片描述

首先想到cinemachine的Target Group Camera。
但是用了下感觉偏向于固定方向的多目标锁定,不能让玩家自己旋转视角(估计也可以实现,但没什么好的想法)。
关于Target Group Camera设置可以参考以下博客:
https://www.pianshen.com/article/63141639747/
锁定的相机似乎是绕着角色和目标做一个椭圆的轨道旋转。
于是用MixingCamera,将主角的相机和一个绕着目标的相机融合,形成一个偏椭圆的轨道。
效果如下:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
黄色为最终混合的相机轨迹,蓝色为目标相机的轨道,可见有两个点要实现:

  1. 目标相机的轨道大小要随着角色和玩家的距离改变,targetOffset = playerOffset + dis
  2. 目标相机的视角角度要同角色相机。
    实现的步骤如下:
    1.创建mixingCamera相机
    2.删除默认子相机,保留一个Orbital transposer跟随算法的子相机作为目标相机。
    注意:由于目标相机用的是Orbital transposer跟随算法,默认打开Recenter to target Heading。
    在这里插入图片描述

我们要关掉它,否则目标相机会一直想回正,导致相机抖动。
3. 为mixingCamera添加一个脚本代码如下:

using Cinemachine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LockVcamController : MonoBehaviour
{ 

private Transform target;
private CinemachineMixingCamera lockVcam;
//当前相机的组件
private CinemachineVirtualCamera currentVcam;
private CinemachineTransposer currentVcamTrans;
//角色身上视点
private Transform viewPoint;
//目标相机的组件
private CinemachineVirtualCamera targetVcam;
private CinemachineOrbitalTransposer lockTargetObi;
//判断是否锁定
private bool _isLock;
private void Awake()
{ 

//获取当前混合相机控件
lockVcam = GetComponent<CinemachineMixingCamera>();
//克隆一个当前的玩家虚拟相机,并放在混合相机下
currentVcam = Instantiate(GameObject.Find("PlayerVcam"), transform).GetComponent<CinemachineVirtualCamera>();
currentVcamTrans = currentVcam.GetCinemachineComponent<CinemachineTransposer>();
//获取viewPoint
viewPoint = currentVcam.Follow;
//获取锁定目标的圆形轨道相机组件
targetVcam = lockVcam.ChildCameras[0] as CinemachineVirtualCamera;
lockTargetObi = targetVcam.GetCinemachineComponent<CinemachineOrbitalTransposer>();
}
/// <summary>
/// 开始锁定并设定锁定目标
/// </summary>
/// <param name="target">锁定目标</param>
/// <returns></returns>
public bool SetLock(Transform target,int priority)
{ 

this.target = target;
if (this.target == null)//如果没目标就返回失败
return false;
//将目标相机的跟随和朝向设为指定目标
targetVcam.Follow = target;
targetVcam.LookAt = target;
lockVcam.Priority = priority + 1;
_isLock = true;
return true;
}
/// <summary>
/// 解锁
/// </summary>
public void Unlock()
{ 

lockVcam.Priority = lockVcam.Priority - 2;
_isLock = false;
}
private void LateUpdate()
{ 

if (_isLock)
{ 

if (target == null)
Unlock();
else
SetObi();
}
}
/// <summary>
/// 设置目标相机的轨道
/// </summary>
private void SetObi()
{ 

var tempPos = viewPoint.position;
tempPos.y = target.position.y;
var dis = Vector3.Distance(tempPos, target.position) + Mathf.Abs(currentVcamTrans.m_FollowOffset.z);
lockTargetObi.m_FollowOffset.z = -dis;//都是从后向前看与玩家设置保持一致
lockTargetObi.m_XAxis.Value = viewPoint.eulerAngles.y;//将target相机的方向同视点方向
//如果是用freeLook相机,就要去获取freelook中组件也有个m_XAxis,lockTargetObi.m_XAxis = TPVcam.m_XAis;
}
}

之后只要去调用脚本中的SetLock()方法,把目标和优先级传进去就可以了。

3. cinemachine的分屏

主要是翻译了cinemachine官方文档。
https://docs.unity3d.com/Packages/com.unity.cinemachine@2.6/manual/CinemachineMultipleCameras.html
分为4步:
1) 首先添加player层。有几个player就要分几个层。
在这里插入图片描述
2) 添加对应个数的unityCamera(不是虚拟相机),并添加各自的cinemachineBrain组件
3) 设置每个unityCamera的cullingMask,把除了本相机对应的层的其它之前添加的层取消。例如:P1Cam的话就把P2层取消。
4) 添加各个分屏对应的虚拟相机,虚拟相机要设置到相应的层里。
5) 修改各个unityCamera里的viewportRect,确定要在屏幕里显示的范围形成分屏效果。
最后效果如下:
在这里插入图片描述

其他使用上的注意:

  1. 注意cinemachine的调用顺序:
    想我这样在脚本中有视角控制相关的脚本,如果出现相机抖动,主要是相同的update系列的函数cinemachine里的先调用。可以在projectSetting里设定同级的系统函数在不同脚本时的调用顺序。
    在这里插入图片描述

  2. 其实跟Cinemachine没什么关系,人物用刚体移动时,刚体要用插值(interpolate)否则会造成相机抖动。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145048.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 600万行代码项目(几万行查代码)

    作者:小傅哥博客:https://bugstack.cn沉淀、分享、成长,让自己和他人都能有所收获!????一、前言20万行代码写完,毕业了找一份工作不是问题!刚一毕业因为找不到工作,就得报名去参加Java培训的大有人在。并不是说参加培训就不好,只不过以你现在这个毕业的时间点参加,就会显得特别匆忙。因为你的压力既来自于培训还需要花家里一笔不小的费用,也有同班同学已经找到一份不错的工作开始赚钱的比对。大学四年其实有足够的时间让你学会编程,也能从一个较长时间的学习中,知道自己适合不适合做程序员。

  • 教你看懂System.out::println

    教你看懂System.out::println在不经意间,我们会看到这样的代码//创建出一个数组List&lt;String&gt;strList=Arrays.asList("YangHang","AnXiaoHei","LiuPengFei");strList.forEach(System.out::println);第一印象,哇,好高大上的写法,那么这究竟是…

  • Maven环境配置及介绍[通俗易懂]

    Maven环境配置及介绍[通俗易懂]Maven环境配置及介绍Maven的出现是为了解决jar包管理的问题,可以通过简短的描述信息,进行项目管理的工具软件。1.maven的安装下载地址:http://maven.apache.org/downloa/d.cgi2.环境变量配置maven环境变量配置,配置方式跟jdk有些类似。新建环境变量MAVEN_HOME(值为maven的根目录)、然后在PATH环境变量里加入%MAVEN_HOME%\bin;即可。使用快捷键win+R,在黑窗口输入mvn–v进行查看,显示如下就表

  • labelImg闪退【解决方案】

    labelImg闪退【解决方案】转载请注明出处解决方案删除C:\Users\YourAccount\..labelImgSettings.pkl,重新打开labelImg,问题解决。【完】

  • CSS 换行_css不允许换行

    CSS 换行_css不允许换行1、强制换行word-break:break-all;/*只对英文起作用,以字母作为换行依据。如果该行末端有个很长的英文单词,它会把单词截断,一部分保持在行尾,另一部分换到下一行。*/word-wrap:break-word;/*只对英文起作用,以单词作为换行依据。如果该行末端宽度不够显示整个单词,它会自动把整个单词放到下一行,而不会把单词截断掉。*/white-space:pre-wrap;/*只对中文起作用,强制换行。*/2、禁止换行(单行文本截断)white-spac

    2022年10月25日
  • iocomp入门教程-以MFC中iplotx为例

    iocomp入门教程-以MFC中iplotx为例最近要做一个项目需要绘制曲线,为了节省时间,就选用了iocomp控件,可网上相关的教程极少,官方给的文档还是比较详尽,但缺少具体的前期准备步骤,在初次接触这个控件很容易蒙,所以我写下这篇,给入门者以便利。用到的材料:              iocomp激活成功教程版(目前常见的为V3和V4,两个版本按喜好选择吧~            

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号