From c221c26a23f7e7e822845e0ade59cd035dead3bc Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 19 Aug 2026 19:37:59 +0200 Subject: [PATCH] Weiter Ingame an den animationen gepfeilt --- .../main/resources/Characters/Models/hero.j3o | Bin 26097672 -> 26097672 bytes .../main/resources/Characters/hero.character | 32 +++++------ .../main/java/de/blight/editor/EditorApp.java | 51 +++++++----------- .../game/animation/AnimationLibrary.java | 41 +++++--------- .../game/control/PlayerInputControl.java | 3 +- .../game/navigation/CharacterNavigator.java | 6 +++ 6 files changed, 52 insertions(+), 81 deletions(-) diff --git a/blight-assets/src/main/resources/Characters/Models/hero.j3o b/blight-assets/src/main/resources/Characters/Models/hero.j3o index ba61881d2047087a947dc556eddfb5072d9dd0c4..4829c05a8d0a6040e47749e35c67704d300bded7 100644 GIT binary patch delta 23860 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 delta 23731 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 aO2af7rqeKkhM6?XqG2}6z_p0=SowdkUfL!A diff --git a/blight-assets/src/main/resources/Characters/hero.character b/blight-assets/src/main/resources/Characters/hero.character index 12c68ab..cf321b6 100644 --- a/blight-assets/src/main/resources/Characters/hero.character +++ b/blight-assets/src/main/resources/Characters/hero.character @@ -2,35 +2,27 @@ "chapter": 0, "level": 0, "xp": 0, - "currentHp": 100, - "currentStamina": 100, - "currentMana": 100, - "maxHp": 100, - "maxStamina": 100, - "maxMana": 100, + "currentHp": 0, + "currentStamina": 0, + "currentMana": 0, + "maxHp": 0, + "maxStamina": 0, + "maxMana": 0, "openHpRegeneration": 0, "openManaRegeneration": 0, "openStaminaRegeneration": 0, "restorationValue": 10, - "abilities": { - "lvlMagic": 1, - "lvlStaffCombat": 1, - "lvlSwordsmanship": 1, - "lvlArchery": 1, - "lvlHeavyWeapons": 1, - "lvlCrossbow": 1, - "lvlThievery": 0, - "lvlAlchemy": 0, - "lvlEngineering": 0, - "lvlSmithery": 0, - "lvlEnchanting": 0 - }, + "playedMonologueIds": [], + "firedTriggerIds": [], + "visitedZoneIds": [], + "gameVariables": {}, + "memberFractionIds": [], "listeners": [], "characterId": "hero", "name": { "id": "hero.name" }, - "modelPath": "Models/Chars/mainchar.j3o", + "modelPath": "Characters/Models/hero.j3o", "animSetPath": "human", "type": "MAIN_CHARACTER" } \ No newline at end of file diff --git a/blight-editor/src/main/java/de/blight/editor/EditorApp.java b/blight-editor/src/main/java/de/blight/editor/EditorApp.java index 63c3fcd..7365b7b 100644 --- a/blight-editor/src/main/java/de/blight/editor/EditorApp.java +++ b/blight-editor/src/main/java/de/blight/editor/EditorApp.java @@ -11410,6 +11410,11 @@ public class EditorApp extends Application { saveCurrentAnimSet(animSetCurrentName, animSetCurrentDir); } + private void autoSaveCharacter() { + if (charIdField == null || charIdField.getText().trim().isBlank()) return; + saveCharacter(ASSET_ROOT.resolve("Characters")); + } + private void saveCurrentAnimSet(String setName, Path setDir) { if (animSetClipListView == null) { return; @@ -12037,16 +12042,6 @@ public class EditorApp extends Application { VBox inner = new VBox(8); inner.setPadding(new Insets(10)); - Button newCharBtn = new Button("Neuer Charakter"); - newCharBtn.setMaxWidth(Double.MAX_VALUE); - newCharBtn.setOnAction(e -> clearCharacterForm()); - - Button importCharModelBtn = new Button("Character-Modell importieren (FBX)…"); - importCharModelBtn.setMaxWidth(Double.MAX_VALUE); - importCharModelBtn.setStyle("-fx-font-weight: bold;"); - importCharModelBtn.setOnAction(e -> handleCharacterModelImport(importCharModelBtn.getScene().getWindow())); - - inner.getChildren().addAll(newCharBtn, importCharModelBtn); charEditorStatusLabel = new Label("Wähle einen Character im Baum oder erstelle einen neuen"); charEditorStatusLabel.setWrapText(true); @@ -12097,18 +12092,6 @@ public class EditorApp extends Application { refreshCharAnimSetCombo(); charAnimSetCombo.setOnAction(e -> updateCharActionCombosFromSet()); - Button stripClipsBtn = new Button("Eingebettete Clips löschen"); - stripClipsBtn.setMaxWidth(Double.MAX_VALUE); - stripClipsBtn.setDisable(true); - charModelCombo.valueProperty().addListener((obs, ov, nv) -> - stripClipsBtn.setDisable(nv == null || nv.isBlank())); - stripClipsBtn.setOnAction(e -> { - String modelPath = charModelCombo.getValue(); - if (modelPath == null || modelPath.isBlank()) return; - if (charEditorStatusLabel != null) - charEditorStatusLabel.setText("Entferne eingebettete Clips…"); - input.animStripClipsRequest.set(modelPath); - }); charEditContainer.getChildren().addAll( dl.apply("ID:"), charIdField, @@ -12202,8 +12185,7 @@ public class EditorApp extends Application { charEditContainer.getChildren().add(charNpcSection); charEditContainer.getChildren().addAll( dl.apply("Modell:"), charModelCombo, - dl.apply("Anim-Set:"), charAnimSetCombo, - stripClipsBtn + dl.apply("Anim-Set:"), charAnimSetCombo ); // ── Aktions-Zuweisung ───────────────────────────────────────────────── @@ -12214,13 +12196,20 @@ public class EditorApp extends Application { charActionLabelsBox.getChildren().add(actionHint); charEditContainer.getChildren().add(charActionLabelsBox); - // ── Speichern ───────────────────────────────────────────────────────── - charEditContainer.getChildren().add(new Separator()); - Button saveCharBtn = new Button("Charakter speichern"); - saveCharBtn.setMaxWidth(Double.MAX_VALUE); - saveCharBtn.setStyle("-fx-font-weight:bold;-fx-background-color:#3a7a3a;-fx-text-fill:white;"); - saveCharBtn.setOnAction(e -> saveCharacter(charDir)); - charEditContainer.getChildren().add(saveCharBtn); + // ── Auto-Save-Listener ──────────────────────────────────────────────── + charIdField.focusedProperty().addListener((obs, ov, nv) -> { if (!nv) autoSaveCharacter(); }); + charTypeCombo.valueProperty().addListener((obs, ov, nv) -> autoSaveCharacter()); + charModelCombo.valueProperty().addListener((obs, ov, nv) -> autoSaveCharacter()); + charAnimSetCombo.valueProperty().addListener((obs, ov, nv) -> autoSaveCharacter()); + charFractionCombo.valueProperty().addListener((obs, ov, nv) -> autoSaveCharacter()); + charStatusCombo.valueProperty().addListener((obs, ov, nv) -> autoSaveCharacter()); + charTraderCheck.selectedProperty().addListener((obs, ov, nv) -> autoSaveCharacter()); + charTraderItemsView.getItems().addListener( + (javafx.collections.ListChangeListener) c -> autoSaveCharacter()); + charMsgFriendly.focusedProperty().addListener((obs, ov, nv) -> { if (!nv) autoSaveCharacter(); }); + charMsgNeutral.focusedProperty().addListener((obs, ov, nv) -> { if (!nv) autoSaveCharacter(); }); + charMsgEnraged.focusedProperty().addListener((obs, ov, nv) -> { if (!nv) autoSaveCharacter(); }); + charMsgEnemy.focusedProperty().addListener((obs, ov, nv) -> { if (!nv) autoSaveCharacter(); }); inner.getChildren().add(charEditContainer); diff --git a/blight-game/src/main/java/de/blight/game/animation/AnimationLibrary.java b/blight-game/src/main/java/de/blight/game/animation/AnimationLibrary.java index 5673c72..44a78d6 100644 --- a/blight-game/src/main/java/de/blight/game/animation/AnimationLibrary.java +++ b/blight-game/src/main/java/de/blight/game/animation/AnimationLibrary.java @@ -336,21 +336,14 @@ public class AnimationLibrary extends BaseAppState { return null; } - // Clips mit Vorwärts-Root-Motion in Local-Y (rennen, gehen, springen): - // Y wird auf 0 eingefroren → kein Drift. Alle anderen Clips: Y bleibt frei (Hinsetzen usw.) - private static final java.util.Set LOCOMOTION_CLIPS = java.util.Set.of( - "running", "walking", "sprinting", "running_jump" - ); - /** * Entfernt Root-Motion aus dem flachsten Bone mit Translation-Track (typischerweise Hips). * Nur dieser eine Bone wird modifiziert — alle anderen Bones bleiben unverändert. * - * In diesen Mixamo-Exporten ist die Achsenbelegung des Hips-Bones: - * Local X → seitlich → wird auf 0 eingefroren (kein Seiten-Drift) - * Local Y → vorwärts → wird auf 0 eingefroren für Lauf-Clips (kein Vorwärts-Drift) - * bleibt frei für Sitz/Stand-Clips (leichte Neigungsbewegung) - * Local Z → Höhe → IMMER frei lassen (Charakter-Höhe und Setz-Bewegung erhalten) + * Achsenbelegung dieses Mixamo-Exports im Hips-Bone-Local-Space: + * Local X → JME3-X (seitlich) → wird auf 0 eingefroren + * Local Y → JME3-Y (Höhe oben) → IMMER frei lassen (Charakter-Höhe erhalten) + * Local Z → JME3-Z (vorwärts) → wird auf 0 eingefroren (alle Clips auf der Stelle) */ @SuppressWarnings("rawtypes") public static AnimClip snapRootBoneXZ(AnimClip clip, Armature armature) { @@ -367,8 +360,6 @@ public class AnimationLibrary extends BaseAppState { } if (minDepth == Integer.MAX_VALUE) return clip; - boolean isLocomotion = LOCOMOTION_CLIPS.contains(clip.getName().toLowerCase(java.util.Locale.ROOT)); - List> newTracks = new ArrayList<>(); boolean modified = false; for (AnimTrack track : clip.getTracks()) { @@ -383,11 +374,6 @@ public class AnimationLibrary extends BaseAppState { continue; } - // Y-Normalisierung für Nicht-Lauf-Clips: Frame-0 auf Bind-Pose-Y - float bindY = j.getInitialTransform().getTranslation().y; - float frame0Y = translations[0].y; - float yOffset = bindY - frame0Y; - // Diagnostik float yMin = Float.MAX_VALUE, yMax = -Float.MAX_VALUE; float xRange = 0, zRange = 0; @@ -397,21 +383,18 @@ public class AnimationLibrary extends BaseAppState { xRange = Math.max(xRange, Math.abs(t.x - translations[0].x)); zRange = Math.max(zRange, Math.abs(t.z - translations[0].z)); } - log.info("[AnimLib] snap '{}' root='{}' locomotion={} bindY={} frame0Y={} yOffset={} yRange={} xRange={} zRange={}", - clip.getName(), j.getName(), isLocomotion, - String.format("%.3f", bindY), String.format("%.3f", frame0Y), - String.format("%.3f", yOffset), String.format("%.3f", yMax - yMin), - String.format("%.3f", xRange), String.format("%.3f", zRange)); + log.info("[AnimLib] snap '{}' root='{}' xRange={} yRange={} zRange={}", + clip.getName(), j.getName(), + String.format("%.3f", xRange), + String.format("%.3f", yMax - yMin), + String.format("%.3f", zRange)); Vector3f[] snapped = new Vector3f[translations.length]; for (int i = 0; i < translations.length; i++) { - float newY = isLocomotion - ? 0f // Lauf-Clips: Y einfrieren (Vorwärts-Drift weg) - : (translations[i].y + yOffset); // Rest: Y normalisiert (Neigung erhalten) snapped[i] = new Vector3f( - 0f, // X immer 0 (Seiten-Drift weg) - newY, - translations[i].z // Z immer frei (Höhe und Setz-Bewegung erhalten) + 0f, // X = 0 (kein seitlicher Drift) + translations[i].y, // Y frei (Höhe; Y=oben in bone-local / JME3-Y) + 0f // Z = 0 (kein Vorwärts-Drift; Z=vorwärts in bone-local) ); } newTracks.add(new TransformTrack(j, tt.getTimes(), snapped, tt.getRotations(), tt.getScales())); diff --git a/blight-game/src/main/java/de/blight/game/control/PlayerInputControl.java b/blight-game/src/main/java/de/blight/game/control/PlayerInputControl.java index 2d9259c..3e13a8a 100644 --- a/blight-game/src/main/java/de/blight/game/control/PlayerInputControl.java +++ b/blight-game/src/main/java/de/blight/game/control/PlayerInputControl.java @@ -168,7 +168,7 @@ public class PlayerInputControl { visualBaseTranslation = visual.getLocalTranslation().clone(); } try { - AnimSet as = AnimSet.load(assetRoot.resolve("animations/sets"), animSetName); + AnimSet as = AnimSet.load(assetRoot.resolve("Characters").resolve("sets"), animSetName); animOffsets = as.getAnimOffsets(); log.info("[AnimCtx] {} Anim-Offset-Einträge geladen.", animOffsets.size()); } catch (Exception e) { @@ -629,6 +629,7 @@ public class PlayerInputControl { } String clip = AnimationLibrary.getClipForAction(assetRoot, animSetName, action); log.info("[Anim] {} → clip='{}' (set={})", action, clip, animSetName); + if (runningClip != null) nextTransitionLength = 0.15; if (clip != null && tryPlay(clip)) return; if (action != AnimationAction.DEFAULT) { String defClip = AnimationLibrary.getClipForAction(assetRoot, animSetName, AnimationAction.DEFAULT); diff --git a/blight-game/src/main/java/de/blight/game/navigation/CharacterNavigator.java b/blight-game/src/main/java/de/blight/game/navigation/CharacterNavigator.java index ae282d3..2067bb1 100644 --- a/blight-game/src/main/java/de/blight/game/navigation/CharacterNavigator.java +++ b/blight-game/src/main/java/de/blight/game/navigation/CharacterNavigator.java @@ -277,6 +277,12 @@ public class CharacterNavigator { } if (clip == null) return; if (!animLib.applyTo(clip, visual)) return; + if (currentAnim != null) { + com.jme3.anim.tween.action.Action nextAction = animComposer.action(clip); + if (nextAction instanceof com.jme3.anim.tween.action.BlendableAction ba) { + ba.setTransitionLength(0.15); + } + } com.jme3.anim.tween.action.Action act = animComposer.setCurrentAction(clip); if (act == null) return; if (skinningControl != null && !skinningControl.isEnabled()) {