IFD敌人初步
This commit is contained in:
@@ -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}'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6098508c9cb8fea4a9d9d6e5871d0362
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cc81acfab8ad50b4c83830b03bcc2c9f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
10265
Assets/Prefabs/MainGame/Characters/Automata/IFD1_Test/IFD1_Test.prefab
Normal file
10265
Assets/Prefabs/MainGame/Characters/Automata/IFD1_Test/IFD1_Test.prefab
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ce47cab4037a84341806935fc84af6f5
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -83,13 +83,13 @@ MonoBehaviour:
|
|||||||
intervals:
|
intervals:
|
||||||
- intervalType: 10
|
- intervalType: 10
|
||||||
intervalName:
|
intervalName:
|
||||||
timeRange: {x: 0, y: 1.2666667}
|
timeRange: {x: 0, y: 1.3333334}
|
||||||
- intervalType: 11
|
- intervalType: 11
|
||||||
intervalName:
|
intervalName:
|
||||||
timeRange: {x: 0, y: 2.1333334}
|
timeRange: {x: 0, y: 2.1333334}
|
||||||
- intervalType: 20
|
- intervalType: 20
|
||||||
intervalName:
|
intervalName:
|
||||||
timeRange: {x: 1.2666667, y: 2.0333333}
|
timeRange: {x: 1.3333334, y: 2.0333333}
|
||||||
- intervalType: 22
|
- intervalType: 22
|
||||||
intervalName:
|
intervalName:
|
||||||
timeRange: {x: 1.7, y: 2.0333333}
|
timeRange: {x: 1.7, y: 2.0333333}
|
||||||
@@ -108,11 +108,11 @@ MonoBehaviour:
|
|||||||
isEnd: 0
|
isEnd: 0
|
||||||
payload:
|
payload:
|
||||||
rid: 7523082033060380672
|
rid: 7523082033060380672
|
||||||
- triggerTime: 1.3666667
|
- triggerTime: 1.3333334
|
||||||
isEnd: 0
|
isEnd: 0
|
||||||
payload:
|
payload:
|
||||||
rid: 7523082033060380674
|
rid: 7523082033060380674
|
||||||
- triggerTime: 1.4
|
- triggerTime: 1.3333334
|
||||||
isEnd: 1
|
isEnd: 1
|
||||||
payload:
|
payload:
|
||||||
rid: 7523082033060380673
|
rid: 7523082033060380673
|
||||||
@@ -126,7 +126,7 @@ MonoBehaviour:
|
|||||||
- rid: 7523082033060380672
|
- rid: 7523082033060380672
|
||||||
type: {class: SetBreakthroughResistance, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
|
type: {class: SetBreakthroughResistance, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
|
||||||
data:
|
data:
|
||||||
eventName:
|
eventName: AnimSetBreakthroughResistance0
|
||||||
mute: 0
|
mute: 0
|
||||||
isEnabling: 1
|
isEnabling: 1
|
||||||
getFromBehaviorTree: 1
|
getFromBehaviorTree: 1
|
||||||
@@ -137,7 +137,7 @@ MonoBehaviour:
|
|||||||
- rid: 7523082033060380673
|
- rid: 7523082033060380673
|
||||||
type: {class: SetBreakthroughResistance, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
|
type: {class: SetBreakthroughResistance, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
|
||||||
data:
|
data:
|
||||||
eventName:
|
eventName: AnimSetBreakthroughResistance1
|
||||||
mute: 0
|
mute: 0
|
||||||
isEnabling: 0
|
isEnabling: 0
|
||||||
getFromBehaviorTree: 1
|
getFromBehaviorTree: 1
|
||||||
@@ -148,7 +148,7 @@ MonoBehaviour:
|
|||||||
- rid: 7523082033060380674
|
- rid: 7523082033060380674
|
||||||
type: {class: InvokePreloadFunction, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
|
type: {class: InvokePreloadFunction, ns: Cielonos.MainGame.FunctionalAnimation, asm: Assembly-CSharp}
|
||||||
data:
|
data:
|
||||||
eventName:
|
eventName: AnimInvokePreloadFunction0
|
||||||
mute: 0
|
mute: 0
|
||||||
functionKey: GeneratePunch
|
functionKey: GeneratePunch
|
||||||
parameters:
|
parameters:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -712,9 +712,18 @@ namespace Cielonos.MainGame.Editor
|
|||||||
// Mouse up
|
// Mouse up
|
||||||
if (e.type == EventType.MouseUp)
|
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);
|
EditorUtility.SetDirty(targetData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -958,16 +967,39 @@ namespace Cielonos.MainGame.Editor
|
|||||||
|
|
||||||
Undo.RecordObject(targetData, "Snap Beats to Grid");
|
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)
|
foreach (int idx in selectedBeatIndices)
|
||||||
{
|
{
|
||||||
if (idx < 0 || idx >= targetData.beatMarkers.Count) continue;
|
if (idx >= 0 && idx < targetData.beatMarkers.Count)
|
||||||
var marker = targetData.beatMarkers[idx];
|
{
|
||||||
|
selectedMarkers.Add(targetData.beatMarkers[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var marker in selectedMarkers)
|
||||||
|
{
|
||||||
float adjustedTime = marker.time - targetData.audioStartOffset;
|
float adjustedTime = marker.time - targetData.audioStartOffset;
|
||||||
int nearestBeatNum = Mathf.RoundToInt(adjustedTime / beatInterval);
|
int nearestBeatNum = Mathf.RoundToInt(adjustedTime / beatInterval);
|
||||||
marker.time = targetData.audioStartOffset + nearestBeatNum * beatInterval;
|
marker.time = targetData.audioStartOffset + nearestBeatNum * beatInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetData.SortBeats(); // Keep sorted
|
||||||
targetData.RecalculateBarIndices();
|
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);
|
EditorUtility.SetDirty(targetData);
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
}
|
}
|
||||||
@@ -1008,6 +1040,7 @@ namespace Cielonos.MainGame.Editor
|
|||||||
|
|
||||||
var marker = new BeatMarker(time, tags);
|
var marker = new BeatMarker(time, tags);
|
||||||
targetData.beatMarkers.Add(marker);
|
targetData.beatMarkers.Add(marker);
|
||||||
|
targetData.SortBeats(); // Keep sorted
|
||||||
|
|
||||||
// Calculate bar/beat index
|
// Calculate bar/beat index
|
||||||
float beatInterval = targetData.BeatInterval;
|
float beatInterval = targetData.BeatInterval;
|
||||||
@@ -1019,7 +1052,8 @@ namespace Cielonos.MainGame.Editor
|
|||||||
marker.beatInBar = totalBeat % targetData.beatsPerBar;
|
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;
|
selectedBeatIndex = newIndex;
|
||||||
selectedBeatIndices.Clear();
|
selectedBeatIndices.Clear();
|
||||||
selectedBeatIndices.Add(newIndex);
|
selectedBeatIndices.Add(newIndex);
|
||||||
|
|||||||
@@ -40,133 +40,43 @@ MonoBehaviour:
|
|||||||
audioStartOffset: 0
|
audioStartOffset: 0
|
||||||
totalDuration: 11.676
|
totalDuration: 11.676
|
||||||
beatMarkers:
|
beatMarkers:
|
||||||
- time: 0
|
- time: 2.5945945
|
||||||
tags:
|
tags:
|
||||||
- Normal
|
- EnemyAttack0
|
||||||
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
|
|
||||||
barIndex: 1
|
barIndex: 1
|
||||||
beatInBar: 0
|
beatInBar: 0
|
||||||
- time: 2.9875
|
- time: 5.189189
|
||||||
tags:
|
tags:
|
||||||
- Normal
|
- EnemyAttack0
|
||||||
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
|
|
||||||
barIndex: 2
|
barIndex: 2
|
||||||
beatInBar: 0
|
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
|
- time: 5.189189
|
||||||
tags:
|
tags:
|
||||||
- Normal
|
- Normal
|
||||||
barIndex: 2
|
barIndex: 2
|
||||||
beatInBar: 0
|
beatInBar: 0
|
||||||
- time: 5.837837
|
- time: 7.7837834
|
||||||
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
|
|
||||||
tags:
|
tags:
|
||||||
- Normal
|
- Normal
|
||||||
barIndex: 3
|
barIndex: 3
|
||||||
beatInBar: 0
|
beatInBar: 0
|
||||||
- time: 8.432431
|
- time: 10.378378
|
||||||
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
|
|
||||||
tags:
|
tags:
|
||||||
- Normal
|
- Normal
|
||||||
barIndex: 4
|
barIndex: 4
|
||||||
beatInBar: 0
|
beatInBar: 0
|
||||||
- time: 11.027028
|
|
||||||
tags:
|
|
||||||
- Normal
|
|
||||||
barIndex: 4
|
|
||||||
beatInBar: 2
|
|
||||||
- time: 11.675677
|
|
||||||
tags:
|
|
||||||
- Normal
|
|
||||||
barIndex: 4
|
|
||||||
beatInBar: 4
|
|
||||||
|
|||||||
@@ -195,6 +195,9 @@ namespace Cielonos.MainGame
|
|||||||
Deactivate();
|
Deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure beat markers are sorted before starting tracking
|
||||||
|
beatData.SortBeats();
|
||||||
|
|
||||||
CurrentBeatData = beatData;
|
CurrentBeatData = beatData;
|
||||||
CurrentBPM = beatData.bpm;
|
CurrentBPM = beatData.bpm;
|
||||||
CurrentSongTime = 0f;
|
CurrentSongTime = 0f;
|
||||||
|
|||||||
Reference in New Issue
Block a user