【目标】

CCDIKRecoil

【思路】

1 CCDIK和Recoil的结合

2 Recoil的回弹机制,逐渐回到原来位置

3 添加一个Recoil基类

【步骤】

1 将\Src\GameFramework\Classes\GameSkelCtrl_Recoil.uc复制到\Src\Engine\Classes\SkelControlRecoilBase.uc

修改一下名称 作为基类

2 其他相关类继承于SkelControlRecoilBase, \Engine\Classes\SkelControlLimbRecoil.uc

make一下

编译不通过

原因是USkeletalControlRecoilBase是在后面声明的

方案:

采取将派生类放GameFrameWork工程中

编译后发现

这里有语法错误

最后还是没有用继承方式,脚本目前很难使用双基类

所以目前还是重复写相同代码

3 添加一个继承类GameSkelCtrl_CCD_IK_Recoil_CCD_IK_Recoil.uc,放到GameFramework中,否则又牵扯到那些结构体声明的先后顺序问题

4 在GameSkelControls.cpp 中添加实现宏,及函数实现

  1. IMPLEMENT_CLASS(UGameSkelCtrl_CCD_IK_Recoil);
 
  1. /*-----------------------------------------------------------------------------
  2. UGameSkelCtrl_CCD_IK_Recoil
  3. -----------------------------------------------------------------------------*/
  4. FVector2DUGameSkelCtrl_CCD_IK_Recoil::GetAim(USkeletalMeshComponent*InSkelComponent)
  5. {
  6. returnAim;
  7. }
  8. /** Is skeleton currently mirrored */
  9. UBOOL UGameSkelCtrl_CCD_IK_Recoil::IsMirrored(USkeletalMeshComponent*InSkelComponent)
  10. {
  11. return FALSE;
  12. }
  13. // USkelControlBase interface
  14. voidUGameSkelCtrl_CCD_IK_Recoil::TickSkelControl(FLOAT DeltaSeconds,USkeletalMeshComponent*SkelComp)
  15. {
  16. bApplyControl = FALSE;
  17. if(ControlStrength> ZERO_ANIMWEIGHT_THRESH )
  18. {
  19. // if willing to play recoil, reset its state
  20. if( bPlayRecoil != bOldPlayRecoil )
  21. {
  22. bPlayRecoil = bOldPlayRecoil;
  23. Recoil.TimeToGo=Recoil.TimeDuration;
  24. // ERS_Random == Start at random position along sine wave,
  25. // ERS_Zero == Start at 0
  26. const FLOAT TWO_PI =2.f*(FLOAT)PI;
  27. Recoil.RotSinOffset.X =Recoil.RotParams.X == ERS_Random ? appFrand()* TWO_PI :0.f;
  28. Recoil.RotSinOffset.Y =Recoil.RotParams.Y == ERS_Random ? appFrand()* TWO_PI :0.f;
  29. Recoil.RotSinOffset.Z =Recoil.RotParams.Z == ERS_Random ? appFrand()* TWO_PI :0.f;
  30. Recoil.LocSinOffset.X =Recoil.LocParams.X == ERS_Random ? appFrand()* TWO_PI :0.f;
  31. Recoil.LocSinOffset.Y =Recoil.LocParams.Y == ERS_Random ? appFrand()* TWO_PI :0.f;
  32. Recoil.LocSinOffset.Z =Recoil.LocParams.Z == ERS_Random ? appFrand()* TWO_PI :0.f;
  33. Recoil.RotOffset=FRotator(0,0,0);
  34. Recoil.LocOffset=FVector(0.f);
  35. }
  36. if(Recoil.TimeToGo>DeltaSeconds)
  37. {
  38. Recoil.TimeToGo-=DeltaSeconds;
  39. if(Recoil.TimeToGo>0.f)
  40. {
  41. bApplyControl = TRUE;
  42. // Smooth fade out
  43. const FLOAT TimePct=Clamp<FLOAT>(Recoil.TimeToGo/Recoil.TimeDuration,0.f,1.f);
  44. const FLOAT Alpha=TimePct*TimePct*(3.f-2.f*TimePct);
  45. const FLOAT AlphaTimesDelta=Alpha*DeltaSeconds;
  46. // Recoil Bone Rotation, compute sin wave value for each component
  47. if(!Recoil.RotAmplitude.IsZero())
  48. {
  49. if(Recoil.RotAmplitude.X !=0.f)
  50. {
  51. Recoil.RotSinOffset.X +=AlphaTimesDelta*Recoil.RotFrequency.X;
  52. Recoil.RotOffset.Pitch= appTrunc(Alpha*Recoil.RotAmplitude.X * appSin(Recoil.RotSinOffset.X));
  53. }
  54. if(Recoil.RotAmplitude.Y !=0.f)
  55. {
  56. Recoil.RotSinOffset.Y +=AlphaTimesDelta*Recoil.RotFrequency.Y;
  57. Recoil.RotOffset.Yaw= appTrunc(Alpha*Recoil.RotAmplitude.Y * appSin(Recoil.RotSinOffset.Y));
  58. }
  59. if(Recoil.RotAmplitude.Z !=0.f)
  60. {
  61. Recoil.RotSinOffset.Z +=AlphaTimesDelta*Recoil.RotFrequency.Z;
  62. Recoil.RotOffset.Roll= appTrunc(Alpha*Recoil.RotAmplitude.Z * appSin(Recoil.RotSinOffset.Z));
  63. }
  64. }
  65. // Recoil Bone Location, compute sin wave value for each component
  66. if(!Recoil.LocAmplitude.IsZero())
  67. {
  68. if(Recoil.LocAmplitude.X !=0.f)
  69. {
  70. Recoil.LocSinOffset.X +=AlphaTimesDelta*Recoil.LocFrequency.X;
  71. Recoil.LocOffset.X =Alpha*Recoil.LocAmplitude.X * appSin(Recoil.LocSinOffset.X);
  72. }
  73. if(Recoil.LocAmplitude.Y !=0.f)
  74. {
  75. Recoil.LocSinOffset.Y +=AlphaTimesDelta*Recoil.LocFrequency.Y;
  76. Recoil.LocOffset.Y =Alpha*Recoil.LocAmplitude.Y * appSin(Recoil.LocSinOffset.Y);
  77. }
  78. if(Recoil.LocAmplitude.Z !=0.f)
  79. {
  80. Recoil.LocSinOffset.Z +=AlphaTimesDelta*Recoil.LocFrequency.Z;
  81. Recoil.LocOffset.Z =Alpha*Recoil.LocAmplitude.Z * appSin(Recoil.LocSinOffset.Z);
  82. }
  83. }
  84. }
  85. }
  86. }
  87. Super::TickSkelControl(DeltaSeconds,SkelComp);
  88. }
  89. voidUGameSkelCtrl_CCD_IK_Recoil::GetAffectedBones(INT BoneIndex,USkeletalMeshComponent*SkelComp,TArray<INT>&OutBoneIndices)
  90. {
  91. check(OutBoneIndices.Num()==0);
  92. // Only process bone if there is something to do
  93. if( bApplyControl )
  94. Super::GetAffectedBones(BoneIndex,SkelComp,OutBoneIndices);
  95. }
  96. voidUGameSkelCtrl_CCD_IK_Recoil::CalculateNewBoneTransforms(INT BoneIndex,USkeletalMeshComponent*SkelComp,TArray<FBoneAtom>&OutBoneTransforms)
  97. {
  98. check(OutBoneTransforms.Num()==0);
  99. // Current bone transform matrix in component space
  100. FBoneAtomNewBoneTM=SkelComp->SpaceBases(BoneIndex);
  101. if(bBoneSpaceRecoil)
  102. {
  103. if(!Recoil.LocOffset.IsZero()||!Recoil.RotOffset.IsZero())
  104. {
  105. FBoneAtomRecoilTM(Recoil.RotOffset,Recoil.LocOffset);
  106. NewBoneTM=RecoilTM*NewBoneTM;
  107. OutBoneTransforms.AddItem(NewBoneTM);
  108. }
  109. return;
  110. }
  111. // Extract Aim
  112. Aim=GetAim(SkelComp);
  113. // Actor to Aim transform matrix
  114. constFRotatorAimRotOffset( appTrunc(Aim.Y*16384), appTrunc(Aim.X*16384),0);
  115. FBoneAtomActorToAim(AimRotOffset,FVector::ZeroVector);
  116. ActorToAim.RemoveScaling();
  117. ActorToAim.SetOrigin(FVector(0.f));
  118. constFBoneAtomAimToActor=ActorToAim.Inverse();
  119. // Component to Actor transform matrix
  120. FBoneAtomComponentToActor=SkelComp->CalcComponentToFrameMatrix(BoneIndex, BCS_ActorSpace, NAME_None);
  121. ComponentToActor.RemoveScaling();
  122. ComponentToActor.SetOrigin(FVector(0.f));
  123. constFBoneAtomActorToComponent=ComponentToActor.InverseSafe();
  124. // Add rotation offset in component space
  125. if(!Recoil.RotOffset.IsZero())
  126. {
  127. FRotatorRotOffset=Recoil.RotOffset;
  128. // Handle mirroring
  129. if(IsMirrored(SkelComp))
  130. {
  131. RotOffset.Yaw=-RotOffset.Yaw;
  132. }
  133. FBoneAtomNewRotTM=NewBoneTM*(ComponentToActor*(AimToActor*FBoneAtom(RotOffset,FVector::ZeroVector)*ActorToAim)*ActorToComponent);
  134. NewRotTM.SetOrigin(NewBoneTM.GetOrigin());
  135. NewBoneTM=NewRotTM;
  136. }
  137. // Add location offset in component space
  138. if(!Recoil.LocOffset.IsZero())
  139. {
  140. FVectorLocOffset=Recoil.LocOffset;
  141. // Handle mirroring
  142. if(IsMirrored(SkelComp))
  143. {
  144. LocOffset.Y =-LocOffset.Y;
  145. }
  146. constFVectorTransInWorld=ActorToAim.TransformNormal(LocOffset);
  147. constFVectorTransInComp=ActorToComponent.TransformNormal(TransInWorld);
  148. constFVectorNewOrigin=NewBoneTM.GetOrigin()+TransInComp;
  149. NewBoneTM.SetOrigin(NewOrigin);
  150. }
  151. // OutBoneTransforms.AddItem(NewBoneTM);
  152. EffectorLocation=NewBoneTM.GetOrigin();
  153. EffectorLocationSpace= BCS_WorldSpace;
  154. Super::CalculateNewBoneTransforms(BoneIndex,SkelComp,OutBoneTransforms);
  155. }
 

5 运行

如果单独一根骨骼的Recoil

 
 

6

14073102(CCDIKRecoil)的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  3. ASP.NET Core 之 Identity 入门(一)

    前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...

  4. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  5. Online Judge(OJ)搭建(第一版)

    搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...

  6. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  7. 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成

    阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...

  8. 【.net 深呼吸】细说CodeDom(5):类型成员

    前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...

  9. 【.net 深呼吸】细说CodeDom(4):类型定义

    上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...

随机推荐

  1. 一首诗,致亲爱的csdn

    来自csdn的Rachel-Zhang姐姐 还记得--致亲爱的csdn 还记得你年轻时的摸样? 简单的文字,无瑕的脸庞. 现在的你,满脸风霜. 五粮液的广告,在我的文章中久久荡漾. 还记得当初的梦想? ...

  2. 使用Python调用Flickr API抓取图片数据

    Flickr是雅虎旗下的图片分享网站,上面有全世界网友分享的大量精彩图片,被认为是专业的图片网站.其API也很友好,可以实现多种功能.这里我使用了Python调用其API获得了大量的照片数据.需要注意 ...

  3. XMLHttpRequest简介

    要真正实现这种绚丽的奇迹,必须非常熟悉一个 JavaScript 对象,即 XMLHttpRequest. 下面给出将要用于该对象的很少的几个 方法和属性. ·open():建立到服务器的新请求. · ...

  4. 微信小程序-图片、录音、音频播放、音乐播放、视屏、文件

    图片: wx.chooseImage(OBJECT) 从本地相册选择图片或使用相机拍照. OBJECT参数说明: 注:文件的临时路径,在小程序本次启动期间可以正常使用,如需持久保存,需在主动调用 wx ...

  5. linux安装配置apk打包程序gradle+jdk+Android_sdk+python自动化编译脚本

    安装gradle: 1.下载gradle包 去这里下载需要的tar.gz包:https://services.gradle.org/distributions/ 2.解压 tar zxvf gradl ...

  6. 【Extjs】large按钮,图片全部覆盖按钮

    在网上找了一些办法,不太好用,还是该Extjs的样式来的最快... 将下列css加到Extjs所用页面. .x-btn-default-large-mc { padding-bottom:0px !i ...

  7. 程序设计入门——C语言 第8周编程练习 1 单词长度(4分)

    第8周编程练习 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统 ...

  8. Spring-boot-admin功能说明

    http://blog.csdn.net/xingfulangren/article/details/52304413 **************************************** ...

  9. ubuntu14.04利用aliyun安装docker

    docker官网上的安装步骤比较麻烦,而且下载下来后pull镜像也特别慢.通过阿里云可以快速安装docker,并且可配置加速器.通过阿里云超快速安装docker: 安装或升级Docker 请安装1.6 ...

  10. centos各版本信息

    CentOS version Architectures RHEL base Kernel CentOS release date RHEL release date Delay (days) 2.1 ...