otamesi
This commit is contained in:
@@ -1,5 +1,26 @@
|
||||
using UnityEngine;
|
||||
|
||||
public interface ISpiderState
|
||||
{
|
||||
void EnterState();
|
||||
void UpdateState();
|
||||
void ExitState();
|
||||
}
|
||||
|
||||
public abstract class SpiderStateBase : ISpiderState
|
||||
{
|
||||
protected readonly BossController boss;
|
||||
|
||||
protected SpiderStateBase(BossController owner)
|
||||
{
|
||||
boss = owner;
|
||||
}
|
||||
|
||||
public virtual void EnterState() { }
|
||||
public abstract void UpdateState();
|
||||
public virtual void ExitState() { }
|
||||
}
|
||||
|
||||
public class SpiderIdleState : SpiderStateBase
|
||||
{
|
||||
public SpiderIdleState(BossController owner) : base(owner) { }
|
||||
@@ -29,14 +50,12 @@ public class SpiderChaseState : SpiderStateBase
|
||||
|
||||
float distance = Vector3.Distance(boss.transform.position, boss.Player.position);
|
||||
|
||||
// 遠距離突進判定(カプセル化されたプロパティを使用)
|
||||
if (distance >= boss.ChargeMinimumDistance && boss.ChargeCooldownTimer <= 0f)
|
||||
{
|
||||
boss.ChangeState<SpiderChargeState>();
|
||||
return;
|
||||
}
|
||||
|
||||
// 至近距離噛みつき判定
|
||||
if (distance <= boss.BiteRange)
|
||||
{
|
||||
boss.ChangeState<SpiderBiteState>();
|
||||
@@ -58,14 +77,12 @@ public class SpiderBiteState : SpiderStateBase
|
||||
public override void EnterState()
|
||||
{
|
||||
stateTimer = 1.5f;
|
||||
boss.Agent.ResetPath();
|
||||
boss.Agent.isStopped = true;
|
||||
boss.Agent.velocity = Vector3.zero;
|
||||
boss.Agent.ResetPath();
|
||||
boss.Agent.isStopped = true;
|
||||
boss.Agent.velocity = Vector3.zero;
|
||||
|
||||
boss.Anim.SetFloat("Speed", 0f);
|
||||
|
||||
boss.Anim.SetTrigger("Attack_Bite");
|
||||
Debug.Log("🎯 蜘蛛ボス:通常噛みつき開始。攻撃モーション中にゆっくり向き直ります。");
|
||||
}
|
||||
|
||||
public override void ExitState()
|
||||
@@ -81,17 +98,17 @@ public class SpiderBiteState : SpiderStateBase
|
||||
{
|
||||
Vector3 lookDir = (boss.Player.position - boss.transform.position).normalized;
|
||||
lookDir.y = 0;
|
||||
|
||||
|
||||
if (lookDir != Vector3.zero)
|
||||
{
|
||||
boss.transform.rotation = Quaternion.Slerp(
|
||||
boss.transform.rotation,
|
||||
Quaternion.LookRotation(lookDir),
|
||||
boss.transform.rotation,
|
||||
Quaternion.LookRotation(lookDir),
|
||||
Time.deltaTime * TurnSpeed
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stateTimer -= Time.deltaTime;
|
||||
if (stateTimer <= 0f)
|
||||
{
|
||||
@@ -121,7 +138,6 @@ public class SpiderChargeState : SpiderStateBase
|
||||
|
||||
boss.ResetChargeCooldown();
|
||||
boss.Anim.SetTrigger("Attack_Roar");
|
||||
Debug.Log($"🔊 蜘蛛ボス:遠距離を検知。その場でピタッと完全停止。咆哮(溜め {roarTimer}秒)を開始!");
|
||||
}
|
||||
|
||||
public override void ExitState()
|
||||
@@ -134,11 +150,10 @@ public class SpiderChargeState : SpiderStateBase
|
||||
|
||||
public override void UpdateState()
|
||||
{
|
||||
// フェーズ1:咆哮・溜めロックオン
|
||||
if (!isChargingPhase)
|
||||
{
|
||||
roarTimer -= Time.deltaTime;
|
||||
boss.Agent.velocity = Vector3.zero; // 完全固定
|
||||
boss.Agent.velocity = Vector3.zero;
|
||||
|
||||
if (boss.Player != null)
|
||||
{
|
||||
@@ -168,13 +183,10 @@ public class SpiderChargeState : SpiderStateBase
|
||||
boss.Agent.speed = boss.ChargeSpeed;
|
||||
boss.Agent.acceleration = 120f;
|
||||
boss.Agent.SetDestination(targetDestination);
|
||||
|
||||
Debug.Log("🚀 蜘蛛ボス:ロックオン完了。全速力で突進ダッシュを発射!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// フェーズ2:突進移動中
|
||||
chargeTimer -= Time.deltaTime;
|
||||
|
||||
if (chargeTimer <= 0f || (boss.Agent.velocity.magnitude < 0.2f && chargeTimer < (boss.ChargeDuration - 0.3f)))
|
||||
@@ -202,12 +214,10 @@ public class SpiderJumpToCeilingState : SpiderStateBase
|
||||
|
||||
boss.Agent.enabled = false;
|
||||
boss.Anim.SetTrigger("Attack_Roar");
|
||||
Debug.Log($"🚨 蜘蛛ボス:必殺技前の一大威嚇(咆哮 {roarTimer}秒)!");
|
||||
}
|
||||
|
||||
public override void UpdateState()
|
||||
{
|
||||
// フェーズ1:飛び立つ前の威嚇
|
||||
if (!isJumpingPhase)
|
||||
{
|
||||
roarTimer -= Time.deltaTime;
|
||||
@@ -219,7 +229,6 @@ public class SpiderJumpToCeilingState : SpiderStateBase
|
||||
return;
|
||||
}
|
||||
|
||||
// フェーズ2:ジャンプ空中移動
|
||||
if (boss.ceilingAnchor == null) return;
|
||||
|
||||
jumpProgress += Time.unscaledDeltaTime * 1.5f;
|
||||
@@ -237,25 +246,20 @@ public class SpiderJumpToCeilingState : SpiderStateBase
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// ■ STATE: CEILING ATTACK (インスペクター無段階調整版)
|
||||
// ==========================================
|
||||
public class SpiderCeilingAttackState : SpiderStateBase
|
||||
{
|
||||
private float timer = 0f;
|
||||
private float shotTimer = 0f;
|
||||
private float timer;
|
||||
private float shotTimer;
|
||||
|
||||
public SpiderCeilingAttackState(BossController owner) : base(owner) { }
|
||||
|
||||
public override void EnterState()
|
||||
{
|
||||
// ★リファクタリング:インスペクターで設定した必殺技の長さを適用
|
||||
timer = boss.CeilingAttackDuration;
|
||||
shotTimer = 0f;
|
||||
|
||||
boss.Anim.SetBool("IsOnCeiling", true);
|
||||
boss.PendingUltimate = false;
|
||||
Debug.Log($"🕸️ 蜘蛛ボス:天井からの乱射開始! 持続時間: {timer}秒 / 発射間隔: {boss.CeilingShotInterval}秒");
|
||||
}
|
||||
|
||||
public override void ExitState()
|
||||
@@ -271,12 +275,9 @@ public class SpiderCeilingAttackState : SpiderStateBase
|
||||
timer -= Time.deltaTime;
|
||||
shotTimer -= Time.deltaTime;
|
||||
|
||||
// タイマーがゼロになったら発射
|
||||
if (shotTimer <= 0f)
|
||||
{
|
||||
ExecuteRandomWebAttack();
|
||||
|
||||
// ★リファクタリング:インスペクターで設定した間隔(秒)でリセットして弾数を制御
|
||||
shotTimer = boss.CeilingShotInterval;
|
||||
}
|
||||
|
||||
@@ -286,14 +287,13 @@ public class SpiderCeilingAttackState : SpiderStateBase
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteRandomWebAttack()
|
||||
private void ExecuteRandomWebAttack()
|
||||
{
|
||||
Vector3 targetGroundPos = Vector3.zero;
|
||||
int maxAttempts = 15; // 無限ループ(フリーズ)を防止するための最大再抽選回数
|
||||
|
||||
int maxAttempts = 15;
|
||||
|
||||
for (int i = 0; i < maxAttempts; i++)
|
||||
{
|
||||
// 1. 一旦ランダムな座標を算出
|
||||
Vector2 randomCircle = Random.insideUnitCircle * boss.AttackRadius;
|
||||
targetGroundPos = new Vector3(
|
||||
boss.groundAnchor.position.x + randomCircle.x,
|
||||
@@ -301,29 +301,23 @@ public class SpiderCeilingAttackState : SpiderStateBase
|
||||
boss.groundAnchor.position.z + randomCircle.y
|
||||
);
|
||||
|
||||
// 2. 現在アクティブなすべての糸との距離を計測する
|
||||
bool isTooClose = false;
|
||||
foreach (Vector3 existingPos in boss.ActiveWebPositions)
|
||||
foreach (Vector3 existingPos in boss.WebSpawner.ActiveWebPositions)
|
||||
{
|
||||
// 設定された回避半径(WebAvoidanceRadius)より近い既存の糸があるか?
|
||||
if (Vector3.Distance(targetGroundPos, existingPos) < boss.WebAvoidanceRadius)
|
||||
if (Vector3.Distance(targetGroundPos, existingPos) < boss.WebSpawner.WebAvoidanceRadius)
|
||||
{
|
||||
isTooClose = true;
|
||||
break; // 被り検知、この座標は使えないのでチェックを抜けて再抽選へ
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 誰とも被っていなければ、このクリーンな座標で確定
|
||||
if (!isTooClose)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!isTooClose) break;
|
||||
}
|
||||
|
||||
// 確定した(または上限に達して安全が担保された)座標へ向けて発射命令
|
||||
boss.SpawnWarningAndWeb(targetGroundPos, boss.WebWarningDelay, boss.WebDuration);
|
||||
boss.WebSpawner.SpawnWarningAndWeb(targetGroundPos, boss.WebWarningDelay, boss.WebDuration);
|
||||
}
|
||||
}
|
||||
|
||||
public class SpiderStunState : SpiderStateBase
|
||||
{
|
||||
private float stunTimer;
|
||||
@@ -336,8 +330,6 @@ public class SpiderStunState : SpiderStateBase
|
||||
boss.Anim.SetTrigger("StunStart");
|
||||
boss.Anim.SetBool("IsStunned", true);
|
||||
if (boss.Agent.enabled) boss.Agent.isStopped = true;
|
||||
Debug.Log("🛡️ パリィ成功! チャンスタイム!");
|
||||
|
||||
}
|
||||
|
||||
public override void ExitState()
|
||||
|
||||
Reference in New Issue
Block a user