Files
VRProject/Assets/_Scripts/SpiderIdleState.cs
2026-07-14 14:14:48 +09:00

313 lines
9.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
public class SpiderIdleState : SpiderStateBase
{
public SpiderIdleState(BossController owner) : base(owner) { }
public override void EnterState() => boss.Anim.SetTrigger("Idle");
public override void UpdateState()
{
if (boss.Player == null) return;
if (Vector3.Distance(boss.transform.position, boss.Player.position) <= boss.ChaseRange)
{
boss.ChangeState<SpiderChaseState>();
}
}
}
public class SpiderChaseState : SpiderStateBase
{
public SpiderChaseState(BossController owner) : base(owner) { }
public override void EnterState() => boss.Agent.isStopped = false;
public override void UpdateState()
{
if (boss.Player == null) return;
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>();
return;
}
boss.Agent.SetDestination(boss.Player.position);
boss.Anim.SetFloat("Speed", boss.Agent.velocity.magnitude);
}
}
public class SpiderBiteState : SpiderStateBase
{
private float stateTimer;
public SpiderBiteState(BossController owner) : base(owner) { }
public override void EnterState()
{
stateTimer = 1.5f;
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 UpdateState()
{
boss.Agent.velocity = Vector3.zero;
stateTimer -= Time.deltaTime;
if (stateTimer <= 0f)
{
if (boss.PendingUltimate) boss.ChangeState<SpiderJumpToCeilingState>();
else boss.ChangeState<SpiderChaseState>();
}
}
}
public class SpiderChargeState : SpiderStateBase
{
private float roarTimer;
private float chargeTimer;
private Vector3 chargeDirection;
private bool isChargingPhase;
public SpiderChargeState(BossController owner) : base(owner) { }
public override void EnterState()
{
roarTimer = boss.ChargeRoarDuration;
chargeTimer = boss.ChargeDuration;
isChargingPhase = false;
boss.Agent.isStopped = true;
boss.Agent.velocity = Vector3.zero;
boss.ResetChargeCooldown();
boss.Anim.SetTrigger("Attack_Roar");
Debug.Log($"🔊 蜘蛛ボス:遠距離を検知。その場でピタッと完全停止。咆哮(溜め {roarTimer}秒)を開始!");
}
public override void ExitState()
{
boss.Anim.SetBool("IsCharging", false);
boss.Agent.speed = boss.NormalSpeed;
boss.Agent.acceleration = boss.NormalAcceleration;
boss.Agent.isStopped = false;
}
public override void UpdateState()
{
// フェーズ1咆哮・溜めロックオン
if (!isChargingPhase)
{
roarTimer -= Time.deltaTime;
boss.Agent.velocity = Vector3.zero; // 完全固定
if (boss.Player != null)
{
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), Time.deltaTime * 10f);
}
}
if (roarTimer <= 0f)
{
isChargingPhase = true;
boss.Anim.SetTrigger("ChargeStart");
boss.Anim.SetBool("IsCharging", true);
if (boss.Player != null)
{
chargeDirection = (boss.Player.position - boss.transform.position).normalized;
chargeDirection.y = 0;
}
Vector3 targetDestination = boss.transform.position + chargeDirection * 20f;
boss.Agent.isStopped = false;
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)))
{
boss.ChangeState<SpiderChaseState>();
}
}
}
public class SpiderJumpToCeilingState : SpiderStateBase
{
private float roarTimer;
private float jumpProgress;
private Vector3 startPos;
private bool isJumpingPhase;
public SpiderJumpToCeilingState(BossController owner) : base(owner) { }
public override void EnterState()
{
roarTimer = boss.JumpRoarDuration;
jumpProgress = 0f;
startPos = boss.transform.position;
isJumpingPhase = false;
boss.Agent.enabled = false;
boss.Anim.SetTrigger("Attack_Roar");
Debug.Log($"🚨 蜘蛛ボス:必殺技前の一大威嚇(咆哮 {roarTimer}秒)!");
}
public override void UpdateState()
{
// フェーズ1飛び立つ前の威嚇
if (!isJumpingPhase)
{
roarTimer -= Time.deltaTime;
if (roarTimer <= 0f)
{
isJumpingPhase = true;
boss.Anim.SetTrigger("JumpUp");
}
return;
}
// フェーズ2ジャンプ空中移動
if (boss.ceilingAnchor == null) return;
jumpProgress += Time.unscaledDeltaTime * 1.5f;
Vector3 currentPos = Vector3.Lerp(startPos, boss.ceilingAnchor.position, jumpProgress);
currentPos.y += Mathf.Sin(jumpProgress * Mathf.PI) * 3f;
boss.transform.position = currentPos;
if (jumpProgress >= 1f)
{
boss.transform.position = boss.ceilingAnchor.position;
boss.ChangeState<SpiderCeilingAttackState>();
}
}
}
// ==========================================
// ■ STATE: CEILING ATTACK (インスペクター無段階調整版)
// ==========================================
public class SpiderCeilingAttackState : SpiderStateBase
{
private float timer = 0f;
private float shotTimer = 0f;
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()
{
boss.Anim.SetBool("IsOnCeiling", false);
if (boss.groundAnchor != null) boss.transform.position = boss.groundAnchor.position;
boss.Agent.enabled = true;
boss.Anim.SetTrigger("Land");
}
public override void UpdateState()
{
timer -= Time.deltaTime;
shotTimer -= Time.deltaTime;
// タイマーがゼロになったら発射
if (shotTimer <= 0f)
{
ExecuteRandomWebAttack();
// ★リファクタリング:インスペクターで設定した間隔(秒)でリセットして弾数を制御
shotTimer = boss.CeilingShotInterval;
}
if (timer <= 0f)
{
boss.ChangeState<SpiderChaseState>();
}
}
private void ExecuteRandomWebAttack()
{
// インスペクターで設定された半径AttackRadiusを基準にランダム座標を計算
Vector2 randomCircle = Random.insideUnitCircle * boss.AttackRadius;
Vector3 targetGroundPos = new Vector3(
boss.groundAnchor.position.x + randomCircle.x,
boss.groundAnchor.position.y,
boss.groundAnchor.position.z + randomCircle.y
);
// ★リファクタリング:予兆マークのディレイや糸の生存時間もインスペクターと完全連動
boss.SpawnWarningAndWeb(targetGroundPos, boss.WebWarningDelay, boss.WebDuration);
}
}
public class SpiderStunState : SpiderStateBase
{
private float stunTimer;
public SpiderStunState(BossController owner) : base(owner) { }
public override void EnterState()
{
stunTimer = 4.0f;
boss.Anim.SetTrigger("StunStart");
boss.Anim.SetBool("IsStunned", true);
if (boss.Agent.enabled) boss.Agent.isStopped = true;
Debug.Log("🛡️ パリィ成功! チャンスタイム!");
}
public override void ExitState()
{
boss.Anim.SetBool("IsStunned", false);
if (boss.Agent.enabled) boss.Agent.isStopped = false;
}
public override void UpdateState()
{
stunTimer -= Time.deltaTime;
if (stunTimer <= 0f)
{
if (boss.PendingUltimate) boss.ChangeState<SpiderJumpToCeilingState>();
else boss.ChangeState<SpiderChaseState>();
}
}
}