UE4实现VRInteractableActor与镭射配件

VRInteractableActor


首先,继承ZomboyInteractableActor蓝图

Mesh


通常将Scene或者Mesh作为RootComponent

StaticMesh: Mesh: Primitive: SceneComp,为什么Mesh能有Physics和Collision的功能?

Mesh里提供了OverrideMaterials的配置(TArray),但它还不能直接拿来用,它只是各种Mesh组件的抽象基类。而StaticMeshComp里缓存了UStaticMesh的引用,因此它可以对其进行操作

InteractionComponent


配置触发交互的范围(ZomboyShapeComponent)

配置GripType:Follow(手跟随物)或Grab(物跟随手)

配置MaxConcurrent: 可以几只手交互

InteractionDetectionDistance

手离开交互范围,会自动结束Interaction

GeneralIndicator


Transfrom尽量不要修改,因为它会控制整体,可能会造成意想不到的效果

表示交互时手的位置,该位置应与控制器握持位置接近,且和触发交互的范围相近

配置手各个拇指的位置 HandPose

配置控制器位置 ControllerRelative(点控制器出现的圆球是整体的变换点,注意!控制器没有变换点)应放在你想让手柄放的位置

配置手的位置 HandRelative (手的控制点在手掌根部那个点) 应放在你想表现的预期位置

需要注意的是,这两个都是RelativeTransform,它会相对Indicator结点的Transform进行变化

配置左手还是右手交互 HandUsage

实现抓取移动


比如上下移动

原理:在OnPreGripUpdateEvent事件里 GetDesiredHandPoseTransformWorldSpace(控制器位置)- GetTargetHandPoseTransformWorldSpace(手部模型当前位置)= 控制器输入的偏移值

上下移动就是取Z分量的值,如果要限制一帧移动的范围,就再Clamp一下VectorSize。得到的向量作为Actor的LocalOffset
更进一步,由于只是ClampVectorSize无法限定交互物移动的范围,所以我们还要对交互物最终的Location进行一下Clamp:
SetHandPoseTransformWorldSpce设置手最终的位置,SetRelativePosition设置交互物自身的位置

怎么实现左手交互


从右手复制,设置HandUsage为Left,然后Visualization里面设置 MotionSourceIsRightHand False,这决定是预览左手还是右手动作。设置右手时,时常看一下左手的效果,这样才不会错

把交互物加到主角身上


用ChildActor或AttachActorToComponent

LaserAttachment


属性:Enable 开关功能

EventBeginPlay: SetTickEnabled False, SetTickGroup: PostPhysics

OnAttachmentInstallation: 开启Enable和SetTickEnabled,计算旋转,开启激光可视

OnAttachmentPulled: 上述操作的反向

EventTick: 由LaserBeam起始点到ValidInstance终点进行LineTraceByChannel检测,实时缩放LaserBeam和显隐LaserGlow

Tick


补充:
  • PrePhysics:默认。它使用的是上一帧的物理数据,通常用于实现Actor和物理对象的交互,随后计算物理模拟
  • DuringPhysics:和物理模拟同时。通常用于与物理无关的而又落后于PrePhysics逻辑的操作,如更新小地图
  • PostPhysics:在物理位置更新之后。常用于追踪(如激光瞄准器,它必须从枪的最终位置发出,即使出现一帧延迟也很明显),这时所有物理对象将位于它们的最终位置
  • n/a:处理隐藏操作、tick 世界时间管理器、更新摄像机、更新关卡流送体积域和流送操作。
  • PostUpdateWork 相机更新之后,通常用于依赖相机的特效。也可用于在帧中绝对最靠后运行的游戏逻辑
  • n/a:创建Defer Actor和渲染
  1. Tick初始是否Enable
  2. Tick时间间隔
  3. Paused时是否Tick
  4. DS上运行时是否Tick
  5. Tick Group

UE中SetLocation是立即执行的,没有同一帧中位移多次合并为一个的优化

Merge后手部抓取、镭射功能失效等奇奇怪怪的问题


可能是继承坏了,重新拉个蓝图实现试一下

CS_Character


全身IK和手部IK同时存在,HandOnly时是隐藏全身的模型

Anomotion BIK是一个全身IK插件。VR要做到全身IK还需要捕捉设备支持

如这里要实现InteractableActor的最终手部模型的Z轴是TargetPose的Z,而Y轴(手朝向的地方)是DesiredPose的Y,那么MakeRotFromZY(首先保Z不变,一定朝上),最后赋给SetPose(实现手抓滑动杆时手腕可旋转的效果)

例:ClimbPipe


它是用ClimbComponent实现PhysClimb的移动模式,交互上它FindTransformClosestToWorldLocation

例:Door


逻辑事件:OnPreGripUpdateEvent(前后推Interaction)→SetHandPoseTransformWorldSpace→SetWorldRotationOnPreGripUpdateEvent(DoorNob门把手)→GetDesiredHandPoseTransformWorldSpace→SetTargetLocation(Target是PhysicsHandle2)OnHandInteractionBegin/EndEvent→Add/Destroy PhysicsHandleComponent→Set DoorNobPhysicsHandle2→GrabComponent AtLocation(Door→Desired HandPose Transform Location)

comments powered by Disqus