feat(combat): cues de hit react + som punch + camera shake (cliente UE)
3 GameplayCueNotify_Burst BPs (taxonomia Lyra GameplayCue.Zeus.Combat.Hit.*): GC_Combat_Hit_React -> PlayAnimMontage AM_HitReact_Light no alvo GC_Combat_Hit_Impact -> SpawnSoundAtLocation SW_Punch_Cartoon na pos do alvo GC_Combat_Hit_Self -> ClientStartCameraShake CS_HitReact no PC do alvo Assets novos: AS_HitReact (+ AM_HitReact_Light/Medium/Heavy) -- montages de reacao SW_Punch_Cartoon -- SFX de impacto (0.3s) CS_HitReact -- LegacyCameraShake (osc 0.35s, pitch/roll/locZ) DT_Abilities recriado (RowStruct ZeusAbilityDataRow): rows Dash+Kick com AbilityClass + ActivateCueTag GameplayCue.Zeus.*. GC_Kick/GC_Dash com tags renomeadas pro prefixo GameplayCue.* (filter do Asset Picker). ZeusServerTags.ini: regenerado via ZeusTool tags sync (106 tags canonicas). Source/Combat/ZeusAnimNotifyState_BodyHitWindow: AnimNotifyState que abre a janela de hit detection (FootR capsule) durante o swing do Kick. GC_Kick_Target removido (substituido por Combat.Hit.React reutilizavel). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,18 @@
|
||||
; Gerado por ZeusTool tags sync -- tags do ZeusServer p/ o cliente UE.
|
||||
; NAO editar a mao: regenere com `ZeusTool tags sync <json> <ini>`.
|
||||
[/Script/GameplayTags.GameplayTagsList]
|
||||
GameplayTagList=(Tag="GameplayCue",DevComment="")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus",DevComment="")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Melee",DevComment="")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Melee.Kick",DevComment="")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Combat",DevComment="Categoria root de cues compartilhados por TODO melee (reutilizaveis)")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Combat.Hit",DevComment="Familia de cues do impacto de hit")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Combat.Hit.Impact",DevComment="Broadcast AOI - SFX impact + VFX sparks na location (todos ouvem)")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Combat.Hit.React",DevComment="Broadcast AOI - AnimMontage de hit react no target (todos veem)")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Combat.Hit.Self",DevComment="Unicast - feedback privado do alvo (camera shake, hit flash, rumble)")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Melee.Kick.Target",DevComment="")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Movement",DevComment="")
|
||||
GameplayTagList=(Tag="GameplayCue.Zeus.Movement.Dash",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Ability",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Ability.Casting",DevComment="")
|
||||
@@ -24,6 +36,7 @@ GameplayTagList=(Tag="Zeus.Attribute.Dex",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Flee",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Hit",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Hp",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.HpRegenRate",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Int",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.JobExp",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.JobLevel",DevComment="")
|
||||
@@ -36,7 +49,9 @@ GameplayTagList=(Tag="Zeus.Attribute.MaxSp",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Mdef",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.SkillPoint",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Sp",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.SpRegenRate",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Stamina",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.StaminaRegenRate",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.StatusPoint",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Str",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Attribute.Vit",DevComment="")
|
||||
@@ -52,11 +67,6 @@ GameplayTagList=(Tag="Zeus.Combo.Slot3",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Combo.Window",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Cooldown",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Cooldown.FireballRain",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Cue",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Cue.Melee",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Cue.Melee.Kick",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Cue.Movement",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Cue.Movement.Dash",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Damage",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Damage.Earth",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Damage.Fire",DevComment="")
|
||||
@@ -78,6 +88,13 @@ GameplayTagList=(Tag="Zeus.Effect.Cost",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Effect.Cost.Sp_10",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Effect.Cost.Sp_50",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Effect.Cost.Stamina_5",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Effect.Damage",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Effect.Damage.Kick",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.State",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.State.NoHpRegen",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.State.NoRegen",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.State.NoSpRegen",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.State.NoStaminaRegen",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Status",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Status.Buff",DevComment="")
|
||||
GameplayTagList=(Tag="Zeus.Status.CC",DevComment="")
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/ZMMO/GAS/Cues/Camera/CS_HitReact.uasset
Normal file
BIN
Content/ZMMO/GAS/Cues/Camera/CS_HitReact.uasset
Normal file
Binary file not shown.
BIN
Content/ZMMO/GAS/Cues/GC_Combat_Hit_Impact.uasset
Normal file
BIN
Content/ZMMO/GAS/Cues/GC_Combat_Hit_Impact.uasset
Normal file
Binary file not shown.
BIN
Content/ZMMO/GAS/Cues/GC_Combat_Hit_React.uasset
Normal file
BIN
Content/ZMMO/GAS/Cues/GC_Combat_Hit_React.uasset
Normal file
Binary file not shown.
BIN
Content/ZMMO/GAS/Cues/GC_Combat_Hit_Self.uasset
Normal file
BIN
Content/ZMMO/GAS/Cues/GC_Combat_Hit_Self.uasset
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/ZMMO/GAS/Cues/HitReact/AM_HitReact_Heavy.uasset
Normal file
BIN
Content/ZMMO/GAS/Cues/HitReact/AM_HitReact_Heavy.uasset
Normal file
Binary file not shown.
BIN
Content/ZMMO/GAS/Cues/HitReact/AM_HitReact_Light.uasset
Normal file
BIN
Content/ZMMO/GAS/Cues/HitReact/AM_HitReact_Light.uasset
Normal file
Binary file not shown.
BIN
Content/ZMMO/GAS/Cues/HitReact/AM_HitReact_Medium.uasset
Normal file
BIN
Content/ZMMO/GAS/Cues/HitReact/AM_HitReact_Medium.uasset
Normal file
Binary file not shown.
BIN
Content/ZMMO/GAS/Cues/HitReact/Animations/AS_HitReact.uasset
Normal file
BIN
Content/ZMMO/GAS/Cues/HitReact/Animations/AS_HitReact.uasset
Normal file
Binary file not shown.
BIN
Content/ZMMO/Sounds/Combat/SW_Punch_Cartoon.uasset
Normal file
BIN
Content/ZMMO/Sounds/Combat/SW_Punch_Cartoon.uasset
Normal file
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
// Copyright Zeus Server Engine. All rights reserved.
|
||||
|
||||
#include "ZeusAnimNotifyState_BodyHitWindow.h"
|
||||
|
||||
#include "Components/SkeletalMeshComponent.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "Game/Entity/ZeusCharacter.h"
|
||||
|
||||
void UZeusAnimNotifyState_BodyHitWindow::NotifyBegin(USkeletalMeshComponent* MeshComp,
|
||||
UAnimSequenceBase* /*Animation*/, float /*TotalDuration*/,
|
||||
const FAnimNotifyEventReference& /*EventReference*/)
|
||||
{
|
||||
if (!MeshComp) { return; }
|
||||
if (AZeusCharacter* Char = Cast<AZeusCharacter>(MeshComp->GetOwner()))
|
||||
{
|
||||
Char->SetHitColliderEnabled(Source, /*bEnabled*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
void UZeusAnimNotifyState_BodyHitWindow::NotifyEnd(USkeletalMeshComponent* MeshComp,
|
||||
UAnimSequenceBase* /*Animation*/, const FAnimNotifyEventReference& /*EventReference*/)
|
||||
{
|
||||
if (!MeshComp) { return; }
|
||||
if (AZeusCharacter* Char = Cast<AZeusCharacter>(MeshComp->GetOwner()))
|
||||
{
|
||||
Char->SetHitColliderEnabled(Source, /*bEnabled*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
FString UZeusAnimNotifyState_BodyHitWindow::GetNotifyName_Implementation() const
|
||||
{
|
||||
const TCHAR* SourceLabel;
|
||||
switch (Source)
|
||||
{
|
||||
case EZeusHitSource::FootR: SourceLabel = TEXT("FootR"); break;
|
||||
case EZeusHitSource::FootL: SourceLabel = TEXT("FootL"); break;
|
||||
case EZeusHitSource::HandR: SourceLabel = TEXT("HandR"); break;
|
||||
case EZeusHitSource::HandL: SourceLabel = TEXT("HandL"); break;
|
||||
case EZeusHitSource::WeaponR: SourceLabel = TEXT("WeaponR"); break;
|
||||
case EZeusHitSource::WeaponL: SourceLabel = TEXT("WeaponL"); break;
|
||||
default: SourceLabel = TEXT("?"); break;
|
||||
}
|
||||
return FString::Printf(TEXT("Zeus Body Hit (%s)"), SourceLabel);
|
||||
}
|
||||
#endif
|
||||
74
Source/ZMMO/Game/Combat/ZeusAnimNotifyState_BodyHitWindow.h
Normal file
74
Source/ZMMO/Game/Combat/ZeusAnimNotifyState_BodyHitWindow.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright Zeus Server Engine. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Animation/AnimNotifies/AnimNotifyState.h"
|
||||
#include "Game/Entity/ZeusCharacter.h" // EZeusHitSource
|
||||
#include "ZeusAnimNotifyState_BodyHitWindow.generated.h"
|
||||
|
||||
class USkeletalMeshComponent;
|
||||
class UAnimSequenceBase;
|
||||
|
||||
/**
|
||||
* AnimNotifyState que liga o HitCollider de uma parte do corpo durante a sua
|
||||
* janela no montage. NotifyBegin liga + NotifyEnd desliga -- define o HIT
|
||||
* WINDOW do golpe melee/arma branca.
|
||||
*
|
||||
* Generaliza para qualquer parte do corpo via EZeusHitSource:
|
||||
* - FootR / FootL -> chute (capsule attachado em foot_*_Socket)
|
||||
* - HandR / HandL -> soco (capsule em HandGrip_*)
|
||||
* - WeaponR / WeaponL -> arma branca (capsule em weapon_*)
|
||||
*
|
||||
* === Como usar ===
|
||||
*
|
||||
* No editor de um AnimMontage (ex: AM_Kick_Montage):
|
||||
* 1. Encontrar o frame onde o membro comeca o movimento de impacto.
|
||||
* 2. Right-click na track de notifies -> Add Notify State -> Zeus Body Hit Window.
|
||||
* 3. Definir Source = FootR (ou HandR pra soco, WeaponR pra arma, etc).
|
||||
* 4. Arrastar o range pra cobrir o arco completo do golpe (ex: frame 8 a 18
|
||||
* em 30fps = ~330ms de janela).
|
||||
*
|
||||
* Pq AnimNotifyState e nao AnimNotify pontual:
|
||||
* - AnimNotify dispara em UM frame -> nao da' pra detectar entradas no
|
||||
* capsule durante a janela.
|
||||
* - AnimNotifyState tem NotifyBegin/NotifyTick/NotifyEnd. Pra "ligar
|
||||
* collider de frame X ate Y", e' o pattern correto.
|
||||
*
|
||||
* === Replicacao ===
|
||||
*
|
||||
* Roda LOCAL em cada cliente. Cliente do ATIVADOR liga capsule local + reporta
|
||||
* overlap via opcode MELEE_HIT_REPORT pro server. Server valida e aplica dano +
|
||||
* dispatcha cue Kick.Target pra todos no AOI do alvo.
|
||||
*
|
||||
* Proxies de outros clientes tocam o montage via GameplayCue replicado (visual)
|
||||
* mas o capsule deles roda no PROXY que e' Pawn local de outra coisa -- nao
|
||||
* importa, o reportador autoritativo eh quem ativou a ability.
|
||||
*/
|
||||
UCLASS(meta = (DisplayName = "Zeus Body Hit Window"))
|
||||
class ZMMO_API UZeusAnimNotifyState_BodyHitWindow : public UAnimNotifyState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/// Qual parte do corpo (capsule) tem o hit ligado durante a janela.
|
||||
/// Default = FootR (chute direito e' o golpe mais comum em montages
|
||||
/// melee unarmed). Trocar pra HandR pra soco, WeaponR pra arma, etc.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|Combat")
|
||||
EZeusHitSource Source = EZeusHitSource::FootR;
|
||||
|
||||
// === AnimNotifyState overrides ===
|
||||
|
||||
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
|
||||
float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
|
||||
|
||||
virtual void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
|
||||
const FAnimNotifyEventReference& EventReference) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
/// Mostra "Zeus Body Hit (FootR/HandL/WeaponR/...)" no editor de montage em
|
||||
/// vez do nome generico da classe -- ajuda a identificar qual parte sem
|
||||
/// abrir details.
|
||||
virtual FString GetNotifyName_Implementation() const override;
|
||||
#endif
|
||||
};
|
||||
Reference in New Issue
Block a user