Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chaos vehicles not respawning even after changing to "Always respawn" #26

Closed
DoubleP90 opened this issue Dec 4, 2021 · 8 comments
Closed

Comments

@DoubleP90
Copy link

Vehicles don't respawn when loading a game, I know they inherit from APawn so by default they shouldn't.
I have tried to set the respawn mode to "Always respawn" and I've added a SpudGuid, with no success.

The vehicle is saved correctly as the data and the vehicles velocity is being restored on load.

It could be that respawn mode doesn't work on any pawn, but I haven't tried it with anything else, pawns that can be possessed temporarily like vehicles and horses might benefit from being able to set them to respawn after loading a game

@sinbad
Copy link
Owner

sinbad commented Dec 6, 2021

I added a test case to the SPUDExamples project which spawns a pawn on a trigger that is set to AlwaysRespawn, then saved and re-loaded (making sure not to activate the trigger again). The pawn was respawned correctly.

@DoubleP90
Copy link
Author

DoubleP90 commented Dec 7, 2021

I just tested with a character in my project, works without problems, same exact setup with the AWheeledVehiclePawn (Chaos vehicle) and it doesn't work, so it seems it's just the vehicle that's problematic.

I am testing on UE5 early access, so it might not be a relevant issue for now

It's odd because AWheeledVehiclePawn is just an APawn with a SkeletalMesh and a VehicleMovementComponent (which I did try adding to the character to see if it's causing problems and it doesn't)

This is all there is to the AWheeledVehiclePawn.h, is there anything you see that might be making it incompatible with spud? I'm not too sure what UCLASS(abstract) does, but it shouldn't cause problems if it's subclassed from what I understand


// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "GameFramework/Pawn.h"
#include "WheeledVehiclePawn.generated.h"

class FDebugDisplayInfo;

/**
 * ChaosWheeledVehicle is the base wheeled vehicle pawn actor.
 * By default it uses UChaosWheeledVehicleMovementComponent for its simulation, but this can be overridden by inheriting from the class and modifying its constructor like so:
 * Super(ObjectInitializer.SetDefaultSubobjectClass<UMyMovement>(VehicleComponentName))
 * Where UMyMovement is the new movement type that inherits from UChaosVehicleMovementComponent
 */

UCLASS(abstract, config=Game, BlueprintType)
class CHAOSVEHICLES_API AWheeledVehiclePawn : public APawn
{
	GENERATED_UCLASS_BODY()

private:
	/**  The main skeletal mesh associated with this Vehicle */
	UPROPERTY(Category = Vehicle, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
	class USkeletalMeshComponent* Mesh;

	/** vehicle simulation component */
	UPROPERTY(Category = Vehicle, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
	class UChaosVehicleMovementComponent* VehicleMovementComponent;
public:

	/** Name of the MeshComponent. Use this name if you want to prevent creation of the component (with ObjectInitializer.DoNotCreateDefaultSubobject). */
	static FName VehicleMeshComponentName;

	/** Name of the VehicleMovement. Use this name if you want to use a different class (with ObjectInitializer.SetDefaultSubobjectClass). */
	static FName VehicleMovementComponentName;

	/** Util to get the wheeled vehicle movement component */
	class UChaosVehicleMovementComponent* GetVehicleMovementComponent() const;

	//~ Begin AActor Interface
	virtual void DisplayDebug(class UCanvas* Canvas, const FDebugDisplayInfo& DebugDisplay, float& YL, float& YPos) override;
	//~ End Actor Interface

	/** Returns Mesh subobject **/
	class USkeletalMeshComponent* GetMesh() const { return Mesh; }

	/** Returns VehicleMovement subobject **/
	class UChaosVehicleMovementComponent* GetVehicleMovement() const { return VehicleMovementComponent; }
};

My vehicle just inherits from it and adds the spud functionality

#pragma once


#include "CoreMinimal.h"
#include "WheeledVehiclePawn.h"
#include "../../../../Plugins/SPUD/Source/SPUD/Public/ISpudObject.h"
#include "BaseVehicle.generated.h"

/**
 * 
 */
UCLASS()
class THEDRIVE_API ABaseVehicle : public AWheeledVehiclePawn, public ISpudObject
{
	GENERATED_BODY()
	
public:
	ABaseVehicle(const FObjectInitializer& ObjectInitializer);

	UPROPERTY(BlueprintReadOnly)
	FGuid SpudGuid;

	virtual ESpudRespawnMode GetSpudRespawnMode_Implementation() const override { return ESpudRespawnMode::AlwaysRespawn; }
	
protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	

};

@sinbad
Copy link
Owner

sinbad commented Dec 7, 2021

I'm happy that SPUD works at all with UE5, I haven't tested that yet :) I can't see anything wrong with the vehicle pawn, but perhaps it's something about its level ownership. All objects are loaded with the level they're owned by, so perhaps check that the vehicle spawn owner is the level you think it is?

Otherwise it would be useful to see what the log says at save & load time. Are there any messages about this instance?

@DoubleP90
Copy link
Author

Yes it works perfectly in UE5!

I had to clean up the log as I had a lot of garbage being printed every frame, Found the problem, the vehicle wants to spawn at world origin, the world was above it so it was colliding and didn't spawn, but I'm not sure why it wants to spawn it there


LogSpudState: Verbose:  * STORE Level Actor: TestMap/INT_Weapon_C_1
LogSpudProps: Verbose:  | ItemOwner = 
LogSpudProps: Verbose:  | AttachedTo = NULL
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose:  * STORE Level Actor: TestMap/INT_Weapon_C_2
LogSpudProps: Verbose:  | ItemOwner = 
LogSpudProps: Verbose:  | AttachedTo = NULL
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose:  * STORE Level Actor: TestMap/ChaosVehicleBlueprint_C_1
LogSpudProps: Verbose:  | bHandbrake = 1
LogSpudProps: Verbose:  | Text = 
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose:  * STORE Level Actor: TestMap/PlayerCharacter_C_0
LogSpudProps: Verbose:  | PlayerData:
LogSpudProps: Verbose:  |- PlayerName = Player
LogSpudState: Error: Property PlayerCharacter_C_0/CustomMaterial is marked for save but is an unsupported type, ignoring. E.g. Arrays of custom structs or UObjects (other than actor refs) are not supported.
LogSpudProps: Verbose:  |- Money = 9000
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose:  * STORE Runtime Actor: D42B7F17-4E11-0490-8ACA-ED94898FDD8D (ChaosVehicleBlueprint_C_0)
LogSpudProps: Verbose:  | bHandbrake = 1
LogSpudProps: Verbose:  | Text = 
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose:  * STORE Runtime Actor: 92EB51AC-47AB-1B7C-451B-2CBF9016E0AE (ChaosVehicleBlueprint_C_2)
LogSpudProps: Verbose:  | bHandbrake = 1
LogSpudProps: Verbose:  | Text = 
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudSubsystem: Save to slot TestSave: Success
LogSpudSubsystem: Verbose: Loading Game from slot TestSave
LogSpudSubsystem: Verbose: (Re)loading map: TestMap
LogNet: Browse: /Game/Maps/TestMap
LogLoad: LoadMap: /Game/Maps/TestMap
LogWorld: BeginTearingDown for /Game/Maps/UEDPIE_0_TestMap
LogWorld: UWorld::CleanupWorld for TestMap, bSessionEnded=true, bCleanupResources=true
LogSlate: InvalidateAllWidgets triggered.  All widgets were invalidated
LogAudio: Display: Audio Device unregistered from world 'None'.
LogUObjectHash: Compacting FUObjectHashTables data took   2.08ms
LogPlayLevel: Creating play world package: /Game/Maps/UEDPIE_0_TestMap
LogPlayLevel: PIE: StaticDuplicateObject took: (0.038410s)
LogAIModule: Creating AISystem for world TestMap
LogPlayLevel: PIE: World Init took: (0.001500s)
LogPlayLevel: PIE: Created PIE world by copying editor world from /Game/Maps/TestMap.TestMap to /Game/Maps/UEDPIE_0_TestMap.TestMap (0.040228s)
LogAudio: Display: Audio Device (ID: 8) registered with world 'TestMap'.
LogLoad: Game class is 'GM_Survival_C'
LogWorld: Bringing World /Game/Maps/UEDPIE_0_TestMap.TestMap up for play (max tick rate 60) at 2021.12.07-19.11.48
LogWorld: Bringing up level for play took: 0.003365
LogSpudSubsystem: Verbose: OnPostLoadMap restore: TestMap
LogSpudState: Verbose: RESTORE level TestMap - Start
LogSpudState: Verbose:  * Respawning actor D42B7F174E1104908ACAED94898FDD8D of type /Game/VehicleAdvBP/Blueprints/ChaosVehicleBlueprint.ChaosVehicleBlueprint_C
LogPhysics: Warning: UWorld::FindTeleportSpot called with an actor that is intersecting geometry. Failed to find new location likely due to movement component's 'UpdatedComponent' not being a collider component.
LogSpawn: Warning: SpawnActor failed because of collision at the spawn location [X=0.000 Y=0.000 Z=0.000] for [ChaosVehicleBlueprint_C]
LogSpudState: Error: Error spawning actor of type /Game/VehicleAdvBP/Blueprints/ChaosVehicleBlueprint.ChaosVehicleBlueprint_C
LogSpudState: Verbose:  * Respawning actor 92EB51AC47AB1B7C451B2CBF9016E0AE of type /Game/VehicleAdvBP/Blueprints/ChaosVehicleBlueprint.ChaosVehicleBlueprint_C
LogPhysics: Warning: UWorld::FindTeleportSpot called with an actor that is intersecting geometry. Failed to find new location likely due to movement component's 'UpdatedComponent' not being a collider component.
LogSpawn: Warning: SpawnActor failed because of collision at the spawn location [X=0.000 Y=0.000 Z=0.000] for [ChaosVehicleBlueprint_C]
LogSpudState: Error: Error spawning actor of type /Game/VehicleAdvBP/Blueprints/ChaosVehicleBlueprint.ChaosVehicleBlueprint_C
LogSpudState: Verbose:  * RESTORE Level Actor: INT_Weapon_C_1
LogSpudState: Verbose:  | Class: /CharacterSystemPlugin/Items/INT_Weapon.INT_Weapon_C
LogSpudState: Verbose:  | FAST path, 3 properties
LogSpudProps: Verbose:  | ItemOwner = 
LogSpudProps: Verbose:  | AttachedTo = NULL
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose:  * RESTORE Level Actor: INT_Weapon_C_2
LogSpudState: Verbose:  | Class: /CharacterSystemPlugin/Items/INT_Weapon.INT_Weapon_C
LogSpudState: Verbose:  | FAST path, 3 properties
LogSpudProps: Verbose:  | ItemOwner = 
LogSpudProps: Verbose:  | AttachedTo = NULL
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose:  * RESTORE Level Actor: ChaosVehicleBlueprint_C_1
LogSpudState: Verbose:  | Class: /Game/VehicleAdvBP/Blueprints/ChaosVehicleBlueprint.ChaosVehicleBlueprint_C
LogSpudState: Verbose:  | FAST path, 3 properties
LogSpudProps: Verbose:  | bHandbrake = 1
LogSpudProps: Verbose:  | Text = 
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose:  * RESTORE Level Actor: PlayerCharacter_C_0
LogSpudState: Verbose:  | Class: /Game/Core/PlayerCharacter.PlayerCharacter_C
LogSpudState: Verbose:  | FAST path, 7 properties
LogSpudProps: Verbose:  |- PlayerName = Player
LogSpudProps: Verbose:  |- Money = 9000
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose: RESTORE level TestMap - Complete

@DoubleP90
Copy link
Author

I tried to dig a bit deeper and it seems SPUD works fine, it spawns the vehicle and sets the transform correctly, then the vehicle suddenly gets set to the origin on the next frame, seems more like a bug with the Chaos vehicle, maybe it's some sort of way to prevent it from flying into the air when it's spawned and its readjusts it's position after spawn.

LogSpudState: Error: XForm is 819.826843,102.264748,96.158966|0.265899,29.702862,0.004031|1.000000,1.000000,1.000000 
LogSpudState: Error: Actor new transform is 819.826843,102.264748,96.158966|0.265899,29.702862,0.004031|1.000000,1.000000,1.000000 
LogSpudState: Verbose:  | Class: /Game/VehicleAdvBP/Blueprints/ChaosVehicleBlueprint.ChaosVehicleBlueprint_C
LogSpudState: Verbose:  | FAST path, 3 properties
LogSpudProps: Verbose:  | bHandbrake = 1
LogSpudProps: Verbose:  | Text = 
LogSpudProps: Verbose:  | bCanBeDamaged = 1
LogSpudState: Verbose: RESTORE level TestMap - Complete
LogSpudSubsystem: Load: Success
LogLoad: Took 0.082253 seconds to LoadMap(/Game/Maps/UEDPIE_0_TestMap)
LogBlueprintUserMessages: [ChaosVehicleBlueprint_C_0] Translation: X=819.827 Y=102.265 Z=96.159 Rotation: P=0.265899 Y=29.702862 R=0.004031 Scale X=1.000 Y=1.000 Z=1.000
AnimBlueprintLog: Warning: Trying to play a non-additive animation 'ALS_N_FallLoop' into a pose that is expected to be additive in anim instance 'ALS_AnimBP_C /Game/Maps/UEDPIE_0_TestMap.TestMap:PersistentLevel.PlayerCharacter_C_0.CharacterMesh0.ALS_AnimBP_C_0'
AnimBlueprintLog: Warning: Trying to play a non-additive animation 'ALS_N_FallLoop_Fast' into a pose that is expected to be additive in anim instance 'ALS_AnimBP_C /Game/Maps/UEDPIE_0_TestMap.TestMap:PersistentLevel.PlayerCharacter_C_0.CharacterMesh0.ALS_AnimBP_C_0'
LogBlueprintUserMessages: [ChaosVehicleBlueprint_C_0] Translation: X=-0.012 Y=-0.003 Z=-1.089 Rotation: P=-0.000034 Y=-0.001434 R=-0.000061 Scale X=1.000 Y=1.000 Z=1.000
AnimBlueprintLog: Warning: Trying to play a non-additive animation 'ALS_N_Land_Light' into a pose that is expected to be additive in anim instance 'ALS_AnimBP_C /Game/Maps/UEDPIE_0_TestMap.TestMap:PersistentLevel.PlayerCharacter_C_0.CharacterMesh0.ALS_AnimBP_C_0'
LogBlueprintUserMessages: [ChaosVehicleBlueprint_C_0] Translation: X=-0.024 Y=-0.006 Z=-3.265 Rotation: P=-0.000034 Y=-0.002869 R=-0.000122 Scale X=1.000 Y=1.000 Z=1.000
LogBlueprintUserMessages: [ChaosVehicleBlueprint_C_0] Translation: X=-0.036 Y=-0.009 Z=-6.530 Rotation: P=-0.000034 Y=-0.004303 R=-0.000153 Scale X=1.000 Y=1.000 Z=1.000

@sinbad
Copy link
Owner

sinbad commented Dec 8, 2021

I did actually find a problem with the respawn behaviour, it needs to set ESpawnActorCollisionHandlingMethod::AlwaysSpawn because the initial spawn is at the origin; this is because the details such as the transform are restored later (properties are overlaid on top of existing objects). Commit here: a257c61

When the transform is set later, it's done like this:

Actor->SetActorTransform(XForm, false, nullptr, ETeleportType::ResetPhysics);

This should reset any physics and have the same effect as spawning at that location, but I don't know if there's something that changed with Chaos.

@DoubleP90
Copy link
Author

I had tried adding that myself when testing, will help with spawning if world origin is obstructed but didn't solve the problem with the vehicles for me.
For now I'll keep my workaround of getting the transform after the restore and applying it again a few frames later, I'll wait for the final release of ue5, maybe the behavior will change.

Is there a way to retrieve the transform saved data before the actor is created?

@sinbad
Copy link
Owner

sinbad commented Dec 9, 2021

Is there a way to retrieve the transform saved data before the actor is created?

No, the data structure for the levels is basically packed properties which are overlaid on top of existing actors (this is so that you can restore properties on top of actors which have had new state added since), and there's a separate list of respawns that need to happen before this to ensure the actors are there to update. This allows us to treat spawned actors and pre-existing actors the same, which is important because spawned actors might already exist, if for example you're quick-loading in game.

@sinbad sinbad closed this as completed Feb 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants