Пример #1
0
 /// <summary>
 /// 检测伤害(显示命中声音)
 /// </summary>
 /// <param name="iDamage"></param>
 /// <param name="fieldName"></param>
 private void IDamageStateChagned(IDamage iDamage, string fieldName)
 {
     if (string.Equals(fieldName, GameState.GetFieldNameStatic <IDamage, int>(temp => temp.WeaponPhysicHit)))
     {
         EnumWeaponTypeByPlayerState weaponType           = (EnumWeaponTypeByPlayerState)iDamage.WeaponPhysicHit;
         PhysicHitAudioStruct        physicHitAudioStruct = physicHitAudios.FirstOrDefault(temp => temp.WeaponType == weaponType);
         if (physicHitAudioStruct != null)
         {
             audioSources[3].clip = physicHitAudioStruct.Clip;
             audioSources[3].Play();
         }
     }
     else if (string.Equals(fieldName, GameState.GetFieldNameStatic <IDamage, int>(temp => temp.MagicTypeHit)))
     {
         if (iDamage.MagicTypeHit >= (int)EnumSkillType.MagicCombinedLevel2Start && iDamage.MagicTypeHit < (int)EnumSkillType.MagicCombinedLevel2End)
         {
             MagicHitAudioStruct magicHitAudioStruct = magicHitAduios.FirstOrDefault(temp => temp.SkillType == iDamage.MagicTypeHit);
             if (magicHitAudioStruct != null)
             {
                 audioSources[3].clip = magicHitAudioStruct.Clip;
                 audioSources[3].Play();
             }
         }
     }
 }
    private void IPlayerStateChagned(IPlayerState iPlayerState, string fieldName)
    {
        if (string.Equals(fieldName, GameState.GetFieldNameStatic <IPlayerState, EnumWeaponTypeByPlayerState>(temp => temp.WeaponTypeByPlayerState)))
        {
            EnumWeaponTypeByPlayerState weaponType_Right = iPlayerState.WeaponTypeByPlayerState | EnumWeaponTypeByPlayerState.Shield - EnumWeaponTypeByPlayerState.Shield;//去除盾牌
            switch (weaponType_Right)
            {
            case EnumWeaponTypeByPlayerState.None:
                SingleWeapon.SetActive(false);
                TwiceWeapon.SetActive(false);
                Arch.SetActive(false);
                break;

            case EnumWeaponTypeByPlayerState.SingleHandedSword:
                SingleWeapon.SetActive(true);
                TwiceWeapon.SetActive(false);
                Arch.SetActive(false);
                break;

            case EnumWeaponTypeByPlayerState.TwoHandedSword:
                SingleWeapon.SetActive(false);
                TwiceWeapon.SetActive(true);
                Arch.SetActive(false);
                break;

            case EnumWeaponTypeByPlayerState.Arch:
                SingleWeapon.SetActive(false);
                TwiceWeapon.SetActive(false);
                Arch.SetActive(true);
                break;

            case EnumWeaponTypeByPlayerState.CrossBow:
                break;

            case EnumWeaponTypeByPlayerState.Shield:
                break;

            case EnumWeaponTypeByPlayerState.Dagger:
                break;

            case EnumWeaponTypeByPlayerState.LongRod:
                break;

            case EnumWeaponTypeByPlayerState.ShortRod:
                break;

            case EnumWeaponTypeByPlayerState.CrystalBall:
                break;
            }
        }
    }
    /// <summary>
    /// 设置物理技能攻击
    /// </summary>
    /// <param name="playerObj">玩家操纵状态对象</param>
    /// <param name="physicsSkillStateStruct">本技能释放时的数据状态</param>
    /// <param name="skillType">技能类型</param>
    /// <param name="weaponTypeByPlayerState">武器类型</param>
    public void SetPhysicSkillAttack(IPlayerState iPlayerState, PhysicsSkillStateStruct physicsSkillStateStruct, EnumSkillType skillType, EnumWeaponTypeByPlayerState weaponTypeByPlayerState)
    {
        if (iPlayerState == null || physicsSkillStateStruct == null)
        {
            return;
        }
        IPlayerState                _iPlayerState            = iPlayerState;
        PhysicsSkillStateStruct     _physicsSkillStateStruct = physicsSkillStateStruct;
        EnumSkillType               _SKillType = skillType;
        EnumWeaponTypeByPlayerState _WeaponTypeByPlayerState   = weaponTypeByPlayerState;
        PhysicSkillInjuryDetection  physicSkillInjuryDetection = _iPlayerState.PhysicSkillInjuryDetection;

        if (physicSkillInjuryDetection != null)
        {
            physicSkillInjuryDetection.CheckAttack(_SKillType, _WeaponTypeByPlayerState, 1, null, (innerOrder, target) =>
            {
                return(CalculatePhysicSkillHurt(_SKillType, _WeaponTypeByPlayerState, _physicsSkillStateStruct, innerOrder, target));
            });
        }
        //如果这是冲锋则开启任务(移动对象)
        switch (skillType)
        {
        case EnumSkillType.ZS03:
            float zs03Time = 0;
            runTaskStruct_Charge.StartTask(0,
                                           () =>
            {
                zs03Time       += Time.deltaTime;
                float speedRate = 0;
                if (zs03Time < 0.3f)
                {
                    speedRate = 0;
                }
                else
                {
                    speedRate = 1;
                }
                _iPlayerState.ForceMoveStruct = new ForceMoveStruct()
                {
                    MoveSpeed = _physicsSkillStateStruct.AttributeState.MoveSpeed * speedRate
                };
                if (zs03Time > 1f)
                {
                    runTaskStruct_Charge.StopTask();
                    IAnimatorState iAnimatorState   = GameState.Instance.GetEntity <IAnimatorState>();
                    iAnimatorState.SkillSustainable = false;
                }
            }, 0, false);
            break;
        }
    }
 /// <summary>
 /// 检测攻击
 /// </summary>
 /// <param name="skillType">技能类型</param>
 /// <param name="WeaponType">武器类型</param>
 /// <param name="attackSpeed">攻击速度</param>
 /// <param name="attackLayerMask">内部设置的检测层</param>
 /// <param name="CheckResultAction">检测到碰撞对象后的回调</param>
 /// <param name="otherCheck">其他的检测</param>
 public void CheckAttack(EnumSkillType skillType, EnumWeaponTypeByPlayerState WeaponType, float attackSpeed, LayerMask?attackLayerMask, Func <int, GameObject, bool> CheckResultAction, int otherCheck = 0)
 {
     this.CheckResultAction = CheckResultAction;
     this.AttackSpeed       = attackSpeed;
     if (attackLayerMask != null)
     {
         tempAttackLayerMask = attackLayerMask.Value;
     }
     else
     {
         tempAttackLayerMask = null;
     }
     if (checkStructCollectionArray != null)
     {
         checkStructCollection = checkStructCollectionArray
                                 .Where(temp => temp.SkillType == skillType)                                                          //判断技能类型
                                 .Where(temp => temp.WeaponType == WeaponType || temp.WeaponType == EnumWeaponTypeByPlayerState.None) //判断武器类型(如果设置的是None表示什么武器都可以)
                                 .Where(temp => (temp.OtherCheck == 0 || otherCheck == 0) ? true : temp.OtherCheck == otherCheck)     //判断是否存在其他的检测,并判断是否通过检测
                                 .FirstOrDefault();
     }
     else
     {
         checkStructCollection = null;
     }
     if (checkStructCollection != null)
     {
         //进行设置
         checkStructCollection.CheckStructs.ToList().ForEach(temp =>
         {
             temp.Collider.gameObject.SetActive(true);//打开检测对象
             //查找检测脚本
             PhysicSkillInjuryDetection_Check physicSkillInjuryDetection_Check = temp.Collider.gameObject.GetComponent <PhysicSkillInjuryDetection_Check>();
             //如果为空则添加
             if (physicSkillInjuryDetection_Check == null)
             {
                 physicSkillInjuryDetection_Check = temp.Collider.gameObject.AddComponent <PhysicSkillInjuryDetection_Check>();
             }
             //设置检测层
             physicSkillInjuryDetection_Check.checkMask = tempAttackLayerMask != null ? tempAttackLayerMask.Value : this.attackLayerMask;
         });
     }
     nowCheckTime        = 0;
     skillOrderToObjList = new Dictionary <int, List <GameObject> >();
 }
    /// <summary>
    /// 计算物理技能伤害
    /// </summary>
    /// <param name="skillType">技能类型</param>
    /// <param name="weaponTypeByPlayerState">武器类型</param>
    /// <param name="physicsSkillStateStruct">物理技能数据</param>
    /// <param name="innerOrder">当前攻击的阶段</param>
    /// <param name="target">攻击的目标</param>
    private bool CalculatePhysicSkillHurt(EnumSkillType skillType, EnumWeaponTypeByPlayerState weaponTypeByPlayerState, PhysicsSkillStateStruct physicsSkillStateStruct, int innerOrder, GameObject target)
    {
        if (target == null)
        {
            return(true);
        }
        InteractiveAsMonster interactiveAsMonster = target.GetComponent <InteractiveAsMonster>();

        if (interactiveAsMonster == null)
        {
            return(true);
        }
        IPlayerState     iPlayerState     = GameState.Instance.GetEntity <IPlayerState>();
        AttackHurtStruct attackHurtStruct = new AttackHurtStruct()
        {
            hurtTransferNum    = 0,
            hurtType           = EnumHurtType.PhysicSkill,
            attributeState     = physicsSkillStateStruct.AttributeState,
            hurtFromObj        = iPlayerState.PlayerObj,
            PhysicAttackFactor = new PhysicAttackFactor()
            {
                IncreaseRatioInjuryFactor = iPlayerState.SelfRoleOfRaceInfoStruct.physicAttackToDamageRateRatio,
                MinimumDamageFactor       = iPlayerState.SelfRoleOfRaceInfoStruct.physicQuickToMinDamageRatio
            }
        };

        CalculateHurt.Result hurtResult = interactiveAsMonster.GiveAttackHurtStruct(attackHurtStruct);
        if (hurtResult.IsCrit || hurtResult.hurtRate > 0.2f)
        {
            iPlayerState.SetVibration(0.1f, 0.7f, 0.7f);//设置手柄震动
        }
        //如果命中了则自身的动画造成0.1秒的延迟
        IAnimatorState iAnimatorState = GameState.Instance.GetEntity <IAnimatorState>();

        if (weaponTypeByPlayerState != EnumWeaponTypeByPlayerState.Arch)
        {
            iAnimatorState.PhysicHitMonsterAnimDelay = true;
        }
        //停止持续
        iAnimatorState.SkillSustainable = false;
        //如果是冲锋则停止任务
        switch (skillType)
        {
        case EnumSkillType.ZS03:
            runTaskStruct_Charge.StopTask();
            break;
        }
        //设置命中声音
        WeaponPhysicHit = (int)weaponTypeByPlayerState;
        //判断技能类型,有些紧只需要判断一次
        switch (skillType)
        {
        case EnumSkillType.GJS03:
        case EnumSkillType.SSS03:
        case EnumSkillType.ZS03:
            return(false);

        default:
            return(true);
        }
    }
    /// <summary>
    /// 计算物理普通攻击伤害
    /// </summary>
    /// <param name="weaponTypeByPlayerState">武器类型</param>
    /// <param name="iAttribute">攻击时的状态数据</param>
    /// <param name="innerOrder">当前攻击的阶段</param>
    /// <param name="target">攻击的目标</param>
    private bool CalculateNormalActionHurt(EnumWeaponTypeByPlayerState weaponTypeByPlayerState, IAttributeState _iAttribute, int innerOrder, GameObject target)
    {
        if (target == null)
        {
            return(true);
        }
        InteractiveAsMonster interactiveAsMonster = target.GetComponent <InteractiveAsMonster>();

        if (interactiveAsMonster == null)
        {
            return(true);
        }
        IPlayerState    iPlayerState = GameState.Instance.GetEntity <IPlayerState>();
        IAttributeState iAttribute   = ((AttributeStateAdditional)_iAttribute).Clone();

        switch (weaponTypeByPlayerState)
        {
        case EnumWeaponTypeByPlayerState.SingleHandedSword:
            if (innerOrder == 3)
            {
                iAttribute.PhysicsAttacking *= 1.2f;
            }
            break;

        case EnumWeaponTypeByPlayerState.TwoHandedSword:
            if (innerOrder == 3)
            {
                iAttribute.PhysicsAttacking *= 0.7f;
            }
            break;

        case EnumWeaponTypeByPlayerState.Arch:
            if (innerOrder == 3)
            {
                iAttribute.PhysicsAttacking *= 2f;
            }
            break;
        }
        AttackHurtStruct attackHurtStruct = new AttackHurtStruct()
        {
            hurtTransferNum    = 0,
            hurtType           = EnumHurtType.NormalAction,
            attributeState     = iAttribute,
            hurtFromObj        = iPlayerState.PlayerObj,
            PhysicAttackFactor = new PhysicAttackFactor()
            {
                IncreaseRatioInjuryFactor = iPlayerState.SelfRoleOfRaceInfoStruct.physicAttackToDamageRateRatio,
                MinimumDamageFactor       = iPlayerState.SelfRoleOfRaceInfoStruct.physicQuickToMinDamageRatio
            }
        };

        CalculateHurt.Result hurtResult = interactiveAsMonster.GiveAttackHurtStruct(attackHurtStruct);
        if (hurtResult.IsCrit || hurtResult.hurtRate > 0.2f)
        {
            iPlayerState.SetVibration(0.1f, 0.6f, 0.6f);//设置手柄震动
        }
        //如果命中了则自身的动画造成0.1秒的延迟
        IAnimatorState iAnimatorState = GameState.Instance.GetEntity <IAnimatorState>();

        if (weaponTypeByPlayerState != EnumWeaponTypeByPlayerState.Arch)
        {
            iAnimatorState.PhysicHitMonsterAnimDelay = true;
        }
        //停止持续
        iAnimatorState.SkillSustainable = false;
        //设置命中声音
        WeaponPhysicHit = (int)weaponTypeByPlayerState;
        //判断武器类型
        switch (weaponTypeByPlayerState)//根据武器类型判断是否还需要下次检测
        {
        case EnumWeaponTypeByPlayerState.Arch:
            return(false);

        default:
            return(true);
        }
    }
    /// <summary>
    /// 设置普通攻击
    /// </summary>
    /// <param name="iPlayerState">玩家状态对象</param>
    /// <param name="attackOrder">攻击的编号</param>
    /// <param name="nowIAttributeState">本技能释放时的数据状态</param>
    /// <param name="weaponTypeByPlayerState">武器类型</param>
    public void SetNormalAttack(IPlayerState iPlayerState, int attackOrder, IAttributeState nowIAttributeState, EnumWeaponTypeByPlayerState weaponTypeByPlayerState)
    {
        if (iPlayerState == null || nowIAttributeState == null)
        {
            return;
        }
        IPlayerState                _iPlayerState            = iPlayerState;
        IAttributeState             _NowIAttributeState      = nowIAttributeState;
        EnumWeaponTypeByPlayerState _WeaponTypeByPlayerState = weaponTypeByPlayerState;
        IAnimatorState              iAnimatorState           = GameState.Instance.GetEntity <IAnimatorState>();
        int _attackOrder = attackOrder;
        PhysicSkillInjuryDetection physicSkillInjuryDetection = _iPlayerState.PhysicSkillInjuryDetection;
        float runTime = 0;//检测超时时间

        if (physicSkillInjuryDetection != null)
        {
            Action BeginCheckAttack = () =>
            {
                runTaskStruct_NormalAttack.StopTask();//停止任务
                physicSkillInjuryDetection.CheckAttack(EnumSkillType.PhysicAttack, _WeaponTypeByPlayerState, 1, null, (innerOrder, target) =>
                {
                    return(CalculateNormalActionHurt(_WeaponTypeByPlayerState, _NowIAttributeState, innerOrder, target));
                },
                                                       attackOrder
                                                       );
            };
            //该任务用于检测是否可以进入该普通攻击的检测
            runTaskStruct_NormalAttack.StartTask(0,
                                                 () =>
            {
                switch (attackOrder)
                {
                case 1:
                    if (iAnimatorState.AnimationClipTypeState != null && iAnimatorState.AnimationClipTypeState.AnimationClipType == EnumAnimationClipType.Attack1 && iAnimatorState.AnimationClipTypeState.TimeType == EnumAnimationClipTimeType.In)
                    {
                        BeginCheckAttack();
                    }
                    break;

                case 2:
                    if (iAnimatorState.AnimationClipTypeState != null && iAnimatorState.AnimationClipTypeState.AnimationClipType == EnumAnimationClipType.Attack2 && iAnimatorState.AnimationClipTypeState.TimeType == EnumAnimationClipTimeType.In)
                    {
                        BeginCheckAttack();
                    }
                    break;

                case 3:
                    if (iAnimatorState.AnimationClipTypeState != null && iAnimatorState.AnimationClipTypeState.AnimationClipType == EnumAnimationClipType.Attack3 && iAnimatorState.AnimationClipTypeState.TimeType == EnumAnimationClipTimeType.In)
                    {
                        BeginCheckAttack();
                    }
                    break;

                default:
                    runTaskStruct_NormalAttack.StopTask();        //停止任务
                    break;
                }
            }, 0, true,
                                                 () =>
            {
                runTime += Time.deltaTime;
                if (runTime > 1)
                {
                    return(false);
                }
                return(true);
            });
        }
    }