IFD敌人初步

This commit is contained in:
SoulliesOfficial
2026-06-14 04:17:41 -04:00
parent a024305799
commit c9d9f60073
10 changed files with 21101 additions and 163 deletions

View File

@@ -0,0 +1,115 @@
using Cielonos.MainGame.Characters.AI;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.Shared.Utility;
using UnityEngine;
namespace Cielonos.MainGame.Characters.AI
{
[Category("Cielonos/Rhythm")]
[Description("Returns Success if an upcoming beat containing a tag that starts with 'EnemyAttack' is within the lead time. Otherwise returns Failure.")]
public class RhythmAttackDetector : AutomataConditionalBase
{
[Tooltip("The lead time before the beat in seconds.")]
public float leadTime = 0.1f;
[Tooltip("The prefix of the tag to match.")]
public string tagPrefix = "EnemyAttack";
private MusicBeatSystem _beatSystem;
private BeatMarker _lastTriggeredBeat;
public override void OnAwake()
{
base.OnAwake();
_beatSystem = CombatManager.GetCombatSystem<MusicBeatSystem>();
}
public override void OnStart()
{
_lastTriggeredBeat = null;
}
public override TaskStatus OnUpdate()
{
if (_beatSystem == null || !_beatSystem.IsActive || _beatSystem.CurrentBeatData == null)
{
return TaskStatus.Failure;
}
BeatMarker targetBeat = FindNextMatchingBeat();
if (targetBeat == null)
{
return TaskStatus.Failure;
}
// If we have already triggered for this specific beat, we shouldn't succeed again
if (_lastTriggeredBeat == targetBeat)
{
return TaskStatus.Failure;
}
float timeUntilBeat = targetBeat.time - _beatSystem.CurrentSongTime;
// Check if we are within the lead time window
if (timeUntilBeat <= leadTime)
{
TriggerDetection(targetBeat, timeUntilBeat);
return TaskStatus.Success;
}
return TaskStatus.Failure;
}
private BeatMarker FindNextMatchingBeat()
{
float currentTime = _beatSystem.CurrentSongTime;
var markers = _beatSystem.CurrentBeatData.beatMarkers;
if (markers == null) return null;
for (int i = 0; i < markers.Count; i++)
{
BeatMarker marker = markers[i];
// Check for upcoming beats
if (marker.time > currentTime)
{
if (marker.tags != null)
{
for (int j = 0; j < marker.tags.Count; j++)
{
if (marker.tags[j].StartsWith(tagPrefix))
{
return marker;
}
}
}
}
}
return null;
}
private void TriggerDetection(BeatMarker beat, float timeUntilBeat)
{
_lastTriggeredBeat = beat;
// Log matching tags for identification
string matchedTag = "";
if (beat.tags != null)
{
foreach (string t in beat.tags)
{
if (t.StartsWith(tagPrefix))
{
matchedTag = t;
break;
}
}
}
Debug.Log($"[RhythmAttackDetector] Conditional MET for {self.gameObject.name} at {beat.time:F3}s " +
$"(in {timeUntilBeat:F3}s) with matched tag '{matchedTag}'.");
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6098508c9cb8fea4a9d9d6e5871d0362

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -83,13 +83,13 @@ MonoBehaviour:
intervals:
- intervalType: 10
intervalName:
timeRange: {x: 0, y: 1.2666667}
timeRange: {x: 0, y: 1.3333334}
- intervalType: 11
intervalName:
timeRange: {x: 0, y: 2.1333334}
- intervalType: 20
intervalName:
timeRange: {x: 1.2666667, y: 2.0333333}
timeRange: {x: 1.3333334, y: 2.0333333}
- intervalType: 22
intervalName:
timeRange: {x: 1.7, y: 2.0333333}
@@ -108,11 +108,11 @@ MonoBehaviour:
isEnd: 0
payload:
rid: 7523082033060380672
- triggerTime: 1.3666667
- triggerTime: 1.3333334
isEnd: 0
payload:
rid: 7523082033060380674
- triggerTime: 1.4
- triggerTime: 1.3333334
isEnd: 1
payload:
rid: 7523082033060380673
@@ -126,7 +126,7 @@ MonoBehaviour:
- rid: 7523082033060380672
type: {class: SetBreakthroughResistance, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
data:
eventName:
eventName: AnimSetBreakthroughResistance0
mute: 0
isEnabling: 1
getFromBehaviorTree: 1
@@ -137,7 +137,7 @@ MonoBehaviour:
- rid: 7523082033060380673
type: {class: SetBreakthroughResistance, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
data:
eventName:
eventName: AnimSetBreakthroughResistance1
mute: 0
isEnabling: 0
getFromBehaviorTree: 1
@@ -148,7 +148,7 @@ MonoBehaviour:
- rid: 7523082033060380674
type: {class: InvokePreloadFunction, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
data:
eventName:
eventName: AnimInvokePreloadFunction0
mute: 0
functionKey: GeneratePunch
parameters:

File diff suppressed because it is too large Load Diff

View File

@@ -712,9 +712,18 @@ namespace Cielonos.MainGame.Editor
// Mouse up
if (e.type == EventType.MouseUp)
{
if (currentDragMode == DragMode.MoveBeat && draggingBeatIndex >= 0)
if (currentDragMode == DragMode.MoveBeat && draggingBeatIndex >= 0 && draggingBeatIndex < targetData.beatMarkers.Count)
{
// Snap if close to grid
var draggedMarker = targetData.beatMarkers[draggingBeatIndex];
targetData.SortBeats(); // Keep sorted after drag
// Re-select the dragged marker
int newIndex = targetData.beatMarkers.IndexOf(draggedMarker);
selectedBeatIndex = newIndex;
selectedBeatIndices.Clear();
if (newIndex != -1)
selectedBeatIndices.Add(newIndex);
EditorUtility.SetDirty(targetData);
}
@@ -958,16 +967,39 @@ namespace Cielonos.MainGame.Editor
Undo.RecordObject(targetData, "Snap Beats to Grid");
// Cache the selected markers before sorting changes their indices
List<BeatMarker> selectedMarkers = new List<BeatMarker>();
foreach (int idx in selectedBeatIndices)
{
if (idx < 0 || idx >= targetData.beatMarkers.Count) continue;
var marker = targetData.beatMarkers[idx];
if (idx >= 0 && idx < targetData.beatMarkers.Count)
{
selectedMarkers.Add(targetData.beatMarkers[idx]);
}
}
foreach (var marker in selectedMarkers)
{
float adjustedTime = marker.time - targetData.audioStartOffset;
int nearestBeatNum = Mathf.RoundToInt(adjustedTime / beatInterval);
marker.time = targetData.audioStartOffset + nearestBeatNum * beatInterval;
}
targetData.SortBeats(); // Keep sorted
targetData.RecalculateBarIndices();
// Re-select markers by finding their new indices
selectedBeatIndices.Clear();
selectedBeatIndex = -1;
for (int i = 0; i < targetData.beatMarkers.Count; i++)
{
if (selectedMarkers.Contains(targetData.beatMarkers[i]))
{
selectedBeatIndices.Add(i);
if (selectedBeatIndex == -1)
selectedBeatIndex = i;
}
}
EditorUtility.SetDirty(targetData);
isDirty = true;
}
@@ -1008,6 +1040,7 @@ namespace Cielonos.MainGame.Editor
var marker = new BeatMarker(time, tags);
targetData.beatMarkers.Add(marker);
targetData.SortBeats(); // Keep sorted
// Calculate bar/beat index
float beatInterval = targetData.BeatInterval;
@@ -1019,7 +1052,8 @@ namespace Cielonos.MainGame.Editor
marker.beatInBar = totalBeat % targetData.beatsPerBar;
}
int newIndex = targetData.beatMarkers.Count - 1;
// Find the new index after sorting
int newIndex = targetData.beatMarkers.IndexOf(marker);
selectedBeatIndex = newIndex;
selectedBeatIndices.Clear();
selectedBeatIndices.Add(newIndex);

View File

@@ -40,133 +40,43 @@ MonoBehaviour:
audioStartOffset: 0
totalDuration: 11.676
beatMarkers:
- time: 0
- time: 2.5945945
tags:
- Normal
barIndex: 0
beatInBar: 0
- time: 0.6486486
tags:
- Normal
barIndex: 0
beatInBar: 2
- time: 1.2972972
tags:
- Normal
barIndex: 0
beatInBar: 4
- time: 1.8041672
tags:
- Normal
barIndex: 0
beatInBar: 6
- time: 2.2125
tags:
- Normal
barIndex: 0
beatInBar: 7
- time: 2.6375
tags:
- Normal
- EnemyAttack0
barIndex: 1
beatInBar: 0
- time: 2.9875
- time: 5.189189
tags:
- Normal
barIndex: 1
beatInBar: 1
- time: 3.2432435
tags:
- Normal
barIndex: 1
beatInBar: 2
- time: 3.4958336
tags:
- Normal
barIndex: 1
beatInBar: 3
- time: 3.8918922
tags:
- Normal
barIndex: 1
beatInBar: 4
- time: 4.1625
tags:
- Normal
barIndex: 1
beatInBar: 5
- time: 4.3125
tags:
- Normal
barIndex: 1
beatInBar: 5
- time: 4.5405407
tags:
- Normal
barIndex: 1
beatInBar: 6
- time: 4.7625
tags:
- Normal
barIndex: 1
beatInBar: 7
- time: 5.0625
tags:
- Normal
- EnemyAttack0
barIndex: 2
beatInBar: 0
- time: 7.7837834
tags:
- EnemyAttack0
barIndex: 3
beatInBar: 0
- time: 10.378378
tags:
- EnemyAttack0
barIndex: 4
beatInBar: 0
- time: 2.5945945
tags:
- Normal
barIndex: 1
beatInBar: 0
- time: 5.189189
tags:
- Normal
barIndex: 2
beatInBar: 0
- time: 5.837837
tags:
- Normal
barIndex: 2
beatInBar: 2
- time: 6.4864855
tags:
- Normal
barIndex: 2
beatInBar: 4
- time: 7.1351337
tags:
- Normal
barIndex: 2
beatInBar: 6
- time: 7.783782
- time: 7.7837834
tags:
- Normal
barIndex: 3
beatInBar: 0
- time: 8.432431
tags:
- Normal
barIndex: 3
beatInBar: 2
- time: 9.08108
tags:
- Normal
barIndex: 3
beatInBar: 4
- time: 9.72973
tags:
- Normal
barIndex: 3
beatInBar: 6
- time: 10.378379
- time: 10.378378
tags:
- Normal
barIndex: 4
beatInBar: 0
- time: 11.027028
tags:
- Normal
barIndex: 4
beatInBar: 2
- time: 11.675677
tags:
- Normal
barIndex: 4
beatInBar: 4

View File

@@ -195,6 +195,9 @@ namespace Cielonos.MainGame
Deactivate();
}
// Ensure beat markers are sorted before starting tracking
beatData.SortBeats();
CurrentBeatData = beatData;
CurrentBPM = beatData.bpm;
CurrentSongTime = 0f;