mirror of
https://github.com/kuhyx/praca_magisterska.git
synced 2026-07-04 13:23:05 +02:00
shooting bullets
This commit is contained in:
parent
3d732ef8d7
commit
85cd1d1c79
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -187,14 +187,14 @@ MRUItem0=/Game/Untitled
|
||||
[DetailCustomWidgetExpansion]
|
||||
InputMappingContext=InputMappingContext.Mappings.ActionMappings,InputMappingContext.Mappings.ActionMappings./Game/Blueprints/IA_Move.IA_Move,InputMappingContext.Mappings.ActionMappings./Game/Input/IA_Move.IA_Move
|
||||
InputAction=
|
||||
CameraComponent=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens,CameraComponent.PostProcess.Lens
|
||||
CameraComponent=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
SceneComponent=
|
||||
BP_Player_C=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
BP_Player_C=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens,EdGraph.Inputs.277B5E44FBD747478CCE123CD66990D9
|
||||
PlayerStart=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
CapsuleComponent=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
LandscapeStreamingProxy=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
PropertyWrapper=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
SkyLight=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens,CameraComponent.PostProcess.Lens
|
||||
SkyLight=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
Landscape=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
EditorStyleSettings=EditorStyleSettings.Graphs.Preview,EditorKeyboardShortcutSettings.EditorViewport.ShowTextureResolution,EditorKeyboardShortcutSettings.EditorViewport.ShowTextureScale,EditorKeyboardShortcutSettings.MainFrame.SwitchProject
|
||||
SlateThemeManager=
|
||||
@ -389,12 +389,19 @@ TcpMessagingSettings=EditorStyleSettings.Graphs.Preview,EditorKeyboardShortcutSe
|
||||
TemplateSequenceEditorSettings=EditorStyleSettings.Graphs.Preview,EditorKeyboardShortcutSettings.EditorViewport.ShowTextureResolution,EditorKeyboardShortcutSettings.EditorViewport.ShowTextureScale,EditorKeyboardShortcutSettings.MainFrame.SwitchProject,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierSmoothDelta,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierDeadZone,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierResponseCurveExponential,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierFOVScaling,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerDown,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerPressed,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerPulse,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerReleased,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerHold,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerHoldAndRelease,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerTap
|
||||
UdpMessagingSettings=EditorStyleSettings.Graphs.Preview,EditorKeyboardShortcutSettings.EditorViewport.ShowTextureResolution,EditorKeyboardShortcutSettings.EditorViewport.ShowTextureScale,EditorKeyboardShortcutSettings.MainFrame.SwitchProject,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierSmoothDelta,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierDeadZone,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierResponseCurveExponential,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierFOVScaling,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerDown,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerPressed,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerPulse,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerReleased,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerHold,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerHoldAndRelease,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerTap
|
||||
WmfMediaSettings=EditorStyleSettings.Graphs.Preview,EditorKeyboardShortcutSettings.EditorViewport.ShowTextureResolution,EditorKeyboardShortcutSettings.EditorViewport.ShowTextureScale,EditorKeyboardShortcutSettings.MainFrame.SwitchProject,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierSmoothDelta,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierDeadZone,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierResponseCurveExponential,EnhancedInputDeveloperSettings.Modifier Default Values.InputModifierFOVScaling,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerDown,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerPressed,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerPulse,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerReleased,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerHold,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerHoldAndRelease,EnhancedInputDeveloperSettings.Trigger Default Values.InputTriggerTap
|
||||
K2Node_VariableGet=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
K2Node_VariableGet=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens,EdGraph.Inputs.277B5E44FBD747478CCE123CD66990D9
|
||||
K2Node_EnhancedInputAction=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
K2Node_VariableSet=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
K2Node_GetInputActionValue=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
EdGraph=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
EdGraph=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens,EdGraph.Inputs.277B5E44FBD747478CCE123CD66990D9
|
||||
K2Node_FunctionEntry=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
BP_Bullet_C=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
StaticMeshComponent=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
DefaultPawn=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
SphereComponent=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
GameModeBase=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
BillboardComponent=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
Initialize=CameraComponent.CameraSettings.Overscan,CameraComponent.PostProcess.Lens
|
||||
|
||||
[/Script/GraphEditor.GraphEditorSettings]
|
||||
DataPinStyle=BPST_VariantA
|
||||
@ -600,9 +607,9 @@ SceneComponent="\"Object\" "
|
||||
ActorComponent="\"Object\" "
|
||||
PaperSpriteComponent="\"Object\" \"Object.Collision.BodyInstance\" "
|
||||
MeshComponent="\"Object\" \"Object.Collision.BodyInstance\" "
|
||||
PrimitiveComponent="\"Object\" "
|
||||
PrimitiveComponent="\"Object\" \"Object.Collision.BodyInstance\" "
|
||||
BoxComponent="\"Object\" \"Object.Collision.BodyInstance\" "
|
||||
ShapeComponent="\"Object\" "
|
||||
ShapeComponent="\"Object\" \"Object.Collision.BodyInstance\" "
|
||||
ArrowComponent="\"Object\" "
|
||||
InputAction="\"Object\" "
|
||||
DataAsset="\"Object\" "
|
||||
@ -688,15 +695,18 @@ InputTriggerTap="\"Object\" "
|
||||
InputTriggerPulse="\"Object\" "
|
||||
EdGraphNode_Comment="\"Object\" "
|
||||
EdGraphNode="\"Object\" "
|
||||
SphereComponent="\"Object\" \"Object.Collision.BodyInstance\" "
|
||||
BillboardComponent="\"Object\" "
|
||||
DefaultPawn="\"Object\" "
|
||||
|
||||
[AssetEditorSubsystem]
|
||||
CleanShutdown=False
|
||||
DebuggerAttached=False
|
||||
RecentAssetEditors=GenericAssetEditor
|
||||
RecentAssetEditors=BlueprintEditor
|
||||
RecentAssetEditors=GenericAssetEditor
|
||||
RecentAssetEditors=GenericAssetEditor
|
||||
RecentAssetEditors=GenericAssetEditor
|
||||
RecentAssetEditors=GenericAssetEditor
|
||||
OpenAssetsAtExit=/Game/Blueprints/BP_Player.BP_Player
|
||||
|
||||
[ContentBrowser]
|
||||
@ -1600,6 +1610,119 @@ K2Node_CallFunction.Inputs=True
|
||||
K2Node_CallFunction.Outputs=True
|
||||
EdGraphNode_Comment.GraphNodeDetail=True
|
||||
EdGraphNode_Comment.Comment=True
|
||||
BP_Bullet_C.Tick=True
|
||||
BP_Bullet_C.Replication=True
|
||||
BP_Bullet_C.Rendering=True
|
||||
BP_Bullet_C.Collision=True
|
||||
BP_Bullet_C.Actor=True
|
||||
BP_Bullet_C.Input=True
|
||||
BP_Bullet_C.HLOD=True
|
||||
BP_Bullet_C.Physics=True
|
||||
BP_Bullet_C.Events=True
|
||||
SphereComponent.Variable=False
|
||||
SphereComponent.TransformCommon=False
|
||||
SphereComponent.Sockets=False
|
||||
SphereComponent.Shape=False
|
||||
SphereComponent.Navigation=False
|
||||
SphereComponent.HLOD=False
|
||||
SphereComponent.ComponentTick=False
|
||||
SphereComponent.Rendering=False
|
||||
SphereComponent.Physics=False
|
||||
SphereComponent.Collision=False
|
||||
SphereComponent.Tags=False
|
||||
SphereComponent.ComponentReplication=False
|
||||
SphereComponent.Cooking=False
|
||||
SphereComponent.Events=True
|
||||
GameNetworkManager.TransformCommon=True
|
||||
GameNetworkManager.Replication=True
|
||||
GameNetworkManager.Physics=True
|
||||
GameNetworkManager.Networking=True
|
||||
GameNetworkManager.Actor=True
|
||||
PlayerController.TransformCommon=True
|
||||
PlayerController.PlayerController=True
|
||||
PlayerController.MouseInterface=True
|
||||
PlayerController.Game=True
|
||||
PlayerController.Input=True
|
||||
PlayerController.WorldPartition=True
|
||||
PlayerController.Replication=True
|
||||
PlayerController.HLOD=True
|
||||
PlayerController.Physics=True
|
||||
PlayerController.Networking=True
|
||||
PlayerController.Actor=True
|
||||
PlayerState.Replication=True
|
||||
PlayerState.Physics=True
|
||||
PlayerState.Networking=True
|
||||
PlayerState.Actor=True
|
||||
DefaultPawn.TransformCommon=True
|
||||
DefaultPawn.StaticMesh=True
|
||||
DefaultPawn.Pawn=True
|
||||
DefaultPawn.FloatingPawnMovement=True
|
||||
DefaultPawn.NavMovement=True
|
||||
DefaultPawn.Velocity=True
|
||||
DefaultPawn.Physics=True
|
||||
DefaultPawn.Collision=True
|
||||
DefaultPawn.PlanarMovement=True
|
||||
DefaultPawn.Lighting=True
|
||||
DefaultPawn.MovementComponent=True
|
||||
DefaultPawn.Tags=True
|
||||
DefaultPawn.AssetUserData=True
|
||||
DefaultPawn.Rendering=True
|
||||
DefaultPawn.Activation=True
|
||||
DefaultPawn.Navigation=True
|
||||
DefaultPawn.Cooking=True
|
||||
DefaultPawn.Shape=True
|
||||
DefaultPawn.HLOD=True
|
||||
DefaultPawn.Mobile=True
|
||||
DefaultPawn.RayTracing=True
|
||||
DefaultPawn.Mesh Painting=True
|
||||
DefaultPawn.VirtualTexture=True
|
||||
DefaultPawn.Camera=True
|
||||
DefaultPawn.Replication=True
|
||||
DefaultPawn.Networking=True
|
||||
DefaultPawn.Input=True
|
||||
DefaultPawn.Actor=True
|
||||
DefaultPawn.Materials=True
|
||||
GameModeBase.Classes=True
|
||||
GameModeBase.Game=True
|
||||
GameModeBase.GameMode=True
|
||||
GameModeBase.Physics=True
|
||||
GameModeBase.Networking=True
|
||||
GameSession.TransformCommon=True
|
||||
GameSession.Replication=True
|
||||
GameSession.Physics=True
|
||||
GameSession.Networking=True
|
||||
GameSession.Actor=True
|
||||
SkyAtmosphere.TransformCommon=True
|
||||
SkyAtmosphere.Planet=True
|
||||
SkyAtmosphere.Atmosphere=True
|
||||
SkyAtmosphere.Atmosphere - Rayleigh=True
|
||||
SkyAtmosphere.Atmosphere - Mie=True
|
||||
SkyAtmosphere.Atmosphere - Absorption=True
|
||||
SkyAtmosphere.Art Direction=True
|
||||
SkyAtmosphere.Rendering=True
|
||||
SkyAtmosphere.Physics=True
|
||||
SkyAtmosphere.Tags=True
|
||||
SkyAtmosphere.Activation=True
|
||||
SkyAtmosphere.Cooking=True
|
||||
SkyAtmosphere.Replication=True
|
||||
SkyAtmosphere.Networking=True
|
||||
SkyAtmosphere.Actor=True
|
||||
ExponentialHeightFog.TransformCommon=True
|
||||
ExponentialHeightFog.ExponentialHeightFogComponent=True
|
||||
ExponentialHeightFog.InscatteringTexture=True
|
||||
ExponentialHeightFog.DirectionalInscattering=True
|
||||
ExponentialHeightFog.VolumetricFog=True
|
||||
ExponentialHeightFog.Rendering=True
|
||||
ExponentialHeightFog.Physics=True
|
||||
ExponentialHeightFog.Tags=True
|
||||
ExponentialHeightFog.Activation=True
|
||||
ExponentialHeightFog.Cooking=True
|
||||
ExponentialHeightFog.Replication=True
|
||||
ExponentialHeightFog.Networking=True
|
||||
ExponentialHeightFog.Actor=True
|
||||
K2Node_FunctionResult.Graph=True
|
||||
K2Node_FunctionResult.Inputs=True
|
||||
K2Node_FunctionResult.Outputs=True
|
||||
|
||||
[DetailMultiObjectNodeExpansion]
|
||||
GeneralProjectSettings=True
|
||||
@ -1662,11 +1785,12 @@ CrowdManager=True
|
||||
CookerSettings=True
|
||||
|
||||
[AssetEditorSubsystemRecents]
|
||||
MRUItem0=/Game/Blueprints/BP_Player
|
||||
MRUItem1=/Game/Input/IMC_Default
|
||||
MRUItem2=/Game/Input/IA_Move
|
||||
MRUItem3=/Game/Input/IA_Special
|
||||
MRUItem4=/Game/Input/IA_Fire
|
||||
MRUItem0=/Game/Blueprints/BP_Bullet
|
||||
MRUItem1=/Game/Blueprints/BP_Player
|
||||
MRUItem2=/Game/Input/IMC_Default
|
||||
MRUItem3=/Game/Input/IA_Move
|
||||
MRUItem4=/Game/Input/IA_Special
|
||||
MRUItem5=/Game/Input/IA_Fire
|
||||
|
||||
[SelectionDetails]
|
||||
PreserveScaleRatio=True
|
||||
@ -1674,6 +1798,7 @@ PreserveScaleRatio=True
|
||||
[DetailCategoriesAdvanced]
|
||||
InputAction.Action=False
|
||||
EdGraph.Graph=True
|
||||
PropertyWrapper.Variable=False
|
||||
|
||||
[AssetEditorToolkitTabLocation]
|
||||
/Game/Input/IA_Move.IA_Move=1
|
||||
|
||||
@ -156,8 +156,9 @@
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/__ExternalActors__/Untitled/5/OM/8IGK2V3IFN3KZLW18YOQBO.uasset",
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/__ExternalActors__/Untitled/B/6S/O5MC4CZRRB62HQ1QQK7X0J.uasset",
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/Untitled.umap",
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/__ExternalActors__/Untitled/7/HJ/X38LX50JWL2L2Y8KSQTL7D.uasset",
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/__ExternalActors__/Untitled/8/DU/ZSDVJX62HUOGBSNTE6TBHV.uasset",
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/Blueprints/BP_Bullet.uasset",
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/__ExternalActors__/Untitled/7/HJ/X38LX50JWL2L2Y8KSQTL7D.uasset",
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/__ExternalActors__/Untitled/8/NZ/GJL3NPSSBFSHGE0B2HZWC6.uasset",
|
||||
"/home/kuhy/praca_magisterska/games/unreal/BulletHellGame/BulletHellGame/Content/Blueprints/IA_Move.uasset"
|
||||
]
|
||||
|
||||
@ -42,6 +42,7 @@ This tutorial recreates the Unity "magisterka_1" bullet-hell shooter in Unreal E
|
||||
- [Step 4.4: Enemy Firing Logic](part-4-create-enemy.md#step-44-enemy-firing-logic)
|
||||
- [Step 4.5: Enemy Damage and Death](part-4-create-enemy.md#step-45-enemy-damage-and-death)
|
||||
- [Step 4.6: Complete Special Ability in BP_Player](part-4-create-enemy.md#step-46-complete-special-ability-in-bp_player)
|
||||
- [Step 4.7: Complete Bullet Collision Logic](part-4-create-enemy.md#step-47-complete-bullet-collision-logic-bp_bullet)
|
||||
|
||||
### Part 5: Create Enemy Spawner
|
||||
- [Step 5.1: Create Spawner Blueprint](part-5-create-spawner.md#step-51-create-spawner-blueprint)
|
||||
|
||||
@ -47,15 +47,73 @@
|
||||
1. In Event Graph, from **Event Tick:**
|
||||
|
||||
#### a) Calculate movement:
|
||||
- Get TravelDirection
|
||||
- Multiply by TravelSpeed
|
||||
- Multiply by Delta Seconds
|
||||
- Add to current location
|
||||
- Set Actor Location
|
||||
|
||||
#### b) Check lifetime:
|
||||
- Subtract Delta Seconds from RemainingLifetime
|
||||
- If <= 0: Destroy Actor
|
||||
1. Right-click → `Get TravelDirection`
|
||||
2. Right-click → `Get TravelSpeed`
|
||||
3. Right-click → search `Multiply (Vector * Float)` → add it
|
||||
- Connect TravelDirection to the Vector input
|
||||
- Connect TravelSpeed to the Float input
|
||||
- Result: a vector representing full speed in travel direction
|
||||
|
||||
4. Right-click → `Get World Delta Seconds`
|
||||
5. Right-click → search `Multiply (Vector * Float)` → add another one
|
||||
- Connect the RESULT from step 3 to the Vector input
|
||||
- Connect World Delta Seconds to the Float input
|
||||
- Result: movement delta for this frame (frame-rate independent)
|
||||
|
||||
6. Right-click → `Get Actor Location`
|
||||
7. Right-click → search `Add (Vector + Vector)` → add it
|
||||
- Connect Actor Location to first input
|
||||
- Connect the movement delta (from step 5) to second input
|
||||
|
||||
8. Right-click → `Set Actor Location`
|
||||
- Connect the Add result to "New Location"
|
||||
- Connect execution wire from Event Tick to Set Actor Location
|
||||
|
||||
#### b) Check lifetime and destroy when expired:
|
||||
|
||||
9. Right-click → `Get RemainingLifetime`
|
||||
|
||||
10. Right-click → `Get World Delta Seconds`
|
||||
|
||||
11. Right-click → search `Subtract (Float)` → add it
|
||||
- Connect RemainingLifetime to the TOP input (A)
|
||||
- Connect World Delta Seconds to the BOTTOM input (B)
|
||||
- Result: RemainingLifetime minus DeltaSeconds
|
||||
|
||||
12. Right-click → `Set RemainingLifetime`
|
||||
- Connect the Subtract result to it
|
||||
- This ALWAYS stores the new decreased lifetime value
|
||||
|
||||
13. Connect execution wire:
|
||||
- From `Set Actor Location` (from step 8) → `Set RemainingLifetime`
|
||||
|
||||
14. Right-click → search `<= (Float)` (less than or equal) → add it
|
||||
- Connect RemainingLifetime (from Set node output, or Get again) to TOP input
|
||||
- Type `0` in BOTTOM input
|
||||
- Result: true if lifetime has expired
|
||||
|
||||
15. From `Set RemainingLifetime`, drag execution → `Branch`
|
||||
- Connect the `<=` result to Branch's "Condition" input
|
||||
|
||||
16. **On TRUE (lifetime expired):**
|
||||
- From Branch's "True" pin, drag → `Destroy Actor`
|
||||
- Target: leave as "Self" (destroys this bullet)
|
||||
|
||||
17. **On FALSE (still alive):**
|
||||
- Leave unconnected (bullet continues to exist, will check again next frame)
|
||||
|
||||
**Visual:**
|
||||
|
||||
```
|
||||
Event Tick ──► Set Actor Location ──► Set RemainingLifetime ──► Branch
|
||||
(movement) = Remaining - Delta (Remaining <= 0?)
|
||||
│
|
||||
TRUE ──────┴────── FALSE
|
||||
│ │
|
||||
▼ ▼
|
||||
Destroy Actor (nothing)
|
||||
```
|
||||
|
||||
### 2. CREATE "Initialize" FUNCTION:
|
||||
|
||||
@ -81,40 +139,100 @@
|
||||
- Compile button shows GREEN checkmark
|
||||
- "Initialize" function appears under Functions with 5 input parameters
|
||||
|
||||
### Expected Result in Play mode (when spawned by player):
|
||||
- Bullets move in their assigned direction at TravelSpeed
|
||||
- Bullets automatically destroy after RemainingLifetime seconds (default 4s)
|
||||
- Movement is smooth and frame-rate independent
|
||||
> **NOTE:** Bullet testing is possible after completing [Step 3.4](#step-34-complete-player-firing-logic-bp_player).
|
||||
|
||||
---
|
||||
|
||||
## Step 3.3: Bullet Collision Logic
|
||||
|
||||
1. Click on "BulletCollision" component in Components panel
|
||||
### 1. ADD THE OVERLAP EVENT:
|
||||
|
||||
2. In Details panel, scroll to "Events" section
|
||||
- Click "+" next to **"On Component Begin Overlap"**
|
||||
- This creates event node in Event Graph
|
||||
1. In the Components panel (top-left), click on **"BulletCollision"** to select it
|
||||
|
||||
3. In the Event Graph, from "On Component Begin Overlap":
|
||||
2. In the Details panel (right side), scroll down to find the **"Events"** section
|
||||
- Look for "On Component Begin Overlap"
|
||||
- Click the green **"+"** button next to it
|
||||
- This creates an event node in the Event Graph
|
||||
|
||||
#### a) First, check if this is enemy projectile:
|
||||
- Get IsEnemyProjectile
|
||||
- Branch
|
||||
3. The Event Graph now shows a red node: **"On Component Begin Overlap (BulletCollision)"**
|
||||
- This fires whenever another actor overlaps with the bullet's collision sphere
|
||||
|
||||
#### b) IF IS ENEMY PROJECTILE (True branch):
|
||||
- Get Other Actor from the overlap event
|
||||
- Cast to BP_Player
|
||||
- If cast succeeds:
|
||||
- Call TakeHit on player, passing Damage
|
||||
- Destroy this bullet (Destroy Actor)
|
||||
|
||||
#### c) IF IS PLAYER BULLET (False branch):
|
||||
- Get Other Actor
|
||||
- Cast to BP_Enemy
|
||||
- If cast succeeds:
|
||||
- Call ApplyDamage on enemy, passing Damage
|
||||
- Destroy this bullet
|
||||
### 2. CHECK IF THIS IS AN ENEMY PROJECTILE:
|
||||
|
||||
4. Right-click → `Get IsEnemyProjectile`
|
||||
- This gets your boolean variable
|
||||
|
||||
5. From "On Component Begin Overlap", drag execution → `Branch`
|
||||
- Connect IsEnemyProjectile to Branch's "Condition" input
|
||||
- TRUE = this is an enemy bullet (should damage player)
|
||||
- FALSE = this is a player bullet (should damage enemies)
|
||||
|
||||
### 3. TRUE BRANCH - Enemy Bullet Hits Player:
|
||||
|
||||
6. From the **"On Component Begin Overlap"** node, look for the **"Other Actor"** output pin
|
||||
- This is the actor that overlapped with the bullet
|
||||
- Drag from "Other Actor" → search `Cast to BP_Player`
|
||||
|
||||
7. Connect execution wire:
|
||||
- From Branch **TRUE** pin → `Cast to BP_Player`
|
||||
|
||||
8. The cast has two execution outputs:
|
||||
- **"Cast Succeeded"** (top) - the other actor IS a player
|
||||
- **"Cast Failed"** (bottom) - the other actor is NOT a player
|
||||
|
||||
9. From "Cast Succeeded", we need to damage the player:
|
||||
- From the cast's **"As BP Player"** output pin, drag → search `TakeHit`
|
||||
- This calls the TakeHit function you created in [Part 2](part-2-create-player.md)
|
||||
- **IMPORTANT:** The "Target" pin on TakeHit should now be connected to "As BP Player" (this happened automatically when you dragged from that pin)
|
||||
- If Target shows "self", you must manually connect "As BP Player" to the "Target" pin - TakeHit must be called ON the player, not on the bullet!
|
||||
|
||||
10. Connect the Damage parameter:
|
||||
- Right-click → `Get Damage` (your bullet's damage variable)
|
||||
- Connect to TakeHit's "DamageAmount" input
|
||||
|
||||
11. After damaging the player, destroy the bullet:
|
||||
- From TakeHit, drag execution → `Destroy Actor`
|
||||
- Leave "Target" as "Self" (destroys this bullet)
|
||||
|
||||
12. Connect execution wire:
|
||||
- Cast to BP_Player → TakeHit → Destroy Actor
|
||||
|
||||
### 4. FALSE BRANCH - Player Bullet Hits Enemy (PLACEHOLDER):
|
||||
|
||||
> **NOTE:** BP_Enemy doesn't exist yet, so we'll add a placeholder. You'll complete this logic in [Part 4, Step 4.7](part-4-create-enemy.md#step-47-complete-bullet-collision-logic-bp_bullet).
|
||||
|
||||
13. From Branch **FALSE** pin, drag execution → `Print String`
|
||||
- In the "In String" field, type: `TODO: Damage enemy`
|
||||
- This is temporary - we'll replace it with real enemy damage logic in Part 4
|
||||
|
||||
**Visual:**
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────┐
|
||||
│ On Component Begin Overlap │
|
||||
│ (BulletCollision) │
|
||||
│ Other Actor ○─────────────────────┐
|
||||
└──────────────┬───────────────────────┘ │
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌──────────────────┐
|
||||
│ Branch │ │ Cast to BP_Player│
|
||||
│ IsEnemyProjectile └────────┬─────────┘
|
||||
└───────┬───┬─────┘ │
|
||||
│ │ Cast Succeeded
|
||||
TRUE ─┘ └─ FALSE │
|
||||
│ │ ▼
|
||||
▼ │ ┌──────────────────┐
|
||||
Cast to BP_Player │ │ TakeHit │
|
||||
(see above) │ │ Damage: Damage │
|
||||
│ └────────┬─────────┘
|
||||
▼ │
|
||||
┌──────────────────┐ ▼
|
||||
│ Print String │ ┌──────────────────┐
|
||||
│ "TODO: Damage │ │ Destroy Actor │
|
||||
│ enemy" │ │ (Self) │
|
||||
└──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
### 4. Compile and Save
|
||||
|
||||
@ -122,12 +240,7 @@
|
||||
- Compile button shows GREEN checkmark
|
||||
- Event Graph shows "On Component Begin Overlap" event connected to Branch
|
||||
|
||||
### Expected Result in Play mode:
|
||||
- Player bullets (IsEnemyProjectile=false) hitting enemies:
|
||||
- Enemy takes damage, bullet disappears
|
||||
- Enemy bullets (IsEnemyProjectile=true) hitting player:
|
||||
- Player takes hit, bullet disappears
|
||||
- Bullets passing through other objects: No effect (bullets ignore non-targets)
|
||||
> **NOTE:** Collision testing requires player firing (Step 3.4) and enemies (Part 4). Full collision behavior is testable after completing [Part 4](part-4-create-enemy.md).
|
||||
|
||||
---
|
||||
|
||||
@ -171,53 +284,68 @@ The entry node should now show two input pins: SpawnLocation and Direction
|
||||
|
||||
2. For the "Class" input:
|
||||
- Right-click → `Get BulletClass` (your variable)
|
||||
- Connect to "Class" pin
|
||||
- Connect BulletClass output (blue pin) to SpawnActor's "Class" input (purple pin)
|
||||
|
||||
3. For the "Spawn Transform" input:
|
||||
- Right-click on the "Spawn Transform" pin → "Split Struct Pin"
|
||||
- This splits it into Location, Rotation, Scale
|
||||
- Connect "SpawnLocation" (from entry node) to "Spawn Transform Location"
|
||||
- Leave Rotation and Scale at defaults
|
||||
3. For the "Spawn Transform Location" input:
|
||||
- On the SpawnActor node, look for "Spawn Transform Location" (orange pin)
|
||||
- If you only see "Spawn Transform", right-click on it → "Split Struct Pin" to expand it
|
||||
- Drag a wire from the **SpawnLocation** parameter (on the SpawnBullet entry node) to **"Spawn Transform Location"**
|
||||
- Leave Rotation and Scale at defaults (0,0,0 and 1,1,1)
|
||||
|
||||
4. Connect execution wire:
|
||||
- Drag from SpawnBullet entry node → Spawn Actor from Class
|
||||
- Drag from SpawnBullet entry node (white triangle) → SpawnActor (white triangle)
|
||||
|
||||
#### f) Initialize the spawned bullet:
|
||||
|
||||
5. The "Spawn Actor from Class" has a "Return Value" output (the spawned actor)
|
||||
- Drag from Return Value → search `Cast to BP_Bullet`
|
||||
- This works now because BP_Bullet exists!
|
||||
5. Add the Cast node:
|
||||
- From SpawnActor's **"Return Value"** output (blue pin on right side), drag → search `Cast to BP_Bullet`
|
||||
- Connect "Return Value" to the Cast's "Object" input
|
||||
|
||||
6. From the cast's "As BP Bullet" output, drag → search `Initialize`
|
||||
- This calls the Initialize function on the bullet (created in Step 3.2)
|
||||
- Connect "Direction" (from entry node) to Initialize's Direction input
|
||||
- Right-click → `Get BulletSpeed` → connect to Speed input
|
||||
- For "bIsEnemy" input: leave unchecked (false) - player bullets aren't enemy
|
||||
- For "Lifetime": type `4.0` (or leave default)
|
||||
6. Connect execution wire:
|
||||
- From SpawnActor (white triangle output) → Cast to BP_Bullet (white triangle input)
|
||||
|
||||
7. Connect execution wires:
|
||||
- Spawn Actor → Cast to BP_Bullet → Initialize
|
||||
7. Add the Initialize call:
|
||||
- From the Cast's **"As BP Bullet"** output (blue pin), drag → search `Initialize`
|
||||
- This calls the Initialize function you created in Step 3.2
|
||||
- **IMPORTANT:** The "Target" pin should automatically connect to "As BP Bullet"
|
||||
|
||||
8. Connect Initialize parameters:
|
||||
- **Direction**: Drag from the **Direction** parameter (on SpawnBullet entry node, yellow pin) → Initialize's "Direction" input
|
||||
- **Speed**: Right-click → `Get BulletSpeed` → connect to Initialize's "Speed" input
|
||||
- **bIsEnemy**: Leave unchecked (false) - player bullets aren't enemy projectiles
|
||||
- **Lifetime**: Type `4.0` in the input field (or leave default)
|
||||
- **DamageValue**: Leave at default `1`
|
||||
|
||||
9. Connect execution wire:
|
||||
- From Cast to BP_Bullet → Initialize
|
||||
|
||||
**Visual:**
|
||||
|
||||
```
|
||||
┌───────────────────────┐ ┌─────────────────────────┐
|
||||
│ SpawnBullet │─────►│ Spawn Actor from Class │
|
||||
│ SpawnLocation ○ │ │ Class: BulletClass │
|
||||
│ Direction ○ │ │ Location: SpawnLocation │
|
||||
└───────────────────────┘ └───────────┬─────────────┘
|
||||
│
|
||||
┌───────────────────────┐ ┌─────────────────────────────────┐
|
||||
│ SpawnBullet │─────►│ Spawn Actor from Class │
|
||||
│ SpawnLocation ○───────┼─────►│ Class: BulletClass │
|
||||
│ Direction ○ │ │ Spawn Transform Location ○◄───┘
|
||||
└───────────────────────┘ │ Return Value ○────────────────┐
|
||||
└─────────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────┘
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Cast to BP_Bullet │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
│ Object ○◄─────────────┘
|
||||
│ As BP Bullet ○────────┐
|
||||
└─────────────────────────┘
|
||||
│
|
||||
┌─────────────┘
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Initialize │
|
||||
│ Direction: Direction │
|
||||
│ Speed: BulletSpeed │
|
||||
│ bIsEnemy: false │
|
||||
│ Target ○◄─────────────┘
|
||||
│ Direction ○◄──────────── (from entry node)
|
||||
│ Speed ○◄────────────── BulletSpeed
|
||||
│ bIsEnemy: false │
|
||||
│ Lifetime: 4.0 │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
@ -360,19 +488,20 @@ The entry node should now show two input pins: SpawnLocation and Direction
|
||||
BUT Unreal's Sin/Cos use RADIANS, not degrees!
|
||||
|
||||
**a) Convert degrees to radians:**
|
||||
- Right-click → search `Radians` or `Degrees to Radians`
|
||||
- Connect your angle (from step 12) to input
|
||||
- Right-click → search `Degrees To Radians` → add it
|
||||
- Connect your angle (from step 12) to the input
|
||||
- Output is angle in radians
|
||||
|
||||
|
||||
**b) Calculate X component (Cos):**
|
||||
- Right-click → `Cos (Radians)`
|
||||
- Connect radians output
|
||||
- This is the X direction component
|
||||
- Right-click → `Cos (Radians)` → add it
|
||||
- Connect the Degrees To Radians output to Cos input
|
||||
|
||||
**c) Calculate Y component (Sin):**
|
||||
- Right-click → `Sin (Radians)`
|
||||
- Connect radians output (same value as Cos input)
|
||||
- This is the Y direction component
|
||||
- Right-click → `Sin (Radians)` → add it
|
||||
- To connect the SAME radians value to Sin (without losing the Cos connection):
|
||||
- **Option 1:** Ctrl+drag from "Degrees To Radians" output to Sin input (creates second wire)
|
||||
- **Option 2:** Drag directly from "Degrees To Radians" output again - UE5 allows multiple wires from one output pin
|
||||
- Both Cos and Sin should now be connected to the same radians value
|
||||
|
||||
**d) Make the direction vector:**
|
||||
- Right-click → `Make Vector`
|
||||
|
||||
@ -346,4 +346,84 @@ Now that BP_Enemy exists (and BP_Bullet from Part 3), we can complete the specia
|
||||
|
||||
---
|
||||
|
||||
## Step 4.7: Complete Bullet Collision Logic (BP_Bullet)
|
||||
|
||||
Now that BP_Enemy exists (and the `ApplyDamage` function from Step 4.3), we can complete the collision logic that was set up as a placeholder in [Part 3, Step 3.3](part-3-create-bullet.md#step-33-bullet-collision-logic).
|
||||
|
||||
### 1. Open BP_Bullet Blueprint:
|
||||
1. Content Browser → Blueprints → double-click `BP_Bullet`
|
||||
2. Go to **Event Graph** tab
|
||||
3. Find the `On Component Begin Overlap (BulletCollision)` event node
|
||||
4. Locate the `Print String "TODO: Damage enemy"` node on the FALSE branch
|
||||
|
||||
### 2. Replace Print String with enemy damage logic:
|
||||
|
||||
#### a) Delete the placeholder:
|
||||
- Select the `Print String` node
|
||||
- Press Delete
|
||||
|
||||
#### b) Add Cast to BP_Enemy:
|
||||
1. Right-click → search `Cast to BP_Enemy` → add it
|
||||
|
||||
2. Connect execution wire:
|
||||
- From Branch **FALSE** pin → `Cast to BP_Enemy`
|
||||
|
||||
3. Connect the "Other Actor" to the cast:
|
||||
- From the **"On Component Begin Overlap"** node, drag from **"Other Actor"** to the Cast's "Object" input
|
||||
- (You can Ctrl+drag to create a second wire without removing the existing one to BP_Player)
|
||||
|
||||
#### c) Call ApplyDamage on the enemy:
|
||||
4. From "Cast Succeeded" on the BP_Enemy cast:
|
||||
- From the cast's **"As BP Enemy"** output pin, drag → search `ApplyDamage`
|
||||
- This calls the ApplyDamage function you created in Step 4.3
|
||||
|
||||
5. Connect the Damage parameter:
|
||||
- Right-click → `Get Damage` (the bullet's damage variable)
|
||||
- Connect to ApplyDamage's "DamageAmount" input
|
||||
|
||||
#### d) Destroy the bullet after damaging:
|
||||
6. From ApplyDamage, drag execution → `Destroy Actor`
|
||||
- Leave "Target" as "Self" (destroys this bullet)
|
||||
|
||||
**Visual:**
|
||||
|
||||
```
|
||||
FALSE
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
Other Actor ──────────►│ Cast to BP_Enemy │
|
||||
└──────────┬───────────┘
|
||||
│
|
||||
Cast Succeeded
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ ApplyDamage │
|
||||
Get Damage ───────────►│ DamageAmount │
|
||||
└──────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ Destroy Actor │
|
||||
│ (Self) │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
### 3. Compile and Save
|
||||
|
||||
### Expected Result after Compile:
|
||||
- Compile button shows GREEN checkmark
|
||||
- No warnings - both BP_Player and BP_Enemy casts are valid now
|
||||
|
||||
### Expected Result in Play mode:
|
||||
- Player bullets (IsEnemyProjectile=false) hitting enemies:
|
||||
- Enemy takes damage, bullet disappears
|
||||
- After enough hits, enemy dies and awards score
|
||||
- Enemy bullets (IsEnemyProjectile=true) hitting player:
|
||||
- Player takes hit, bullet disappears
|
||||
- Bullets passing through other objects: No effect (bullets ignore non-targets)
|
||||
|
||||
---
|
||||
|
||||
[← Previous: Part 3 - Create the Bullet](part-3-create-bullet.md) | [Back to Index](README.md) | [Next: Part 5 - Create Enemy Spawner →](part-5-create-spawner.md)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user