Unreal Engine 4 —— 可交互绳索的构建
来源:互联网 发布:哪个品牌的网络电视好 编辑:程序博客网 时间:2024/04/27 20:45
在隐龙传:影踪中的钩爪玩法中,绳索是使用UE4中的Cable Component构建的。在当初还看了一下这方面的源代码和文档,可以在Unreal Engine 4的博客专栏搜到对应信息:传送门。
UE4的这个Cable Component是与世界场景没有交互的,因此这篇博客将讲解如何基于该Cable Component来实现绳索与世界的交互。
Verlet Integration
在查看UCableComponent
的源代码时,看到在Tick函数中有这么一段代码:
// Perform simulation substepsTimeRemainder += DeltaTime;while(TimeRemainder > UseSubstep){ PerformSubstep(UseSubstep, Gravity); TimeRemainder -= UseSubstep;}
而PerformSubstep
函数的实现如下:
void UCableComponent::PerformSubstep(float InSubstepTime, const FVector& Gravity){ VerletIntegrate(InSubstepTime, Gravity); SolveConstraints();}
看到VerletIntegrate
函数我就笑了,因为当初专门研究过它,对应的论文如下:传送门。
Cable Particle
在UE4的UCableComponent
中,使用Cable Particle来模拟绳索,使用Verlet Integration与松弛法进行绳索粒子的模拟,然后在对应的SceneProxy
中进行Mesh的构建。
UE4中的代码如下:
void UCableComponent::SolveConstraints(){ const float SegmentLength = CableLength/(float)NumSegments; // For each iteration.. for(int32 IterationIdx=0; IterationIdx<SolverIterations; IterationIdx++) { // For each segment.. for(int32 SegIdx=0; SegIdx<NumSegments; SegIdx++) { FCableParticle& ParticleA = Particles[SegIdx]; FCableParticle& ParticleB = Particles[SegIdx+1]; // Solve for this pair of particles SolveDistanceConstraint(ParticleA, ParticleB, SegmentLength); } }}
与球形物体的交互
该如何实现绳索与球形物体的交互?相对来讲还是比较简单,只需要在松弛法里面加上一个检测——如果有Cable Particle陷到对应的球形里面去了,那么直接将其推到球面上即可。
因此我们将SolveConstraints
函数改为:
void UCableComponent::SolveConstraints(){ const float SegmentLength = CableLength/(float)NumSegments; // For each iteration.. for(int32 IterationIdx=0; IterationIdx<SolverIterations; IterationIdx++) { SolveCollides(); // For each segment.. for(int32 SegIdx=0; SegIdx<NumSegments; SegIdx++) { FCableParticle& ParticleA = Particles[SegIdx]; FCableParticle& ParticleB = Particles[SegIdx+1]; // Solve for this pair of particles SolveDistanceConstraint(ParticleA, ParticleB, SegmentLength); } }}
只添加了一个SolveCollides
函数,用于约束Particle与物体的碰撞:
void UCableComponent::SolveCollides(){ for (int32 SegIdx = 0; SegIdx < NumSegments SegIdx++) { for (int SphereIdx = 0; SphereIdx < CollideSphere.Num(); SphereIdx++) { SolveSphereCollide(Particles[SegIdx + 1], CollideSphere[SphereIdx]); } }}void UCableComponent::SolveSphereCollide(FStripParticle& Particle, FComponentReference Comp){ auto Component = Comp.GetComponent(GetOwner()); if (IsValid(Component)) { if (Particle.bFree) { const float dist = FVector::Dist(Component->GetComponentLocation(), Particle.Position); auto sphere = Cast<USphereComponent>(Component); if (sphere && dist < (sphere->GetScaledSphereRadius())) { auto tmp1 = Particle.Position; auto tmp2 = sphere->GetComponentLocation(); auto tmp3 = sphere->GetScaledSphereRadius(); auto delta = tmp3 * ((tmp1 - tmp2).GetSafeNormal()); Particle.Position = Component->GetComponentLocation() + delta; } } }}
这样一来就可以实现绳索与球形的碰撞交互了。
与胶囊体的碰撞
绳索与胶囊体的碰撞约束也很简单,只要将对应的点推到胶囊体表面即可。这里不方便将代码放出,读者可以自己实现。
思考
UE4中的Cable Component使用的是Verlet Integration,而Mesh在SceneProxy里面进行构建。在这里实现了与球形&胶囊体的碰撞,这样一来就可以很方便地实现布料&发丝&水面的模拟啊……
- Unreal Engine 4 —— 可交互绳索的构建
- Unreal Engine 4 —— 多线程任务构建
- Unreal Engine 4 —— 多线程任务构建
- Unreal Engine 4 —— 多线程任务构建
- Unreal Engine 4 —— 版本兼容的工作原理以及一些可优化项
- Unreal Engine 4 —— 版本兼容的工作原理以及一些可优化项
- Unreal Engine 4 C++ AI 简单巡逻BehaviorTree的构建
- Unreal Engine 4 —— 冷却UI的制作
- Unreal Engine 4 —— 反射机制的实现
- Unreal Engine 4 —— 反射机制的实现
- Unreal Engine 4 —— UE4的内存模型杂七杂八
- Unreal Engine 4 —— 常见Tips
- Unreal Engine 4 —— 常见Tips
- Unreal Engine 4 HTC Vive UI交互流程
- Unreal Engine 4 创建Destructible Mesh(可破坏网格)
- Unreal Engine 4学习笔记:蓝图入门,构建蓝图类
- Unreal Engine 4 —— Physically Based Materials
- Unreal Engine 4 —— 禅意花园项目中的水池
- 利用Pybrain库进行神经网络函数拟合
- android数据库配置和操作
- struts2基本介绍以及环境配置
- POJ 网络流题集(转)
- hdu3527 SPY 水题
- Unreal Engine 4 —— 可交互绳索的构建
- POJ 2983Is the Information Reliable? (差分约束)
- 郭大侠与Rabi-Ribi(优先队列)
- 对象图 详解
- hdu1395 2^n mod n =1 简单数学题
- nyoj 84 阶乘的0
- js函数(类)的继承机制的设计与实现
- 数据库Sharding的基本思想和切分策略
- 纯属娱乐