Пример #1
0
        public override void    execute()
        {
            BasicAction basic_action = this.behavior.basic_action;

            if (this.finish_child())
            {
                this.step.set_next(STEP.MOVE);
            }

            // ---------------------------------------------------------------- //
            // 다음 상태로 전환할지 체크합니다.

            switch (this.step.do_transition())
            {
            // 걷는 중.
            case STEP.MOVE:
            {
            }
            break;

            // 멈춤.
            case STEP.REST:
            {
                if (this.step.get_time() > 1.0f)
                {
                    this.step.set_next(STEP.MOVE);
                }

                chrBehaviorLocal player = PartyControl.get().getLocalPlayer();

                if (this.behavior.isInAttackRange(player.control))
                {
                    this.push(this.melee_attack);
                    this.step.sleep();
                }
            }
            break;
            }

            // ---------------------------------------------------------------- //
            // 상태가 전환됐을 때의 초기화.

            while (this.step.get_next() != STEP.NONE)
            {
                switch (this.step.do_initialize())
                {
                // 걷는 중.
                case STEP.MOVE:
                {
                }
                break;
                }
            }

            // ---------------------------------------------------------------- //
            // 각 상태에서의 실행 처리.

            switch (this.step.do_execution(Time.deltaTime))
            {
            // 걷는 중.
            case STEP.MOVE:
            {
                var coli = basic_action.control.collision_results.Find(x => x.object1.tag == "Wall" || x.object1.tag == "Player");

                // 벽(또는 플레이어)에 부딪히면 반사해서 방향을 바꿉니다.
                do
                {
                    if (coli == null)
                    {
                        break;
                    }
                    if (coli.option0 == null)
                    {
                        break;
                    }
                    ContactPoint cp = (ContactPoint)coli.option0;

                    // 벽의 법선 방향을 90도 단위로 합니다.

                    Vector3 normal = cp.normal;

                    float normal_angle = Mathf.Atan2(normal.x, normal.z) * Mathf.Rad2Deg;

                    normal_angle = MathUtility.unormDegree(normal_angle);
                    normal_angle = Mathf.Round(normal_angle / 90.0f) * 90.0f;

                    normal = Quaternion.AngleAxis(normal_angle, Vector3.up) * Vector3.forward;

                    Vector3 v = basic_action.getMoveVector();

                    if (Vector3.Dot(v, normal) >= 0.0f)
                    {
                        break;
                    }

                    v -= 2.0f * Vector3.Dot(v, normal) * normal;
                    basic_action.setMoveDirByVector(v);

                    // 플레이어에게 부딪혔으면 대미지를 줍니다.
                    do
                    {
                        if (coli.object1.tag != "Player")
                        {
                            break;
                        }

                        chrController chr = coli.object1.GetComponent <chrController>();

                        if (chr == null)
                        {
                            break;
                        }
                        if (!(chr.behavior is chrBehaviorLocal))
                        {
                            break;
                        }

                        chr.causeDamage(this.control.vital.getAttackPower(), -1);
                    } while(false);
                } while(false);

                basic_action.setMoveSpeed(4.0f);
                basic_action.setMoveMotionSpeed(0.0f);

                basic_action.executeMove();

                //

                this.model.transform.Rotate(new Vector3(7.0f, 0.0f, 0.0f));
            }
            break;

            // 멈춤.
            case STEP.REST:
            {
                basic_action.setMoveMotionSpeed(0.0f);
            }
            break;
            }

            // ---------------------------------------------------------------- //

            this.execute_child();
        }
Пример #2
0
    // ================================================================ //

    public void             execute()
    {
        if (this.is_attacking)
        {
            if (this.behavior.control.getMotion() != "m003_attack")
            {
                this.is_attacking = false;
            }
        }
        else
        {
            if (this.is_trigger_attack)
            {
                this.timer             = 0.5f;
                this.is_trigger_attack = false;
                this.is_attacking      = true;

                this.behavior.control.cmdSetMotion("m003_attack", 1);
            }
        }

        if (this.is_attacking)
        {
            // 목표 방향으로 향한다.
            if (this.target != null)
            {
                this.behavior.control.cmdSmoothHeadingTo(this.target.control.getPosition());
            }

            do
            {
                if (this.behavior.control.getMotion() != "m003_attack")
                {
                    break;
                }

                if (!this.behavior.control.isMotionAcrossingTime(0.35f))
                {
                    break;
                }

                // 공격 범위 내에 있는 적에게 대미지.

                int layer_mask = LayerMask.GetMask("Enemy", "EnemyLair", "Boss");
                var coliders   = Physics.OverlapSphere(this.behavior.control.getPosition(), this.behavior.control.vital.getAttackDistance(), layer_mask);

                foreach (var colider in coliders)
                {
                    chrController chr = colider.gameObject.GetComponent <chrController>();

                    if (chr == null)
                    {
                        continue;
                    }
                    if (!this.isInAttackRange(chr))
                    {
                        continue;
                    }

                    chr.causeDamage(this.behavior.control.vital.getAttackPower(), this.behavior.control.global_index);

                    // '근접공격이 먹혔을 때 호출하는 함수' 호출.
                    this.behavior.onMeleeAttackHitted(chr.behavior);
                }
            } while(false);
        }

        this.timer -= Time.deltaTime;
        this.timer  = Mathf.Max(0.0f, this.timer);
    }