Place initial gameplay actors in test map
This commit is contained in:
@@ -132,6 +132,11 @@ Completed in version .01:
|
||||
- [x] Created `IA_Interact` input action.
|
||||
- [x] Bound `IA_Interact` to `E` and `Gamepad_FaceButton_Left`.
|
||||
- [x] Assigned `IA_Interact` to the character Blueprint's `InteractAction`.
|
||||
- [x] Created item definition assets for wood, stone, fiber, food, meat, hide, and primitive structure parts.
|
||||
- [x] Created recipe data assets for campfire, primitive shelter, basic tool, and bandage.
|
||||
- [x] Created item definition assets for craft result items: campfire, primitive shelter, basic tool, and bandage.
|
||||
- [x] Created Blueprint child actors for wood resource, campfire, primitive shelter, and first wildlife species.
|
||||
- [x] Placed and verified wood resource, campfire, primitive shelter, and rabbit wildlife Blueprints in the test map.
|
||||
|
||||
Open version .01 tasks:
|
||||
|
||||
@@ -139,10 +144,11 @@ Open version .01 tasks:
|
||||
- [x] Create `IA_Interact` input action.
|
||||
- [x] Bind `IA_Interact` to `E` and a gamepad button.
|
||||
- [x] Assign `IA_Interact` to the character Blueprint's `InteractAction`.
|
||||
- [ ] Create item definition assets for wood, stone, fiber, food, meat, hide, and primitive structure parts.
|
||||
- [ ] Create recipe data assets for campfire, primitive shelter, basic tool, and bandage.
|
||||
- [ ] Create Blueprint child actors for wood resource, campfire, primitive shelter, and first wildlife species.
|
||||
- [ ] Place resource nodes, campfire, shelter, and wildlife in the test map.
|
||||
- [x] Create item definition assets for wood, stone, fiber, food, meat, hide, and primitive structure parts.
|
||||
- [x] Create recipe data assets for campfire, primitive shelter, basic tool, and bandage.
|
||||
- [x] Create item definition assets for craft result items: campfire, primitive shelter, basic tool, and bandage.
|
||||
- [x] Create Blueprint child actors for wood resource, campfire, primitive shelter, and first wildlife species.
|
||||
- [x] Place resource nodes, campfire, shelter, and wildlife in the test map.
|
||||
- [~] Add a simple HUD/debug display for survival and inventory.
|
||||
- [ ] Test gather -> inventory -> craft -> place shelter -> save/load loop.
|
||||
- [ ] Test wildlife damage/death/harvest loop.
|
||||
@@ -330,10 +336,10 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
|
||||
## 1.4 Single Biome MVP Map
|
||||
|
||||
- [ ] Choose MVP biome.
|
||||
- [ ] Create playable test map.
|
||||
- [~] Create playable test map.
|
||||
- [ ] Add terrain base.
|
||||
- [ ] Add foliage pass.
|
||||
- [ ] Add resource nodes.
|
||||
- [~] Add resource nodes.
|
||||
- [ ] Add water source.
|
||||
- [ ] Add weather exposure zones if needed.
|
||||
- [ ] Add landmark or ruin placeholder.
|
||||
@@ -363,7 +369,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
|
||||
## 1.6 Gathering And Resources
|
||||
|
||||
- [x] Create resource node base class.
|
||||
- [~] Add wood resource.
|
||||
- [x] Add wood resource.
|
||||
- [ ] Add stone resource.
|
||||
- [ ] Add fiber resource.
|
||||
- [ ] Add edible plant resource.
|
||||
@@ -381,11 +387,11 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
|
||||
- [x] Create recipe data assets.
|
||||
- [x] Implement recipe validation.
|
||||
- [x] Implement crafting queue or instant crafting.
|
||||
- [ ] Add primitive tool recipe.
|
||||
- [ ] Add campfire recipe.
|
||||
- [ ] Add shelter recipe.
|
||||
- [x] Add primitive tool recipe.
|
||||
- [x] Add campfire recipe.
|
||||
- [x] Add shelter recipe.
|
||||
- [ ] Add simple container recipe.
|
||||
- [ ] Add bandage or basic treatment recipe.
|
||||
- [x] Add bandage or basic treatment recipe.
|
||||
- [ ] Add crafting UI.
|
||||
- [x] Add multiplayer authority checks.
|
||||
- [~] Add crafting debug tools.
|
||||
@@ -438,7 +444,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
|
||||
|
||||
## 1.11 Wildlife Prototype
|
||||
|
||||
- [ ] Choose MVP wildlife species.
|
||||
- [x] Choose MVP wildlife species.
|
||||
- [x] Create wildlife base pawn.
|
||||
- [x] Add simple AI wander.
|
||||
- [x] Add flee behavior.
|
||||
@@ -446,7 +452,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
|
||||
- [x] Add health.
|
||||
- [ ] Add damage.
|
||||
- [x] Add harvesting interaction.
|
||||
- [~] Add meat/hide/bone resources if needed.
|
||||
- [x] Add meat/hide resources.
|
||||
- [ ] Add spawn manager.
|
||||
- [x] Add replication.
|
||||
- [ ] Add performance limits.
|
||||
@@ -1238,14 +1244,14 @@ Next version .01 priorities:
|
||||
- [ ] Open the project in Unreal Editor from the shared project path.
|
||||
- [ ] Create `IA_Interact` and bind it to `E` plus a gamepad button.
|
||||
- [ ] Assign `IA_Interact` to the Agrarian character Blueprint.
|
||||
- [ ] Create the first editor assets needed for the playable loop.
|
||||
- [ ] Place and test the first gatherable resource node.
|
||||
- [ ] Place and test the campfire.
|
||||
- [ ] Place and test the primitive shelter.
|
||||
- [ ] Place and test the first wildlife Blueprint.
|
||||
- [x] Create the first editor assets needed for the playable loop.
|
||||
- [x] Place and test the wood resource node.
|
||||
- [x] Place and test the campfire.
|
||||
- [x] Place and test the primitive shelter.
|
||||
- [x] Place and test the rabbit wildlife Blueprint.
|
||||
- [~] Add simple survival/inventory HUD feedback.
|
||||
- [ ] Run the first full gather -> craft -> place -> save -> load test.
|
||||
|
||||
Immediate next item:
|
||||
|
||||
- [ ] Open the project in Unreal Editor on Windows-Builder using the shared project path, then create/bind `IA_Interact` so the C++ interaction path can be tested in the editor.
|
||||
- [ ] Run the first full gather -> inventory -> craft -> place shelter -> save/load loop.
|
||||
|
||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,85 @@
|
||||
import unreal
|
||||
|
||||
|
||||
MAP_PATH = "/Game/ThirdPerson/Lvl_ThirdPerson"
|
||||
|
||||
PLACEMENTS = [
|
||||
{
|
||||
"label": "AGR_WoodResourceNode_01",
|
||||
"class_path": "/Game/Agrarian/Blueprints/Resources/BP_WoodResourceNode",
|
||||
"location": unreal.Vector(650.0, -150.0, 120.0),
|
||||
"rotation": unreal.Rotator(0.0, 15.0, 0.0),
|
||||
},
|
||||
{
|
||||
"label": "AGR_Campfire_01",
|
||||
"class_path": "/Game/Agrarian/Blueprints/Structures/BP_Campfire",
|
||||
"location": unreal.Vector(900.0, 120.0, 60.0),
|
||||
"rotation": unreal.Rotator(0.0, 0.0, 0.0),
|
||||
},
|
||||
{
|
||||
"label": "AGR_PrimitiveShelter_01",
|
||||
"class_path": "/Game/Agrarian/Blueprints/Structures/BP_PrimitiveShelter",
|
||||
"location": unreal.Vector(1200.0, -260.0, 140.0),
|
||||
"rotation": unreal.Rotator(0.0, -20.0, 0.0),
|
||||
},
|
||||
{
|
||||
"label": "AGR_RabbitWildlife_01",
|
||||
"class_path": "/Game/Agrarian/Blueprints/Wildlife/BP_RabbitWildlife",
|
||||
"location": unreal.Vector(450.0, 420.0, 100.0),
|
||||
"rotation": unreal.Rotator(0.0, 135.0, 0.0),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def load_blueprint_class(path):
|
||||
generated_class = unreal.EditorAssetLibrary.load_blueprint_class(path)
|
||||
if not generated_class:
|
||||
raise RuntimeError(f"Could not load Blueprint class: {path}")
|
||||
return generated_class
|
||||
|
||||
|
||||
def get_actor_label(actor):
|
||||
try:
|
||||
return actor.get_actor_label()
|
||||
except Exception:
|
||||
return actor.get_name()
|
||||
|
||||
|
||||
def remove_existing_placed_actors(labels):
|
||||
for actor in unreal.EditorLevelLibrary.get_all_level_actors():
|
||||
if get_actor_label(actor) in labels:
|
||||
unreal.EditorLevelLibrary.destroy_actor(actor)
|
||||
|
||||
|
||||
def set_actor_label(actor, label):
|
||||
try:
|
||||
actor.set_actor_label(label, mark_dirty=True)
|
||||
except TypeError:
|
||||
actor.set_actor_label(label)
|
||||
|
||||
|
||||
def main():
|
||||
if not unreal.EditorLevelLibrary.load_level(MAP_PATH):
|
||||
raise RuntimeError(f"Could not load map: {MAP_PATH}")
|
||||
|
||||
labels = {placement["label"] for placement in PLACEMENTS}
|
||||
remove_existing_placed_actors(labels)
|
||||
|
||||
for placement in PLACEMENTS:
|
||||
actor_class = load_blueprint_class(placement["class_path"])
|
||||
actor = unreal.AgrarianEditorAutomationLibrary.spawn_actor_in_editor_world(
|
||||
actor_class,
|
||||
placement["location"],
|
||||
placement["rotation"],
|
||||
placement["label"],
|
||||
)
|
||||
if not actor:
|
||||
raise RuntimeError(f"Could not spawn {placement['class_path']}")
|
||||
|
||||
unreal.log(f"Placed {placement['label']} at {placement['location']}")
|
||||
|
||||
unreal.EditorLevelLibrary.save_current_level()
|
||||
unreal.log("Agrarian test map placement setup complete.")
|
||||
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,91 @@
|
||||
import unreal
|
||||
|
||||
|
||||
MAP_PATH = "/Game/ThirdPerson/Lvl_ThirdPerson"
|
||||
|
||||
EXPECTED_PLACEMENTS = {
|
||||
"AGR_WoodResourceNode_01": {
|
||||
"class_path": "/Game/Agrarian/Blueprints/Resources/BP_WoodResourceNode",
|
||||
"location": unreal.Vector(650.0, -150.0, 120.0),
|
||||
"properties": {
|
||||
"remaining_harvests": 6,
|
||||
"quantity_per_harvest": 2,
|
||||
},
|
||||
},
|
||||
"AGR_Campfire_01": {
|
||||
"class_path": "/Game/Agrarian/Blueprints/Structures/BP_Campfire",
|
||||
"location": unreal.Vector(900.0, 120.0, 60.0),
|
||||
"properties": {
|
||||
"fuel_seconds": 180.0,
|
||||
"warmth_radius": 650.0,
|
||||
},
|
||||
},
|
||||
"AGR_PrimitiveShelter_01": {
|
||||
"class_path": "/Game/Agrarian/Blueprints/Structures/BP_PrimitiveShelter",
|
||||
"location": unreal.Vector(1200.0, -260.0, 140.0),
|
||||
"properties": {
|
||||
"weather_protection": 0.7,
|
||||
},
|
||||
},
|
||||
"AGR_RabbitWildlife_01": {
|
||||
"class_path": "/Game/Agrarian/Blueprints/Wildlife/BP_RabbitWildlife",
|
||||
"location": unreal.Vector(450.0, 420.0, 100.0),
|
||||
"properties": {
|
||||
"wildlife_id": "rabbit",
|
||||
"max_health": 12.0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def nearly_equal(left, right):
|
||||
return abs(float(left) - float(right)) < 0.001
|
||||
|
||||
|
||||
def vectors_close(left, right):
|
||||
return (
|
||||
abs(left.x - right.x) < 0.1
|
||||
and abs(left.y - right.y) < 0.1
|
||||
and abs(left.z - right.z) < 0.1
|
||||
)
|
||||
|
||||
|
||||
def get_actor_label(actor):
|
||||
try:
|
||||
return actor.get_actor_label()
|
||||
except Exception:
|
||||
return actor.get_name()
|
||||
|
||||
|
||||
def main():
|
||||
if not unreal.EditorLevelLibrary.load_level(MAP_PATH):
|
||||
raise RuntimeError(f"Could not load map: {MAP_PATH}")
|
||||
|
||||
failures = []
|
||||
actors_by_label = {get_actor_label(actor): actor for actor in unreal.EditorLevelLibrary.get_all_level_actors()}
|
||||
|
||||
for label, expected in EXPECTED_PLACEMENTS.items():
|
||||
actor = actors_by_label.get(label)
|
||||
if not actor:
|
||||
failures.append(f"{label} missing")
|
||||
continue
|
||||
|
||||
actor_location = actor.get_actor_location()
|
||||
if not vectors_close(actor_location, expected["location"]):
|
||||
failures.append(f"{label} expected location {expected['location']}, got {actor_location}")
|
||||
|
||||
for property_name, expected_value in expected.get("properties", {}).items():
|
||||
actual_value = actor.get_editor_property(property_name)
|
||||
if isinstance(expected_value, (int, float)):
|
||||
if not nearly_equal(actual_value, expected_value):
|
||||
failures.append(f"{label} {property_name} expected {expected_value}, got {actual_value}")
|
||||
elif str(actual_value) != expected_value:
|
||||
failures.append(f"{label} {property_name} expected {expected_value}, got {actual_value}")
|
||||
|
||||
if failures:
|
||||
raise RuntimeError("Test map placement verification failed: " + "; ".join(failures))
|
||||
|
||||
unreal.log("Agrarian test map placement verification complete.")
|
||||
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "AgrarianEditorAutomationLibrary.h"
|
||||
|
||||
#include "Engine/World.h"
|
||||
|
||||
#if WITH_EDITOR
|
||||
#include "Editor.h"
|
||||
#endif
|
||||
|
||||
AActor* UAgrarianEditorAutomationLibrary::SpawnActorInEditorWorld(TSubclassOf<AActor> ActorClass, const FVector& Location, const FRotator& Rotation, const FString& ActorLabel)
|
||||
{
|
||||
#if WITH_EDITOR
|
||||
if (!ActorClass)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UWorld* EditorWorld = GEditor ? GEditor->GetEditorWorldContext().World() : nullptr;
|
||||
if (!EditorWorld)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FActorSpawnParameters SpawnParameters;
|
||||
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||
SpawnParameters.ObjectFlags = RF_Transactional;
|
||||
|
||||
AActor* SpawnedActor = EditorWorld->SpawnActor<AActor>(ActorClass, Location, Rotation, SpawnParameters);
|
||||
if (!SpawnedActor)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ActorLabel.IsEmpty())
|
||||
{
|
||||
SpawnedActor->SetActorLabel(ActorLabel, true);
|
||||
}
|
||||
|
||||
SpawnedActor->MarkPackageDirty();
|
||||
EditorWorld->MarkPackageDirty();
|
||||
return SpawnedActor;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "AgrarianEditorAutomationLibrary.generated.h"
|
||||
|
||||
/**
|
||||
* Editor automation helpers used by Python setup scripts.
|
||||
*/
|
||||
UCLASS()
|
||||
class AGRARIANGAME_API UAgrarianEditorAutomationLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|Editor Automation")
|
||||
static AActor* SpawnActorInEditorWorld(TSubclassOf<AActor> ActorClass, const FVector& Location, const FRotator& Rotation, const FString& ActorLabel);
|
||||
};
|
||||
@@ -23,6 +23,13 @@ public class AgrarianGame : ModuleRules
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(new string[] { });
|
||||
|
||||
if (Target.bBuildEditor)
|
||||
{
|
||||
PrivateDependencyModuleNames.AddRange(new string[] {
|
||||
"UnrealEd"
|
||||
});
|
||||
}
|
||||
|
||||
PublicIncludePaths.AddRange(new string[] {
|
||||
"AgrarianGame",
|
||||
"AgrarianGame/Variant_Platforming",
|
||||
|
||||
Reference in New Issue
Block a user