void Update() { bool is_damaged = false; if (isPaused) { return; } lifeTimer += Time.deltaTime; // 충돌 체크. do { // 벽에 닿으면 지운다. // 벽 건너편 적에 맞지 않게 먼저 벽을 조사한다. if (this.collision_results.Exists(x => x.object1.layer == LayerMask.NameToLayer("Wall"))) { is_damaged = true; break; } // 플레이어 닿으면 대미지를 준다. foreach (var result in this.collision_results) { if (result.object1 == null) { continue; } if (result.object1.tag != "Player") { continue; } chrBehaviorPlayer behavior = result.object1.GetComponent <chrController>().behavior as chrBehaviorPlayer; if (behavior == null) { continue; } if (!behavior.isLocal()) { // 리모트 플레이어에게는 대미지를 주지 않는다. continue; } result.object1.GetComponent <chrController>().causeDamage(this.owner.vital.getShotPower(), -1); result.object1 = null; is_damaged = true; } if (is_damaged) { break; } // 라이프 타이머가 초과되면 사라진다. if (lifeTimer >= lifeSpan) { is_damaged = true; break; } } while(false); this.collision_results.Clear(); if (is_damaged) { GameObject.Destroy(this.gameObject); } else { // 이동. float speed = 12.0f; Vector3 move_to = this.transform.position + this.transform.forward * speed * Time.deltaTime; this.rigidbody.MovePosition(move_to); } }
protected void execCharge(float deltaTime) { // 일정 거리를 이동했으면 돌격 종료. if ((transform.position - chargeStartPoisition).magnitude > CHARGE_DISTANCE) { finishedCharging(); return; } // ---------------------------------------------------------------- // // 이동(위치 좌표 보간). Vector3 position = this.getPosition(); float rotateAlpha = 1.0f; // 어느 정도 강력하게 진로를 바꾸는가. 속도가 오르면 방향을 바꾸기 어려워진다. float currentMaxSpeed = maxSpeed * getMaxSpeedModifier(); velocity += acceleration * deltaTime; velocity = Mathf.Clamp(velocity, 0.0f, maxSpeed * getMaxSpeedModifier()); float speed_per_frame = velocity * Time.deltaTime; Vector3 move_vector = this.transform.forward; position += move_vector * speed_per_frame * velocity; position.y = floorY; this.cmdSetPosition(position); // 스피드가 나오지 않은 동안은 타깃 방향으로 향한다. rotateAlpha = 1.0f - velocity / currentMaxSpeed; updateDesiredDir(targetToCharge); exec_rotate(deltaTime, rotateAlpha); // 연출 처리. // 발 연기 처리. footSmokeRespawnTimer += deltaTime; if (footSmokeRespawnTimer >= chargeFootSmokeRespawnDuration) { footSmokeRespawnTimer = 0.0f; // 여기 랜덤은 연출용. createFootSmoke(transform.rotation * Quaternion.AngleAxis(Random.Range(-30.0f, 30.0f), Vector3.up) * Vector3.back * 5.0f); } // FIXME. 어쨌든 오라는 최고속이 되고 난 후에 나온다. if (chargeAura == null && Mathf.Abs(velocity - maxSpeed * getMaxSpeedModifier()) <= float.Epsilon) { // 오라 처리. chargeAura = EffectRoot.getInstance().createChargeAura(); chargeAura.transform.parent = transform; chargeAura.transform.localPosition = new Vector3(0.0f, 3.6f, 5.0f); chargeAura.transform.localRotation = Quaternion.identity; // 대신에 콧김은 이제 내뿜지 않는다. enableSpawnSnortEffects = false; } float speed_rate = velocity / currentMaxSpeed; foreach (var result in this.collision_results) { if (result.object1 == null) { continue; } GameObject other = result.object1; // 충돌한 플레이어에게 대미지를 준다. if (other.tag == "Player") { chrBehaviorPlayer player = chrBehaviorBase.getBehaviorFromGameObject <chrBehaviorPlayer>(other); if (player == null) { continue; } if (this.tackled_players.Contains(player)) { continue; } if (speed_rate < 0.5f) { continue; } if (player.isLocal()) { player.control.causeDamage(this.vital.getAttackPower(), -1); player.beginBlowOutSide(this.getPosition(), 3.0f * this.getScale(), this.transform.forward); } this.tackled_players.Add(player); finishedCharging(); break; } } }