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(); }
// ================================================================ // 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); }