zoukankan      html  css  js  c++  java
  • 7:《地牢守卫者》代码分析:DarkElf,DrakElfController

      DarkElf是远战敌人,该敌人能射出一支箭从而对玩家产生伤害。在执行装箭动画的过程中动态的让箭创建出来并连接到手的插槽上。

      动画情况是这样:DarkElf从后背拿出一支箭,这时候动态生成该箭的模型,当在MeleeSwingEnd的时候(预备实际发出射弹的时候将该Component销毁)

      有两个重要的函数Mesh.DetachComponent(component); //将一个组件从模型上剔除     

       Mesh.AttachComponentToSocket(component,socket);  //将一个组件连接到一个插槽上

      var name ProjectileSocketName;                              //生成的箭射弹插槽

      var name AttachmentSocketName;                         //拿在手上动画插槽

      var vector ArrowLocation;               

      var rotator ArrowRotation;

      var SkeletalMesh ArrowMesh;      

      var vector ArrowMeshScale;

      var transient SkeletalMeshComponent ArrowMeshComponent;

       以上是一些定义在DarkElf中的变量。

      event MeleeSwingEnd()

    {

      if(ArrowMeshComponent!=none)

      {

        Mesh.DetachComponent(ArrowMeshComponent);

        ArrowMeshComponent=none; //当把裝箭动作执行完的时候就把该组件给弄消失

      }

      DarkElfController(Controller).FireProjectile(); //这里生成射出的箭
    }

       起始攻击动作

     event MeleeSwingStart()

    {

      if(ArrowMeshComponent!=none)

      {

        Mesh.DetachComponent(ArrowMeshComponent);

        ArrowMeshComponent=none; //当把裝箭动作执行完的时候就把该组件给弄消失

      }

      if(!controller.IsInState(EnemyController(controller).AttackStateName)) //检测该动作是否在攻击状态中执行

      return;



      ArrowMeshComponent=new class'SkeletalMeshComponent' //新生成一个共箭的组件

      ArrowMeshComponent.SetSkeletalMesh(ArrowMesh);

      ArrowMeshComponent.SetTranslation(ArrowLocation);

      ArrowMeshComponent.SetDrawScale(ArrowMeshScale);

      ArrowMeshComponent.SetRotation(ArrowRotation);

      Mesh.AttachComponentToSocket(ArrowMeshComponent,AttachmentSocketName);
    }

      前面讲过GetSocketWorldLocationAndRotation(name,out_location,out_rotation)可以看出不用返回,因为参数是out型

      

    function GetProjectileFireOrientation(out vector out_location,out rotator out_rotation)

      {

        Mesh.GetSocketWorldLocationAndRotation(ProjectileSocketName,out_Location,out_rotation);
      }

      这里获取了射弹的方向和位置,稍后再看该函数在哪里进行调用。

      

      现在进入DrakElfController类

       插一个话题,如何使用最简单的方法生成一个火箭炮攻击玩家呢?

      function Fire()

    {  

      local UTProj_Rocket MyRocket; //这是火箭筒的射弹

      MyRocket = spawn(class'UTProj_Rocket', self,, Location); //生成是当然的

      MyRocket.Init(normal(Enemy.Location - Location));     //初始化函数Init指定敌人的方向,将会攻击敌人

    }

       controller类只不过是将上述程序复杂化了,当然功能和安全性将会更完善。

       

    local AntProjectile SpawnProjectileTemplate;

      function FireProjectile(); //在攻击状态外面声明一下该函数

        随后进入攻击状态

      state ShootAttacking extends Attacking

    {

       

    function FireProjectile()

      {

        local AntProjectile theProjectile; //看看简化函数就明白了

        local vector SpawnProjectileLocation;

        local rotator SpawnProjectileRotation;

          

        DarkElf(pawn).GetProjectileFireOrientation(SpawnProjectileLocation,SpawnProjectileRotation);

        if(VSize(SpawnProjectileLocation)==0) //如果获取不到插槽位置就用pawn.location来替代,这样使代码更为健壮

        SpawnProjectileLocation=pawn.location;

        

        theProjectile=Spawn(SpawnProjectileTemplate,,,SpawnProjectielLocation,SpawnProjectileRotation,SpawnProjectileTemplate,true);

        theProjectile.ProjectileInit(vector(SpawnProjectileRotation),pawn); ////重写了Init函数,为了使用偏差使用
      }


       

     Begin:

          //先播动画,在动画的notify中自然会调用发射事件

          

          StopLatentExecution();

          // if we have an attack animation...
         if(DunDefEnemy(Pawn).PlayAttackAnimation() > 0)
      {
       // sleep and hold position until we're finished playing the attack animation
      // -- anim notifies will presumably take care of actually triggering the firing the projectile while we're waiting
       while(DunDefEnemy(Pawn).IsCurrentlyPlayingAttackAnimation())
       {
       Pawn.Acceleration.X = 0;
       Pawn.Acceleration.Y = 0;
       Pawn.Acceleration.Z = 0;

      Focus=none;
      Sleep(0);
       }
      }
       else //in case we have no animation, just wait a small time and then fire
       {
       Pawn.Acceleration.X = 0;
       Pawn.Acceleration.Y = 0;
       Pawn.Acceleration.Z = 0;
       Focus=none;
      Sleep(1.5);
       FireProjectile();
       }

       PopState();

          
      }

    这样所有的pawn和controller相关的内容结束,下来我将进入武器和射弹类的研究。
       

  • 相关阅读:
    c# 集合运算
    Nuxt
    引入js,不共享变量
    sourcetree将存在的本地项目提交到远程仓库
    c#DateTime与unix时间戳互相转换
    IfcBoundingBox
    IfcBooleanResult
    IfcAnnotationFillArea
    IfcGeometricRepresentationItem
    IfcRepresentationItem
  • 原文地址:https://www.cnblogs.com/NEOCSL/p/2370086.html
Copyright © 2011-2022 走看看