This commit is contained in:
ohgushiyuga
2026-08-27 12:51:15 +09:00
parent 1441c96f74
commit 52341100ed
32 changed files with 840 additions and 1076 deletions

View File

@@ -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()