妥協案

慣性をゼロにして蜘蛛と重ならないようにする
This commit is contained in:
oogushiyuuga
2026-07-06 17:59:19 +09:00
parent 4d3fee6ca5
commit bb90c969b4
8 changed files with 8146 additions and 94 deletions

View File

@@ -593,14 +593,6 @@ BlendTree:
m_Mirror: 0 m_Mirror: 0
- serializedVersion: 2 - serializedVersion: 2
m_Motion: {fileID: 7400000, guid: 4969fb900faad2b449340e1b6607370c, type: 3} m_Motion: {fileID: 7400000, guid: 4969fb900faad2b449340e1b6607370c, type: 3}
m_Threshold: 0.5
m_Position: {x: 0, y: 0}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: Speed
m_Mirror: 0
- serializedVersion: 2
m_Motion: {fileID: 7400024, guid: 8419ae74331b7e244986a3788edb7d65, type: 3}
m_Threshold: 1 m_Threshold: 1
m_Position: {x: 0, y: 0} m_Position: {x: 0, y: 0}
m_TimeScale: 1 m_TimeScale: 1

View File

@@ -331,7 +331,7 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 12d3bf61b014a48a2b7564c61da9d7ad, type: 3} m_Script: {fileID: 11500000, guid: 12d3bf61b014a48a2b7564c61da9d7ad, type: 3}
m_Name: AndroidXRPerformanceMetrics Standalone m_Name: AndroidXRPerformanceMetrics Android
m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRPerformanceMetrics m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRPerformanceMetrics
m_enabled: 0 m_enabled: 0
nameUi: Android XR Performance Metrics nameUi: Android XR Performance Metrics
@@ -713,7 +713,7 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 90ae1e8c3c7a542bba339faf2e771c5a, type: 3} m_Script: {fileID: 11500000, guid: 90ae1e8c3c7a542bba339faf2e771c5a, type: 3}
m_Name: AndroidXRSupportFeature Standalone m_Name: AndroidXRSupportFeature Android
m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRSupportFeature m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRSupportFeature
m_enabled: 0 m_enabled: 0
nameUi: Android XR Support nameUi: Android XR Support
@@ -1216,8 +1216,8 @@ MonoBehaviour:
features: features:
- {fileID: 7011443450567333355} - {fileID: 7011443450567333355}
- {fileID: -671281728444007487} - {fileID: -671281728444007487}
- {fileID: -901939997048047619} - {fileID: -6832857813982530537}
- {fileID: -1734471456787174204} - {fileID: -4559034614451708685}
- {fileID: 8980318060753866109} - {fileID: 8980318060753866109}
- {fileID: -6559185765804338520} - {fileID: -6559185765804338520}
- {fileID: -4756202077021157709} - {fileID: -4756202077021157709}
@@ -1228,7 +1228,7 @@ MonoBehaviour:
- {fileID: 348827886137839178} - {fileID: 348827886137839178}
- {fileID: -7499073031166464939} - {fileID: -7499073031166464939}
- {fileID: 7666556398442971420} - {fileID: 7666556398442971420}
- {fileID: -142859899272520151} - {fileID: 431653824124869831}
- {fileID: 3985858319333531581} - {fileID: 3985858319333531581}
- {fileID: -6511185071715886993} - {fileID: -6511185071715886993}
- {fileID: -4363231183632145407} - {fileID: -4363231183632145407}
@@ -1438,7 +1438,7 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6c36843bac48b29469f79baf3c98f9b6, type: 3} m_Script: {fileID: 11500000, guid: 6c36843bac48b29469f79baf3c98f9b6, type: 3}
m_Name: AndroidXRHandMeshData Standalone m_Name: AndroidXRHandMeshData Android
m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRHandMeshData m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRHandMeshData
m_enabled: 0 m_enabled: 0
nameUi: 'Android XR: Hand Mesh Data' nameUi: 'Android XR: Hand Mesh Data'

8
Assets/_Recovery.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d6baf78e3db2c4cfcb13753d1bfa9ae7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

7958
Assets/_Recovery/0.unity Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fa3b7b956ad1e4cdb9cd97acf0463412
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -692,7 +692,7 @@ MonoBehaviour:
maxHp: 500 maxHp: 500
currentHp: 500 currentHp: 500
chaseRange: 15 chaseRange: 15
biteRange: 4 biteRange: 5
ceilingAnchor: {fileID: 1626958826} ceilingAnchor: {fileID: 1626958826}
groundAnchor: {fileID: 1519524653} groundAnchor: {fileID: 1519524653}
attackRadius: 10 attackRadius: 10
@@ -716,7 +716,7 @@ NavMeshAgent:
m_Acceleration: 8 m_Acceleration: 8
avoidancePriority: 50 avoidancePriority: 50
m_AngularSpeed: 120 m_AngularSpeed: 120
m_StoppingDistance: 0 m_StoppingDistance: 6
m_AutoTraverseOffMeshLink: 1 m_AutoTraverseOffMeshLink: 1
m_AutoBraking: 1 m_AutoBraking: 1
m_AutoRepath: 1 m_AutoRepath: 1
@@ -745,6 +745,33 @@ BoxCollider:
serializedVersion: 3 serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1} m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 1.2} m_Center: {x: 0, y: 0, z: 1.2}
--- !u!54 &139010317
Rigidbody:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 139010306}
serializedVersion: 5
m_Mass: 1
m_LinearDamping: 0
m_AngularDamping: 0.05
m_CenterOfMass: {x: 0, y: 0, z: 0}
m_InertiaTensor: {x: 1, y: 1, z: 1}
m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_ImplicitCom: 1
m_ImplicitTensor: 1
m_UseGravity: 0
m_IsKinematic: 1
m_Interpolate: 0
m_Constraints: 0
m_CollisionDetection: 0
--- !u!1 &142265989 --- !u!1 &142265989
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1740,6 +1767,59 @@ Transform:
m_CorrespondingSourceObject: {fileID: 400000, guid: 24be8e1643b8a474fbb57fcda8a1c454, type: 3} m_CorrespondingSourceObject: {fileID: 400000, guid: 24be8e1643b8a474fbb57fcda8a1c454, type: 3}
m_PrefabInstance: {fileID: 267529390} m_PrefabInstance: {fileID: 267529390}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
--- !u!1 &290025993
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 290025994}
- component: {fileID: 290025995}
m_Layer: 0
m_Name: BiteTrigger
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!4 &290025994
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 290025993}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -0, y: -1.399, z: 5.395}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1928165057}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!65 &290025995
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 290025993}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 1
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!1001 &330362507 --- !u!1001 &330362507
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -4129,15 +4209,15 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 4782747046613586, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3} - target: {fileID: 4782747046613586, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
propertyPath: m_LocalScale.x propertyPath: m_LocalScale.x
value: 3.5 value: 3
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 4782747046613586, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3} - target: {fileID: 4782747046613586, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
propertyPath: m_LocalScale.y propertyPath: m_LocalScale.y
value: 3.5 value: 3
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 4782747046613586, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3} - target: {fileID: 4782747046613586, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
propertyPath: m_LocalScale.z propertyPath: m_LocalScale.z
value: 3.5 value: 3
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 4782747046613586, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3} - target: {fileID: 4782747046613586, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
propertyPath: m_LocalPosition.x propertyPath: m_LocalPosition.x
@@ -4185,7 +4265,10 @@ PrefabInstance:
objectReference: {fileID: 9100000, guid: ba91720f331c67548b9072c7454e7b3d, type: 2} objectReference: {fileID: 9100000, guid: ba91720f331c67548b9072c7454e7b3d, type: 2}
m_RemovedComponents: [] m_RemovedComponents: []
m_RemovedGameObjects: [] m_RemovedGameObjects: []
m_AddedGameObjects: [] m_AddedGameObjects:
- targetCorrespondingSourceObject: {fileID: 4560522044495882, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
insertIndex: -1
addedObject: {fileID: 290025994}
m_AddedComponents: m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 1987720806421918, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3} - targetCorrespondingSourceObject: {fileID: 1987720806421918, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
insertIndex: -1 insertIndex: -1
@@ -4196,6 +4279,9 @@ PrefabInstance:
- targetCorrespondingSourceObject: {fileID: 1987720806421918, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3} - targetCorrespondingSourceObject: {fileID: 1987720806421918, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
insertIndex: -1 insertIndex: -1
addedObject: {fileID: 139010311} addedObject: {fileID: 139010311}
- targetCorrespondingSourceObject: {fileID: 1987720806421918, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
insertIndex: -1
addedObject: {fileID: 139010317}
m_SourcePrefab: {fileID: 100100000, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3} m_SourcePrefab: {fileID: 100100000, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
--- !u!1001 &1153141912 --- !u!1001 &1153141912
PrefabInstance: PrefabInstance:
@@ -5121,6 +5207,10 @@ PrefabInstance:
propertyPath: m_Radius propertyPath: m_Radius
value: 0.3 value: 0.3
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 4295892835532738850, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4750419573833148750, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3} - target: {fileID: 4750419573833148750, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3}
propertyPath: m_AnchorMax.y propertyPath: m_AnchorMax.y
value: 1 value: 1
@@ -5287,7 +5377,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8806329115733545878, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3} - target: {fileID: 8806329115733545878, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3}
propertyPath: m_LocalPosition.x propertyPath: m_LocalPosition.x
value: 56.358013 value: 70.97
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8806329115733545878, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3} - target: {fileID: 8806329115733545878, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3}
propertyPath: m_LocalPosition.y propertyPath: m_LocalPosition.y
@@ -5295,7 +5385,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8806329115733545878, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3} - target: {fileID: 8806329115733545878, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3}
propertyPath: m_LocalPosition.z propertyPath: m_LocalPosition.z
value: -0.3739485 value: -0.37
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8806329115733545878, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3} - target: {fileID: 8806329115733545878, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3}
propertyPath: m_LocalRotation.w propertyPath: m_LocalRotation.w
@@ -7078,6 +7168,11 @@ MeshFilter:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1910195020} m_GameObject: {fileID: 1910195020}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1928165057 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 4560522044495882, guid: a2dfe588a42016e40892b72d31fd1cf6, type: 3}
m_PrefabInstance: {fileID: 1129977831}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &1949155364 --- !u!1001 &1949155364
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -11,7 +11,7 @@ public class BossController : MonoBehaviour
[SerializeField] private float maxHp = 500f; [SerializeField] private float maxHp = 500f;
[SerializeField] private float currentHp = 500f; [SerializeField] private float currentHp = 500f;
[SerializeField] public float chaseRange = 15f; [SerializeField] public float chaseRange = 15f;
[SerializeField] public float biteRange = 2.5f; [SerializeField] public float biteRange = 8f;
[Header("必殺技(天井)設定")] [Header("必殺技(天井)設定")]
[Tooltip("天井の待機座標となる空のGameObjectのTransformを指定してください")] [Tooltip("天井の待機座標となる空のGameObjectのTransformを指定してください")]
@@ -30,6 +30,20 @@ public class BossController : MonoBehaviour
[SerializeField] public float chargeDuration = 2f; [SerializeField] public float chargeDuration = 2f;
[SerializeField] public float chargeMinimumDistance = 6f; [SerializeField] public float chargeMinimumDistance = 6f;
[SerializeField] public float chargeCooldownDuration = 4f; [SerializeField] public float chargeCooldownDuration = 4f;
// ─── ボス固有の通常移動パラメーターStart時に自動キャッシュされます ───
public float NormalSpeed { get; private set; }
public float NormalAcceleration { get; private set; }
private void Start()
{
// インセペクターで設定されたNavMeshAgentの初期値を記憶しておく
if (Agent != null)
{
NormalSpeed = Agent.speed;
NormalAcceleration = Agent.acceleration;
}
}
#endregion #endregion
#region #region
@@ -41,7 +55,7 @@ public class BossController : MonoBehaviour
#region FSM #region FSM
private ISpiderState currentState; private ISpiderState currentState;
// ステートのインスタンスをキャッシュ(ガベージコレクションの発生を抑える) // ステートのインスタンスをキャッシュ(ガベージコレクションの発生を抑える)
private Dictionary<System.Type, ISpiderState> stateCache; private Dictionary<System.Type, ISpiderState> stateCache;
@@ -55,7 +69,7 @@ public class BossController : MonoBehaviour
{ {
Agent = GetComponent<NavMeshAgent>(); Agent = GetComponent<NavMeshAgent>();
Anim = GetComponent<Animator>(); Anim = GetComponent<Animator>();
GameObject pObj = GameObject.FindGameObjectWithTag("Player"); GameObject pObj = GameObject.FindGameObjectWithTag("Player");
if (pObj != null) Player = pObj.transform; if (pObj != null) Player = pObj.transform;
@@ -79,20 +93,16 @@ public class BossController : MonoBehaviour
ChangeState<SpiderIdleState>(); ChangeState<SpiderIdleState>();
} }
private void Update() private void Update()
{ {
currentState?.UpdateState(); currentState?.UpdateState();
// ★新設突進のクールダウンのみ、通常のUpdateで常に独立して減算する
if (ChargeCooldownTimer > 0f) if (ChargeCooldownTimer > 0f)
{ {
ChargeCooldownTimer -= Time.deltaTime; ChargeCooldownTimer -= Time.deltaTime;
} }
} }
/// <summary>
/// オブジェクト指向に基づいた、型安全なステート遷移メソッド
/// </summary>
public void ChangeState<T>() where T : ISpiderState public void ChangeState<T>() where T : ISpiderState
{ {
if (currentState != null) if (currentState != null)
@@ -136,8 +146,8 @@ public class BossController : MonoBehaviour
private void TriggerPhaseTransition() private void TriggerPhaseTransition()
{ {
// 咆哮、ジャンプ、スタン中以外であれば、現在の行動をキャンセルして即座に天井へエスケープ // 咆哮、ジャンプ、スタン中以外であれば、現在の行動をキャンセルして即座に天井へエスケープ
if (currentState is not SpiderJumpToCeilingState && if (currentState is not SpiderJumpToCeilingState &&
currentState is not SpiderCeilingAttackState && currentState is not SpiderCeilingAttackState &&
currentState is not SpiderStunState) currentState is not SpiderStunState)
{ {
ChangeState<SpiderJumpToCeilingState>(); ChangeState<SpiderJumpToCeilingState>();

View File

@@ -1,8 +1,5 @@
using UnityEngine; using UnityEngine;
// ==========================================
// ■ STATE: IDLE (待機状態)
// ==========================================
public class SpiderIdleState : ISpiderState public class SpiderIdleState : ISpiderState
{ {
private BossController boss; private BossController boss;
@@ -23,15 +20,6 @@ public class SpiderIdleState : ISpiderState
} }
} }
// ==========================================
// ■ STATE: CHASE (追跡・行動分岐状態)
// ==========================================
// ==========================================
// ■ STATE: CHASE (追跡・行動分岐状態) - 13x13ステージ最適化版
// ==========================================
// ==========================================
// ■ STATE: CHASE (遠距離即座突進・最適化版)
// ==========================================
public class SpiderChaseState : ISpiderState public class SpiderChaseState : ISpiderState
{ {
private BossController boss; private BossController boss;
@@ -47,7 +35,7 @@ public class SpiderChaseState : ISpiderState
float distance = Vector3.Distance(boss.transform.position, boss.Player.position); float distance = Vector3.Distance(boss.transform.position, boss.Player.position);
// ─── ★最優先判定:遠距離(6m以上かつクールダウン終了 ➔ 1歩も歩かずに即突進 ─── // 6m以上かつクールダウン終了 ➔ 1歩も歩かずに即突進
if (distance >= boss.chargeMinimumDistance && boss.ChargeCooldownTimer <= 0f) if (distance >= boss.chargeMinimumDistance && boss.ChargeCooldownTimer <= 0f)
{ {
boss.ChangeState<SpiderChargeState>(); boss.ChangeState<SpiderChargeState>();
@@ -61,15 +49,13 @@ public class SpiderChaseState : ISpiderState
return; return;
} }
// 判定3中間距離2.5m6m、または遠距離だけどクールダウン中の場合
// 💡 ここで初めて「通常歩きWalk」でじりじりとプレイヤーに近づきます
boss.Agent.SetDestination(boss.Player.position); boss.Agent.SetDestination(boss.Player.position);
boss.Anim.SetFloat("Speed", boss.Agent.velocity.magnitude); boss.Anim.SetFloat("Speed", boss.Agent.velocity.magnitude);
} }
} }
// ========================================== // ==========================================
// ■ STATE: BITE (通常噛みつき - パリィ可) // ■ STATE: BITE (完全足止め・めり込み防止版)
// ========================================== // ==========================================
public class SpiderBiteState : ISpiderState public class SpiderBiteState : ISpiderState
{ {
@@ -80,31 +66,33 @@ public class SpiderBiteState : ISpiderState
public void EnterState() public void EnterState()
{ {
stateTimer = 1.5f; // 攻撃アニメーションの想定想定想定 stateTimer = 1.5f;
// ★超重要:噛みつきモーションに入った瞬間、移動を「完全強制停止」してめり込みを防ぐ
boss.Agent.isStopped = true;
boss.Agent.velocity = Vector3.zero; // 慣性もゼロにする
boss.Anim.SetTrigger("Attack_Bite"); boss.Anim.SetTrigger("Attack_Bite");
Debug.Log("🎯 蜘蛛ボス:噛みつき攻撃!(パリィ受付中"); Debug.Log("🎯 蜘蛛ボス:噛みつき攻撃!(その場に完全固定");
} }
public void ExitState() { } public void ExitState()
{
// ステートを出るときに停止ロックを解除する
boss.Agent.isStopped = false;
}
public void UpdateState() public void UpdateState()
{ {
stateTimer -= Time.deltaTime; stateTimer -= Time.deltaTime;
if (stateTimer <= 0f) if (stateTimer <= 0f)
{ {
// 攻撃が終わったら、フェーズ移行チェックを挟みつつ追跡に戻る
if (boss.PendingUltimate) boss.ChangeState<SpiderJumpToCeilingState>(); if (boss.PendingUltimate) boss.ChangeState<SpiderJumpToCeilingState>();
else boss.ChangeState<SpiderChaseState>(); else boss.ChangeState<SpiderChaseState>();
} }
} }
} }
// ==========================================
// ■ STATE: CHARGE (走って体当たり突進 - パリィ可)
// ==========================================
// ==========================================
// ■ STATE: CHARGE (咆哮・溜めロック ➔ ロケット発射)
// ==========================================
public class SpiderChargeState : ISpiderState public class SpiderChargeState : ISpiderState
{ {
private BossController boss; private BossController boss;
@@ -117,89 +105,86 @@ public class SpiderChargeState : ISpiderState
public void EnterState() public void EnterState()
{ {
roarTimer = 1.5f; // 咆哮・溜めロックの時間1.5秒) roarTimer = 1.5f; // 溜め(咆哮)時間
chargeTimer = boss.chargeDuration; chargeTimer = boss.chargeDuration;
isChargingPhase = false; isChargingPhase = false;
boss.Agent.enabled = false; // その場に固定するためNavMeshを即オフ // ★重要突進の溜め中は、NavMeshAgentの自動移動を「一時停止」にしてその場に固定する
boss.ResetChargeCooldown(); // 突進のクールダウンを開始 boss.Agent.isStopped = true;
boss.ResetChargeCooldown();
// 1. 遠距離を検知した「その場」で、即座に咆哮威嚇を再生
boss.Anim.SetTrigger("Attack_Roar"); boss.Anim.SetTrigger("Attack_Roar");
Debug.Log("🔊 蜘蛛ボス:【遠距離検知】その場で咆哮・突進の溜め開始"); Debug.Log("🔊 蜘蛛ボス:その場で突進の溜め(咆哮)開始");
} }
public void ExitState() public void ExitState()
{ {
boss.Anim.SetBool("IsCharging", false); boss.Anim.SetBool("IsCharging", false);
boss.Agent.enabled = true;
// ★重要:突進ステートを出るときは、スピードと加速を通常のザコ敵・巡回時の値に必ず戻す
boss.Agent.speed = boss.NormalSpeed;
boss.Agent.acceleration = boss.NormalAcceleration;
boss.Agent.isStopped = false;
} }
public void UpdateState() public void UpdateState()
{ {
// ─── フェーズ1咆哮・溜め(動かずプレイヤーの方向を完全にロック) ─── // ─── フェーズ1咆哮・溜めロックオン(その場で旋回のみ ───
if (!isChargingPhase) if (!isChargingPhase)
{ {
roarTimer -= Time.deltaTime; roarTimer -= Time.deltaTime;
// プレイヤーが動いても、突進直前までずーーっとその方向を向いてロックオンし続ける
if (boss.Player != null) if (boss.Player != null)
{ {
Vector3 lookDir = (boss.Player.position - boss.transform.position).normalized; Vector3 lookDir = (boss.Player.position - boss.transform.position).normalized;
lookDir.y = 0; lookDir.y = 0;
if (lookDir != Vector3.zero) if (lookDir != Vector3.zero)
{ {
// 凄まじい速度でプレイヤーを正面に捉え続ける
boss.transform.rotation = Quaternion.Slerp(boss.transform.rotation, Quaternion.LookRotation(lookDir), Time.deltaTime * 10f); boss.transform.rotation = Quaternion.Slerp(boss.transform.rotation, Quaternion.LookRotation(lookDir), Time.deltaTime * 10f);
} }
} }
// 溜め時間が終わったら「発射」 // 溜め終了 ➔ 「発射」の瞬間
if (roarTimer <= 0f) if (roarTimer <= 0f)
{ {
isChargingPhase = true; isChargingPhase = true;
boss.Anim.SetTrigger("ChargeStart"); boss.Anim.SetTrigger("ChargeStart");
boss.Anim.SetBool("IsCharging", true); boss.Anim.SetBool("IsCharging", true);
// 発射した瞬間のプレイヤーのベクトルを最終確定(ロック完了) // 1. 発射する直線ベクトルを確定
if (boss.Player != null) if (boss.Player != null)
{ {
chargeDirection = (boss.Player.position - boss.transform.position).normalized; chargeDirection = (boss.Player.position - boss.transform.position).normalized;
chargeDirection.y = 0; chargeDirection.y = 0;
boss.transform.rotation = Quaternion.LookRotation(chargeDirection);
} }
Debug.Log("🚀 蜘蛛ボス:ロックオン完了、全速力で発射!");
// 2. ★プロの技:ボスの正面方向の「遥か彼方(例: 20m先」に、突進の目的地座標を計算
Vector3 targetDestination = boss.transform.position + chargeDirection * 20f;
// 3. ★移動をNavMeshAgentに一任する超高速化
boss.Agent.isStopped = false; // 移動再開
boss.Agent.speed = boss.chargeSpeed; // スピードを全速力14fなど
boss.Agent.acceleration = 120f; // 即座に最高速に達するように加速を爆上げする
// 目的地を設定NavMeshの壁やプレイヤーのCharacterControllerを考慮して自動で進むようになる
boss.Agent.SetDestination(targetDestination);
Debug.Log("🚀 蜘蛛ボスNavMesh突進ダッシュ発射");
} }
return; return;
} }
// ─── フェーズ2発射(端から端まで全速力ダッシュ ─── // ─── フェーズ2突進中NavMeshAgentが自動で走っているので、スクリプト側はタイマーを監視するだけ ───
// 【安全対策:レイキャストによる壁検知】
// 13x13ステージの端壁や柱に激突してめり込むのを防ぐため、ボスの目の前1.5mに障害物がないかチェック
Ray ray = new Ray(boss.transform.position + Vector3.up * 0.5f, chargeDirection);
if (Physics.Raycast(ray, 1.5f))
{
Debug.Log("🔒 蜘蛛ボス:ステージの端(壁)を検知したため、突進を安全に終了します。");
boss.ChangeState<SpiderChaseState>();
return;
}
// 全速力で直線移動
boss.transform.position += chargeDirection * boss.chargeSpeed * Time.deltaTime;
chargeTimer -= Time.deltaTime; chargeTimer -= Time.deltaTime;
if (chargeTimer <= 0f)
// 壁やプレイヤーに激突して完全に急停止したか、または設定時間が経過したら安全に終了
if (chargeTimer <= 0f || boss.Agent.velocity.magnitude < 0.2f && chargeTimer < (boss.chargeDuration - 0.3f))
{ {
// 時間を駆け抜けたら追跡に戻る
boss.ChangeState<SpiderChaseState>(); boss.ChangeState<SpiderChaseState>();
} }
} }
} }
// ==========================================
// ■ STATE: JUMP TO CEILING (天井への大ジャンプ)
// ==========================================
public class SpiderJumpToCeilingState : ISpiderState public class SpiderJumpToCeilingState : ISpiderState
{ {
private BossController boss; private BossController boss;
@@ -258,9 +243,6 @@ public class SpiderJumpToCeilingState : ISpiderState
} }
} }
// ==========================================
// ■ STATE: CEILING ATTACK (必殺技:天井糸吐き)
// ==========================================
public class SpiderCeilingAttackState : ISpiderState public class SpiderCeilingAttackState : ISpiderState
{ {
private BossController boss; private BossController boss;