• 14040802(攻击骨骼控制)


    【目标】

    攻击时的骨骼控制

    【思路】

    1 武器骨骼碰撞时要受碰撞面影响

    2 参考FootPlaceMent的机制

    3 AUDKPawn.DoFootPlacement

    4 为

    5

    问题:

    1)如何确定射线方向

    作为参数

    2)是否需要三个方向的射线(XYZ轴)

    方案:

    1 每帧Tick检测碰撞的结果,碰撞的结果影响骨骼位置

    2

    方案2:

    1 USkelControlAttack.CalculateNewBoneTransforms中,从当前骨骼上面找两块骨骼,分别为End Mid Start(Start为最上面的)

    2 计算最上面Start到End方向上的射线检测,碰撞的点就是当前

    【问题】骨骼的方向并不一定是武器下落时的方向,一般情况应是骨骼方向的垂直方向

    所以在原方向上要有旋转

    3 如果用碰撞体?

    4 【问题】

    如果碰撞到设置骨骼位置,只影响一块骨骼就会出现

    如何约束骨骼的旋转

    可以采用一根骨骼的方法

    5 【问题】

    武器没有AnimTree,需要手动添加上去

    USkeletalMeshComponent.Animations 

    是配置到USkeletonMesh上,还是在代码中设置?

    6 【问题】

    如果检测的结果在正面和反面

    就会出现

     

    7

    【步骤】

    1 新建DevelopmentSrcEngineClassesSkelControlHitPlacement.uc

    class SkelControlHitPlacement extends SkelControlLimb
        hidecategories(Effector)
        native(Anim);
    cpptext
    {
        // USkelControlBase interface
        virtual void CalculateNewBoneTransforms(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<FBoneAtom>& OutBoneTransforms);    
    }
    defaultproperties
    {
    }

    编译

    2 添加USkelControlHitPlacement.CalculateNewBoneTransforms

    void USkelControlHitPlacement::CalculateNewBoneTransforms(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<FBoneAtom>& OutBoneTransforms)
    {
        check(BoneIndex != 0);
        INT LowerLimbIndex = SkelComp->SkeletalMesh->RefSkeleton(BoneIndex).ParentIndex;
        check(LowerLimbIndex != 0);
        INT UpperLimbIndex = SkelComp->SkeletalMesh->RefSkeleton(LowerLimbIndex).ParentIndex;
        
        // Find the root and end position in world space.
        FVector RootPos = SkelComp->SpaceBases(UpperLimbIndex).GetOrigin();
        FVector WorldRootPos = SkelComp->LocalToWorld.TransformFVector(RootPos);
        FVector EndPos = SkelComp->SpaceBases(BoneIndex).GetOrigin();
        FVector WorldEndPos = SkelComp->LocalToWorld.TransformFVector(EndPos);
        FVector LegDelta = WorldEndPos - WorldRootPos;
        FVector LegDir = LegDelta.SafeNormal();
        FMatrix WorldMatrix = SkelComp->SpaceBases(BoneIndex).ToMatrix() * SkelComp->LocalToWorld;
        LegDir = WorldMatrix.TransformNormal(GetAxisDirVector(AXIS_X,false).SafeNormal());
        FVector CheckEndPos = WorldEndPos + (1000.f) * LegDir;
        FVector HitLocation, HitNormal;
        UBOOL bHit = SkelComp->LegLineCheck( WorldRootPos, CheckEndPos, HitLocation, HitNormal);
        
        AActor* Owner = SkelComp->GetOwner();
        
        if(bHit)
        {
            EffectorLocation = HitLocation;
        }
        else
            EffectorLocation = WorldEndPos;
            EffectorLocationSpace = BCS_WorldSpace;
        Super::CalculateNewBoneTransforms(BoneIndex, SkelComp, OutBoneTransforms);
        check(OutBoneTransforms.Num() == 3);
        if( Owner )
        {
            Owner->DrawDebugLine(WorldRootPos,CheckEndPos,255,0,0);
            Owner->DrawDebugPoint(EffectorLocation,10,FLinearColor(255,255,0));
        }
    }

    换色的点是检测到的射线交点

    3 调整射线方向 脚骨骼的Z轴方向

    绿色点为起点 黄色点为检测到的碰撞点

     

    4 添加属性DevelopmentSrcEngineClassesSkelControlHitPlacement.uc

    var(Hit)        EAxis                    CheckAxis;
    var(Hit)        bool                    bInvertCheckAxis;
    var(Hit)        float                    CheckLineRadius;

    相应的C++

    【问题】

    目前只有剑尖有检测,调整的是剑尖的骨骼位置

    如果需要中部骨骼检测,再调整体的旋转怎么办?

    【问题】

     

    细红线为射线,方向有可能两边,交点法线方向

    所以,用射线和交点法线方向决定不了骨骼是否碰撞了面

    方案1:

        减少射线长度,减少误差,

        就会出现很近才能检测到结果,

    方案2:

        交点到骨骼的方向和交点法线方向 (还是不能确定)

      

    方案3

        骨骼A到B的射线检测,如果有交点且红色射线也检测到交点,说明真正有交点

    A和B如果都在物体中呢,AB的射线长度多少呢?

    方案4

        采取A到C的射线检测,和红色射线检测来共同决定

     

    void USkelControlHitPlacement::CalculateNewBoneTransforms(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<FBoneAtom>& OutBoneTransforms)
    {
        check(BoneIndex != 0);
        INT LowerLimbIndex = SkelComp->SkeletalMesh->RefSkeleton(BoneIndex).ParentIndex;
        check(LowerLimbIndex != 0);
        INT UpperLimbIndex = SkelComp->SkeletalMesh->RefSkeleton(LowerLimbIndex).ParentIndex;
        
        // Find the root and end position in world space.
        FVector RootPos = SkelComp->SpaceBases(UpperLimbIndex).GetOrigin();
        FVector WorldRootPos = SkelComp->LocalToWorld.TransformFVector(RootPos);
        FVector EndPos = SkelComp->SpaceBases(BoneIndex).GetOrigin();
        FVector WorldEndPos = SkelComp->LocalToWorld.TransformFVector(EndPos);
        FVector LegDelta = WorldEndPos - WorldRootPos;
        FVector LegDir = LegDelta.SafeNormal();
        FMatrix WorldMatrix = SkelComp->SpaceBases(BoneIndex).ToMatrix() * SkelComp->LocalToWorld;
        LegDir = WorldMatrix.TransformNormal(GetAxisDirVector(CheckAxis,bInvertCheckAxis).SafeNormal());
        FVector CheckEndPos = WorldEndPos + CheckLineRadius * LegDir;
        FVector CheckStartPos = WorldEndPos - CheckLineRadius * LegDir;
        FVector HitLocation, HitNormal;
        UBOOL bBoneHit = SkelComp->LegLineCheck( CheckStartPos, CheckEndPos, HitLocation, HitNormal);
        FVector HitLocation2, HitNormal2;
        UBOOL bBoneLineHit = SkelComp->LegLineCheck( WorldEndPos, WorldRootPos, HitLocation2, HitNormal2);
        
        AActor* Owner = SkelComp->GetOwner();
        
        if(bBoneHit && bBoneLineHit)
        {
            EffectorLocation = HitLocation;
        }
        else
            EffectorLocation = WorldEndPos;
        EffectorLocationSpace = BCS_WorldSpace;
        Super::CalculateNewBoneTransforms(BoneIndex, SkelComp, OutBoneTransforms);
        check(OutBoneTransforms.Num() == 3);
        if( Owner )
        {
            Owner->DrawDebugLine(CheckStartPos,CheckEndPos,255,0,0);
            Owner->DrawDebugPoint(EffectorLocation,10,FLinearColor(255,255,0));
            Owner->DrawDebugPoint(WorldRootPos,8,FLinearColor(0,0,255));
            Owner->DrawDebugPoint(CheckEndPos,8,FLinearColor(0,255,255));
            Owner->DrawDebugPoint(CheckStartPos,8,FLinearColor(0,255,0));
        }
    }

    6





  • 相关阅读:
    win7文件搜索技巧
    【SpringCloud】Zuul网关入门(十五)
    【SpringCloud】Hystrix仪表板(Dashboard)(十四)
    【SpringCloud】Hystrix工作原理(十三)
    【SpringCloud】Hystrix服务隔离(十二)
    【SpringCloud】Hystrix服务熔断(十一)
    【SpringCloud】Hystrix服务降级(十)
    【SpringCloud】OpenFeign服务超时与日志输出(九)
    【SpringCloud】OpenFeign服务调用(八)
    【SpringCloud】自定义Ribbon均衡策略(七)
  • 原文地址:https://www.cnblogs.com/username/p/5821433.html
Copyright © 2020-2023  润新知