diff --git a/02-Note/DAWA/AI/AIVirtualIdel动画方案.md b/02-Note/DAWA/AI/AIVirtualIdel动画方案.md index 7b20ffc..1cf8b1a 100644 --- a/02-Note/DAWA/AI/AIVirtualIdel动画方案.md +++ b/02-Note/DAWA/AI/AIVirtualIdel动画方案.md @@ -198,4 +198,15 @@ p=位置 q=旋转(四元数) s=MR 合成的比例 o=MR 合成的偏移 ## UE Remote Control https://docs.unrealengine.com/5.1/en-US/remote-control-for-unreal-engine/ -基于WebSocket \ No newline at end of file +基于WebSocket + +# VMC4UE的实现 +## AnimNode +实现: +- FAnimNode_ModifyVMC4UEBones +- FAnimNode_ModifyVMC4UEMorph + +![[AnimNode]] + +# VMC APP代码参考 +- https://github.com/digital-standard/ThreeDPoseTracker \ No newline at end of file diff --git a/03-UnrealEngine/Gameplay/Animation/AnimNode.md b/03-UnrealEngine/Gameplay/Animation/AnimNode.md new file mode 100644 index 0000000..f0281f4 --- /dev/null +++ b/03-UnrealEngine/Gameplay/Animation/AnimNode.md @@ -0,0 +1,57 @@ +--- +title: AnimNode +date: 2023-08-08 12:23:11 +excerpt: +tags: +rating: ⭐ +--- + +# 前言 +参考: +- https://zhuanlan.zhihu.com/p/611398524 + +## 动画逻辑节点(AnimNode) +AnimNode是动画节点的纯逻辑类,用于运行时执行。实际上是一个Struct。 + +### 更新(Update) +节点的Update用于根据Weight计算动画的各种权重。因为Weight会在下一阶段清空。如果按照Epic的编写习惯,我们应该在Update里面拿到所有外部数据并且预计算,保证Evaluate可以直接使用。 + +### 评估(Evaluate) +根据上一个节点的Pose,计算出输出到下个节点的Pose。这是动画节点最重要的部分。正常来说我们应该把骨骼计算部分都放在这里。 +注意Update和Evaluate都有可能运行在子线程上,除了读写AnimInstanceProxy外,操作其他东西都不是线程安全的,尽可能不要碰外部的UObject。 + +### 根节点(Root) +也叫Output Pose节点。根节点是最重要的节点。对于用户来说,他是所有动画逻辑的输出节点。但是对于蓝图来说,他是整个蓝图节点的开始。AnimInstance将从这里开始建立整个动画节点的树状联系。 +![](https://pic4.zhimg.com/80/v2-67104412823695737b0a0382b8e5992b_720w.webp) + +### 动画节点的属性 +AnimNode通过他们的属性从外部获取信息。尽可能通过属性拿到想要的数据,而不是在运行时一层层往上Cast然后获取。 +AnimNode里面的EditAnywhere的UProperty都会在动画蓝图里暴露出来。有几个特殊的Meta +- AlwaysAsPin +- NeverAsPin +- PinShownByDefault +- PinHiddenByDefault + +他们可以控制属性要不要作为pin暴露出去。 +变成Pin后可以直接从变量连接过去(图中的Translation),也可以直接绑定属性(图中的Alpha)。 +如果连接变量的话,要注意节点是否仍然保持着FastGraph(闪电图标)。 + +## 骨骼索引(BoneIndex) +BoneIndex有三种,我们一一解释。 + +### SkeletonBoneIndex +首先Skeleton的骨骼包含着所有Mesh的所有骨骼。每当新增骨骼,只要名字不重复,就可以插入到Skeleton里面。Skeleton主要保存着他们的父子关系,所以不同网格体之间的同名骨骼的父子关系一定要正确。 +在Skeleton里面,所有的骨骼都有一个唯一的Name和唯一的ParentIndex,然后保存在BoneTree里面。骨骼在这里面的Index,就属于SkeletonBoneIndex了。 +SkeletonBoneIndex主要用于查找父骨骼,当然很多地方已经直接帮你缓存下来了,实际应用中很少需要自己去Skeleton里面查找。 + +### MeshBoneIndex +MeshBoneIndex是当前的骨骼网格体用到的骨骼的Index。 +用于显示骨架网格体,所以输出的话是输出MeshBoneIndex。 + +### CompactPoseBoneIndex +当前Lod用到的骨骼的Index,在RequiredBone里面保存。 +通过`XXBone.Initialize(RequiredBones)` 进行初始化。 +我们在动画节点里面一般通过FBoneReference来操作骨骼。BoneRefrence会通过BoneName获得3个骨骼索引。如果传入的是BoneContainer,那`BoneIndex`保存的是MeshIndex,如果传入的是Skeleton的话,那`BoneIndex`保存的是SkeletonIndex。 +Epic网站上也有一篇文章作为参考[[1]](https://zhuanlan.zhihu.com/p/611398524#ref_1)。 + +#