Engine crashes when setting properties of AIPerception component

I have a bug to report where when I create an AIPerception Component through C++ and have it exposed to blueprint, setting any of the AI Sight Config properties causes the engine to crash.

Here is what I’m setting:

Here is the crash report when changing any of those values:

Unknown exception - code 00000001 (first/second chance not available)

"Assertion failed: Obj [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.8\Engine\Source\Editor\UnrealEd\Classes//Editor//Transactor.h] [Line: 158] 
"

KERNELBASE
UE4Editor_Core!FOutputDeviceWindowsError::Serialize() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\windows\windowsplatformoutputdevices.cpp:95]
UE4Editor_Core!FOutputDevice::Logf__VA() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\misc\outputdevice.cpp:144]
UE4Editor_Core!FDebug::AssertFailed() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\misc\outputdevice.cpp:355]
UE4Editor_UnrealEd!FTransaction::FObjectRecord::FPersistentObjectRef::operator->() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\editor\unrealed\classes\editor\transactor.h:159]
UE4Editor_UnrealEd!FTransaction::FObjectRecord::FObjectRecord() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\editor\unrealed\private\editortransaction.cpp:32]
UE4Editor_UnrealEd!FTransaction::SaveObject() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\editor\unrealed\private\editortransaction.cpp:241]
UE4Editor_CoreUObject!SaveToTransactionBuffer() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\coreuobject\private\uobject\uobjectglobals.cpp:1723]
UE4Editor_CoreUObject!UObject::Modify() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\coreuobject\private\uobject\obj.cpp:830]
UE4Editor_CoreUObject!UObject::PreEditChange() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\coreuobject\private\uobject\obj.cpp:311]
UE4Editor_PropertyEditor!FPropertyNode::NotifyPreChange() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\editor\propertyeditor\private\propertynode.cpp:1877]
UE4Editor_PropertyEditor!FPropertyValueImpl::ImportText() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\editor\propertyeditor\private\propertyhandleimpl.cpp:405]
UE4Editor_PropertyEditor!FPropertyValueImpl::ImportText() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\editor\propertyeditor\private\propertyhandleimpl.cpp:297]
UE4Editor_PropertyEditor!FPropertyHandleFloat::SetValue() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\editor\propertyeditor\private\propertyhandleimpl.cpp:2160]
UE4Editor_PropertyEditor!SPropertyEditorNumeric<float>::OnValueCommitted() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\editor\propertyeditor\private\userinterface\propertyeditor\spropertyeditornumeric.h:254]
UE4Editor_PropertyEditor!TBaseSPMethodDelegateInstance<0,SPropertyEditorNumeric<float>,0,TTypeWrapper<void> __cdecl(float,enum ETextCommit::Type)>::Execute() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:282]
UE4Editor_PropertyEditor!TBaseSPMethodDelegateInstance<0,SPropertyEditorNumeric<float>,0,void __cdecl(float,enum ETextCommit::Type)>::ExecuteIfSafe() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:388]
UE4Editor_PropertyEditor!SSpinBox<float>::CommitValue() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\public\widgets\input\sspinbox.h:614]
UE4Editor_PropertyEditor!SSpinBox<float>::TextField_OnTextCommitted() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\public\widgets\input\sspinbox.h:544]
UE4Editor_PropertyEditor!TBaseSPMethodDelegateInstance<0,SSpinBox<float>,0,TTypeWrapper<void> __cdecl(FText const & __ptr64,enum ETextCommit::Type)>::Execute() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:282]
UE4Editor_PropertyEditor!TBaseSPMethodDelegateInstance<0,SSpinBox<float>,0,void __cdecl(FText const & __ptr64,enum ETextCommit::Type)>::ExecuteIfSafe() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:388]
UE4Editor_Slate!SEditableText::OnEnter() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\private\widgets\input\seditabletext.cpp:973]
UE4Editor_Slate!FTextEditHelper::OnKeyDown() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\private\framework\text\textedithelper.cpp:191]
UE4Editor_Slate!SEditableText::OnKeyDown() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\private\widgets\input\seditabletext.cpp:1637]
UE4Editor_Slate!<lambda_4f604f87f3ce3f5c3b6a1447676ad634>::operator()() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:3750]
UE4Editor_Slate!FEventRouter::Route<FReply,FEventRouter::FBubblePolicy,FKeyEvent,<lambda_4f604f87f3ce3f5c3b6a1447676ad634> >() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:212]
UE4Editor_Slate!FEventRouter::RouteAlongFocusPath<FEventRouter::FBubblePolicy,<lambda_4f604f87f3ce3f5c3b6a1447676ad634>,FKeyEvent>() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:194]
UE4Editor_Slate!FSlateApplication::ProcessKeyDownEvent() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:3751]
UE4Editor_Slate!FSlateApplication::OnKeyDown() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:3675]
UE4Editor_Core!FWindowsApplication::ProcessDeferredMessage() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\windows\windowsapplication.cpp:1262]
UE4Editor_Core!FWindowsApplication::DeferMessage() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\windows\windowsapplication.cpp:1711]
UE4Editor_Core!FWindowsApplication::ProcessMessage() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\windows\windowsapplication.cpp:706]
UE4Editor_Core!FWindowsApplication::AppWndProc() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\windows\windowsapplication.cpp:628]
user32
user32
UE4Editor_Core!FWindowsPlatformMisc::PumpMessages() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\windows\windowsplatformmisc.cpp:792]
UE4Editor!FEngineLoop::Tick() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\launch\private\launchengineloop.cpp:2323]
UE4Editor!GuardedMain() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\launch\private\launch.cpp:142]
UE4Editor!GuardedMainWrapper() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\launch\private\windows\launchwindows.cpp:126]
UE4Editor!WinMain() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\launch\private\windows\launchwindows.cpp:200]

My C++ class is defined like this: class TESTINGAI_API ATheAIController : public AAIController

So it inherits from AAIController, and my BP inherits from my C++ class.

Hey -

I’m trying to reproduce this on my machine, could you post the code for your TheAIController class so that I can make sure I’m following the same setup?

Cheers

Here is my AIController.h;

#pragma once

#include "AIController.h"
#include "Perception/AIPerceptionComponent.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "BehaviorTree/BehaviorTreeComponent.h"
#include "TheAIController.generated.h"

UCLASS()
class TESTINGAI_API ATheAIController : public AAIController
{
	GENERATED_BODY()

public:

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerSensing")
		UAIPerceptionComponent* AISensor;

	ATheAIController();

	void onPerception(TArray<AActor*> UpdatedActors);

	virtual void Tick(float DeltaTime) override;

	float threatEvalFreq; //at what time shall we evaluate our threats

	float elapsedTime;
};

And here is my AIController.cpp:

#include "TestingAI.h"
#include "Engine.h"
#include "Kismet/KismetSystemLibrary.h"
#include "TheAIController.h"


ATheAIController::ATheAIController(){

	AISensor = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIPerceptionSensor"));
	AISensor->OnPerceptionUpdated.AddDynamic(this, &ATheAIController::onPerception);
	PrimaryActorTick.bCanEverTick = true;
	threatEvalFreq = 5;

}

void ATheAIController::Tick(float DeltaTime){
	elapsedTime = elapsedTime + DeltaTime;
	if (elapsedTime >= threatEvalFreq){
		elapsedTime = 0;
	}
}

void ATheAIController::onPerception(TArray<AActor*> UpdatedActors){

	FActorPerceptionBlueprintInfo Info;
	for (TArray<AActor*>::TIterator it = UpdatedActors.CreateIterator(); it; ++it)
	{
		
		AISensor->GetActorsPerception(*it, Info);
		
	}
}

Hey ,

The best way to declare components is to limit the access to them. You can set the component itself to protected and then use the AllowPrivateAccess meta tag in the UPROPERTY() along with a public Get() function to still access the component without having it be EditAnywhere or BlueprintReadWrite. You can look at the CameraBoom component of the default character from a Third Person template project for an example. Let me know if doing so helps.

Cheers

Is there is a reason why I can’t do it the other way around? I just expose my components through the EditAnywhere and BlueprintReadWrite and it works fine. Is there a disadvantage to doing it this way?

There is not necessarily a disadvantage to doing it that way however there is an advantage to doing it the other way. In the case of using the Get() function it protects the component itself from being unnecessarily edited in the edit when it’s not expected. Using the Camera Boom from the Third Person Template as an example, using EditAnywhere and BlueprintReadWrite would allow the camera boom to be changed from a Spring Arm component to something else inside the editor which could cause other problems. Instead using VisibleAnywhere, BlueprintReadOnly, and meta = (AllowPrivateAccess = “true”) along with a Get() function allowed the values of the component to be edited without being able to change the component itself.

I did what you suggested and I’m not crashing anymore. I guess I’ll start using AllowPrivateAccess from now on. Thanks for the help.

Hey ,

I found this question while researching the same crash, but I DO use AllowPrivateAccess and I still get the crash like clockwork. Any advice?

UPROPERTY(Category = "Wa Combat", VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
	UAIPerceptionComponent* AIPerception;

Best regards,
Damir H.

Hey -

Can you provide more information by posting your callstack and crash logs as well? Does the crash also occur for you when trying to edit the blueprint property values? If possible could you also post the code files where the property is being created/used (header and source).

Cheers