个人项目(4):敌人2

个人项目(4):敌人2

敌人的行动逻辑

第二种类型敌人(即敌人2,远程)当主角位于其攻击范围之外时并不会做任何行动,当主角位于其攻击范围之内时便会向主角进行攻击,当主角进入其被攻击范围时便会逃跑,逃跑方向便是向主角移动方向的相反方向,该行动逻辑的部分实现代码如下:

Vector3 x=follow.position;
       Vector3 y=this.GetComponent<Transform>().position;
       float distances=Vector3.Distance(x,y);
       if(distances<=maxdistance&&distances>mindistance){//当主体对象位于该对象攻击范围内时
           movement.Set(0.0f,0.0f,0.0f);
           Animator.SetBool("isrunning",false);
           as1.Stop();
           musicplaying=true;
           if(canhit==true){//可以攻击
                Animator.SetBool("isattacking",true);
                canhit=false;
                animaction=true;
           }
           else if(canhit==false){//攻击冷却
                if(animaction==true){//动画执行中
                animTimer+=Time.deltaTime;
                if(animTimer>=animTime)
                {
                    Animator.SetBool("isattacking",false);
                    animTimer=0;
                    animaction=false;//动画结束
                }
                }
                hitTimer+=Time.deltaTime;
                if (hitTimer>=hitTime)
                {
                    canhit=true;
                    hitTimer=0;
                    animaction=true;
                }
           }
           rotation2();
       }
       else if(distances<=mindistance){//当主体对象位于该对象逃跑范围时
            if(musicplaying==true){
            as1.Play();
            }
            musicplaying=false;
            if(canhit==false){
                if(animaction==true){
                Animator.SetBool("isattacking",false);
                animTimer=0;
                animaction=false;
                }
                hitTimer+=Time.deltaTime;
                if (hitTimer>=hitTime)
                {
                    canhit=true;
                    hitTimer=0;
                }
           }
           movement=this.GetComponent<Transform>().position-follow.position;
           movement.Normalize();
           Animator.SetBool("isrunning",true);
           Animator.SetBool("isattacking",false);
           rotation1();
       }
       else if(distances>maxdistance){//当主体对象位于该对象发觉范围外时
           as1.Stop();
           musicplaying=true;
           if(canhit==false){
                if(animaction==true){
                Animator.SetBool("isattacking",false);
                animTimer=0;
                animaction=false;
                }
                hitTimer+=Time.deltaTime;
                if (hitTimer>=hitTime)
                {
                    canhit=true;
                    hitTimer=0;
                }
           }
           movement.Set(0.0f,0.0f,0.0f);
           Animator.SetBool("isrunning",false);
           Animator.SetBool("isattacking",false);
       }

为了避免敌人2随意地使用投掷技能,以及配合动画效果的实现,我为敌人2的投掷也设定了冷却时间,同时也设置了动画时间,确保子弹能在动画相应时间内发射出去。动画控制器如图:

image-20220824105237411

子弹逻辑

既然是远程设计的敌人,那就需要设置远程射击物。因为没有现成模型,我就用胶囊体代表了子弹,因为动画效果是右手攻击一下再左手攻击一下,所以我准备了两颗子弹,一左一右。

image-20220824105412509

当动画开始执行,即人物开始攻击时,右手子弹发射,等动画执行一秒后,此时左手运动,左手子弹再发射。所以我设置了动画时间这一参数,相关的代码逻辑如下:

void Update()
    {
        if(isfly==false){//子弹不在飞行
            GetComponent<Renderer>().enabled = false; 
            if(mainbody.animaction==true) hit();
            else if(mainbody.animaction==false){
            transform.position=follow2.position;
            }
        }
        else if(isfly==true){//子弹在飞行
            GetComponent<Renderer>().enabled = true;
            flytimer+=Time.deltaTime;
            if (flytimer>=flytime)
            {//子弹返回
                isfly=false;
                flytimer=0;
                transform.position=follow2.position;
            }
            else{
                transform.position = Vector3.Lerp (transform.position, TargetPosition,m_Speed * Time.deltaTime);
            }
        }
        if(ishit==true){//子弹击中主体角色
            if(player.invincibility==false){
               ishit=false;
               player.hp--;
               player.ishit=true;
           }
        }
    }

    private void OnTriggerStay(Collider other){
        if(other.transform==follow1){
            ishit=true;
        }
    }

    private void OnTriggerExit(Collider other){
        if(other.transform==follow1){
            ishit=false;
        }
    }

    void hit(){//子弹飞向主体角色当前所在位置
        isfly=true;
        TargetPosition=follow1.position+Vector3.up;
        transform.position = Vector3.Lerp (transform.position, TargetPosition,m_Speed * Time.deltaTime);
    }
void hit(){//子弹经过一段时间后飞向主体角色当前所在位置
        waitTimer+=Time.deltaTime;
        if(waitTimer>=waitTime)
        {
            isfly=true;
            waitTimer=0;
            TargetPosition=follow1.position+Vector3.up;
            transform.position = Vector3.Lerp (transform.position, TargetPosition,m_Speed * Time.deltaTime);
        }
    }

子弹触发器的逻辑与敌人1的攻击触发器逻辑类似。GetComponent().enabled 用于控制模型渲染呈现与否,当其为false时,模型会消失,即隐形,即子弹在飞行时会呈现,不飞行返回人物身边时会消失。我也设置了子弹的飞行时间,当飞行时间到了便会自动返回人物身边,返回的位置是加在人物模型旁边的特定位置(即position1和position2),因为模型移动时该位置也会相对于人物移动,就可以实现子弹返回的效果了(但是因为要添加多个敌人预制件,position1和position2的Tag位置相同的话会造成子弹全部只返回到一个敌人身边,所以我给每个敌人的子弹都重新添加了新的脚本,这就造成了脚本复用率的低下)。

image-20220824110220216

猜你喜欢

转载自blog.csdn.net/m0_54119099/article/details/126503372
今日推荐