UE4 action game example RPG Action analysis three: achieving effects, three-hit Combo, ray detection, displaying health bars, fireball

1. Three consecutive combos

To achieve three weapon combos, the requirements are:

1. The next combo can be randomly selected.

2. The input can only be detected again at a certain time.

3. Wait for the current segment to finish playing before playing the next segment.

1.1. Montage settings

By right-clicking - New Montage Clip, create three clips in the montage, and remove the relevant connections, so that only the first clip will be played by default.

Drag different clips to play animations from the Asset Browser.

1.2. Create JumpSection animation notification class

Overload NotifyBegin and NotifyEnd methods

NotifyBegin sets a bool variable to enable detection of attack input

NotifyEnd sets the bool variable to false and turns off detection of attack input

Create an array for editing the optional name of the Combo in the next section

1.3. Detect input during the attack to achieve combos

The main function montage sets the next clip. If you want to jump immediately, you can also set the montage to move to the clip.

target is the current animation instance

Section Name to Change is the currently playing section

Next Section is the segment to jump to

Montage is the currently active montage

At this point, the three-click function is completed.

2. Radiographic detection to obtain targets

2.1. Create a sphere ray detection TargetType

BlueprintNativeEvent means that it hopes to be overloaded in the blueprint. After this setting, the Event in the blueprint will be called first. If the Event in the blueprint does not have a method body, the C++ method _Implementation will be called.

/** Called to determine targets to apply gameplay effects to */
	UFUNCTION(BlueprintNativeEvent)
	void GetTargets(ARPGCharacterBase* TargetingCharacter, AActor* TargetingActor, FGameplayEventData EventData,
		TArray<FHitResult>& OutHitResults, TArray<AActor*>& OutActors) const;

Main Method: Multisphere Detection of Objects

Notice! ! !

UCLASS(Blueprintable, meta = (ShowWorldContextPin))
class ACTIONRPG_API URPGTargetType : public UObject

After adding ShowWorldContextPin, for the RPGTargetType blueprint that inherits UObject, in order to display the object's multi-box detection and other methods, you need to specify the WorldContextOject object.

Start: initial position, add an OffsetFromActor vector

End: End position Actor forward vector, add a length variable

SphereRadius, detection radius

ObjectTypes :

DrawDebug can draw detection boxes

According to the detection results, the hit result information list is obtained as the return value, and it is judged whether the Hit Actor is valid.

2.2. Montage creates Send EventTag animation notification event

Send EventTag, Payload data is empty

Montage Add the animation notification event and edit the EventTag

Through analysis, it can be seen that GameplayEffects is added to the GameplayAbility of the Player attack, so that after receiving the EventTag, the target will be obtained according to the TargetType, and then the corresponding TargetGameplayEffect effect will be applied.

2.3. The results are as follows

The third stage of the attack creates a capsule collision box. Green means the target is detected.

3. AttributeSet

3.1. Introduction to Attribute Set:

PreAttributeChange: Called before any attribute changes, usually used to impose rules on values.

PostGameplayEffectExecute: It will be called after any GameplayEffect that affects Attribute is executed. It is usually used to clamp the value and trigger events in the game.

Original link:GAS - Gameplay Attributes

Attribute
Attribute records Actor numerical information. The type is FGameplayAttributeData (currently float). Common attributes include blood volume, mana volume, attack power, movement speed, etc. Gameplay Effect is usually used to act on Attribute and modify the attribute value.
Gameplay Attribute can be said to be the data core of this system. The purpose of using GAS is to change the numerical attributes and status of the Actor (the status is usually a binary number Yes or No, using Gameplay Tag). Design skills are also based on the attributes possessed by Actors.


Attribute Set
Define and Configure attribute
How to add attributes to Actor? The AttributeSet class is used here. As the name suggests, the attribute set class. The float defined in this class (marked by UPROPERTY) is Attribute.

 



RPGAttributeSet,h

Health, MaxHealth, and Mana in the above picture are all attributes. Of course, there are also some functions and macro definitions. Their functions will be detailed later.
After creating your own AttributeSet class, you must use AbilitySystemComponent to register it. There are two ways to implement it:
1. Set it as the SubObject of the Actor that owns the AbilitySystemComponent.

 



RPGCharacterBase.h


In the constructor:
 



RPGCharacterBase.cpp


2. Pass the class to the GetOrCreateAttributeSubobject function of Ability System Component.
 



AbilitySystemComponent.cpp


Related response function (I don’t know how to call it, let’s call it this for now)
When the attribute value changes, Or when casting GameplayEffect, we want to do some processing. At this time, we need the response function provided by the system to operate. For example, in ActionRPG, two functions are implemented:
 



RPGAttributeSet.h


Interruption: Writing override is a good habit! ! !
The main response functions are:

  • PreAttributeBaseChange
  • PreAttributeChange
  • PreGameplayEffectExecute
  • PostGameplayEffectExecute

I would like to mention here the difference between Base value and (Current) value. Base value is permanently modified, while value is temporarily stored. This should be related to the network. GAS supports client rollback.
Description of each function:
Attention! ! Only modifiers and Setter can be used to change the attribute value (current value), which should also serve synchronization
PreAttributeBaseChange: called before the base value is modified. Because it is a permanent modification, the use of temporary modifiers is not allowed (modifiers are also a class. Usually, GameplayEffect is used to modify properties, which defines basic modifiers and can be expanded by yourself) and should not be used in game logic. Clamp is mostly used for numerical values.
PreAttributeChange: Same as above, except that temporary modifiers can be used here. Example:

 



RPGAttributeSet.cpp

PreGameplayEffectExecute, PostGameplayEffectExecute: As the name suggests, it will be called before and after the skill is released.
 



Official description


Replication (network)
You need to add ReplicatedUsing = OnRep_MyAttribute in UPROPERTY, and set LiftTime in the GetLifetimeReplicatedProps function, so in the end it will Become like this.

 


 



This is the case in ActionRPG, but the settings of LifeTime are different. If the above picture is correct, an error may occur when ActionRPG is set online.

 



RPGAttributeSet.cpp

Related macros (Macro)
In the previous response function implementation, we found that we need to use many Get functions to obtain attributes Or attribute value. Fortunately, the engine has macros ready for us.

 



AttributeSet.h

Data-driven
You can use a data table to initialize your AttributeSet.

 

3.2. RPGAction Health attribute analysis

3.2.1 Define a Health attribute and a MaxHealth attribute:

// Uses macros from AttributeSet.h
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
	GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)

/**
 * 
 */
UCLASS()
class ACTIONRPGCOPY_API URPGAttributeSet : public UAttributeSet
{
	GENERATED_BODY()
	
public:

	URPGAttributeSet();
	virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
	virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;

	/** Current Health, when 0 we expect owner to die. Capped by MaxHealth */
	UPROPERTY(BlueprintReadOnly, Category = "Health")
	FGameplayAttributeData Health;
	ATTRIBUTE_ACCESSORS(URPGAttributeSet, Health)

	/** MaxHealth is its own attribute, since GameplayEffects may modify it */
	UPROPERTY(BlueprintReadOnly, Category = "Health")
	FGameplayAttributeData MaxHealth;
	ATTRIBUTE_ACCESSORS(URPGAttributeSet, MaxHealth)
};

3.2.2 PreAttributeChange: Called before any attribute changes, usually used to impose rules on values.

RPGAction adds a function AdjustAttributeForMaxChange , its function is to change the current value proportionally when the maximum value of the attribute changes.

void URPGAttributeSet::AdjustAttributeForMaxChange(FGameplayAttributeData& AffectedAttribute, const FGameplayAttributeData& MaxAttribute, float NewMaxValue, const FGameplayAttribute& AffectedAttributeProperty)
{
//获得UAbilitySystemComponent实例
    UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();、
//Getter方法获取的都是current value而不是base value
    const float CurrentMaxValue = MaxAttribute.GetCurrentValue();
    if (!FMath::IsNearlyEqual(CurrentMaxValue, NewMaxValue) && AbilityComp)
    {
        // Change current value to maintain the current Val / Max percent
        const float CurrentValue = AffectedAttribute.GetCurrentValue();
        float NewDelta = (CurrentMaxValue > 0.f) ? (CurrentValue * NewMaxValue / CurrentMaxValue) - CurrentValue : NewMaxValue;
                //      通过UAbilitySystemComponent实例
        AbilityComp->ApplyModToAttributeUnsafe(AffectedAttributeProperty, EGameplayModOp::Additive, NewDelta);
    }
}


We should note that the modification of the attribute value is achieved by calling the GameplayAbilityComponent's ApplyModToAttributeUnsafe method.

3.2.3 PostGameplayEffectExecute: It will be called after any GameplayEffect that affects Attribute is executed. It is usually used to clamp the value and trigger events in the game.

void URPGAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
	Super::PostGameplayEffectExecute(Data);

//GameplayEffectContext结构体存有关于GameplayEffectSpec创建者(Instigator)和TargetData的信息
	FGameplayEffectContextHandle Context = Data.EffectSpec.GetContext();
	UAbilitySystemComponent* Source = Context.GetOriginalInstigatorAbilitySystemComponent();
	const FGameplayTagContainer& SourceTags = *Data.EffectSpec.CapturedSourceTags.GetAggregatedTags();

	float DeltaValue = 0;
	if (Data.EvaluatedData.ModifierOp == EGameplayModOp::Type::Additive)
	{
		DeltaValue = Data.EvaluatedData.Magnitude;
	}

	AActor* TargetActor = nullptr;
	ARPGCharacterBase* TargetCharacter = nullptr;
	if (Data.Target.AbilityActorInfo.IsValid() && Data.Target.AbilityActorInfo->AvatarActor.IsValid())
	{
		TargetActor = Data.Target.AbilityActorInfo->AvatarActor.Get();
		TargetCharacter = Cast<ARPGCharacterBase>(TargetActor);
	}

	if (Data.EvaluatedData.Attribute == GetHealthAttribute())
	{
		SetHealth(FMath::Clamp(GetHealth(),0.0f,GetMaxHealth()));

		if (TargetCharacter)
		{
			TargetCharacter->HandleHealthChanged(DeltaValue,SourceTags);
		}
	}
}

4. Create a health bar

4.1. Create a health bar UI

1.1 Create a control blueprint as follows. The size can be adjusted in the lower right corner.

Add a progress bar

1.2 In the chart layer, add the SetProgress method, the input parameter is float type, and set the percentage

1.3 Drag the control blueprint into the BP_EnemyCharacter object and adjust it to the appropriate position

Set the control class to the health bar control just created

Space set to screen type

4.2. Get the enemy’s health percentage

In the previous section, a function OnHealthChanged was created in BP_CharacterBase

	UFUNCTION(BlueprintImplementableEvent)
	void OnHealthChanged(float DeltaValue,const FGameplayTagContainer& EventTags);

When the health value changes, this function will be called

Implement the function in the BP_EnemyCharacter blueprint: health bar percentage = Health value/MaxHealth value

4.3. Create a GameplayEffect to deduct the Health effect

Add this effect to Player's attack GA. If you hit the enemy, 10 blood points will be deducted. The default Health value of BP_Character is set to 100.

4.4. Final effect

5. Fireball

5.1. Create an Actor fireball

Create an Actor blueprint class, BP_AbilityProjectileBase, as the blueprint base class for remote weapons,

Add sphere collision component, arrow component,

ProjectileMovement component: has the function of giving initial velocity to components in the scene

Set the initial velocity and adjust the Gravity Range value of the projectile to 0 so that it will not be affected by gravity.

Create a sub-blueprint BP_FireBall and add a particle effect,

Notice! ! ! If element 2 in the material cannot be assigned a value, you can restart the engine.

Drag FireBall into the scene and run it to see the fireball fly ahead.

Set the FireBall life cycle to 10s

5.2. When hitting the WorldStatic and WorldDynamic objects, emit a particle event and destroy itself

Set the collision event of FireBall sphere collision, block it with walls, etc., and Pawn triggers the overlap event

Event Hit: Event called when this Actor collides with a blocking object, or blocks another Actor that collides with it

5.3. Add input

BP_CharacterBase adds an activation method

bool ARPGCharacterBase::ActivateAbilitiesWithTag(FGameplayTagContainer AbilityTags, bool bAllowRemoteActivation)
{
	if (AbilitySystemComponent)
	{
		return AbilitySystemComponent->TryActivateAbilitiesByTag(AbilityTags,bAllowRemoteActivation);
	}

	return false;
}

Activate skills via AbilityTags

5.4. Create and release remote weapon skills GameplayAbility

Create a ranged weapon skill base class, GA_SpawnProjectileBase,

The same as the previous melee playback skill, after receiving the skill EventTag sent by Montage, call the EventReceived method

Create an RPGGameplayEffectContainerSpec structure, and then generate Actor based on ProjectileClass. ProjectileClass is the newly created fireball base class type BP_AbilityProjectileBase. Get the Actor information as the generation location.

DoesEffectContainerSpecHaveEffects is to determine whether there is GameEffect

Inherit GASpawnProjectileBase, create a subclass GA_PlayerSkillFireBall, and set parameters

Send EventTag at the selected time of montage playback,

5.5. During the flight of the fireball, overlapping events and hit events are triggered.

In the overlapping event, apply the EffectContainerSpec generated during the skill release to the Actor, so that the Actor will apply the GamepalyEffect effect

Add a play particle effect and destroy the Actor effect in the overlapping event of the subclass

At this point, the effect is complete

Guess you like

Origin blog.csdn.net/yuchenwuhen/article/details/134411542