Pointer related UE4 crash. Where are my pointers wrong? - c++

I'm creating a third person laser tag shooter thing for fun and I'm having difficulty creating my weapon hierarchy. My main problem is my editor is crashing from an access error from some errors from pointers in my code and I don't understand pointers enough to be able to figure this out myself.
I'm trying to add a weapon to my default pawn ALTPlayer. I'm doing this by using TSubclassOf to ensure I can only attach children of ALTWeapon to my character
If it helps my explanation, current hierarchy is:
APawn->ALTWeapon->ALaserGun
... and I'm planning on adding a bunch more classes with ALTWeapon as their parent. I'm hoping this will make my code organized and easier to code different functionality for each weapon.
With that in mind, I'll start with my ALTPlayer.h file. Here I declare WeaponClass as my subclass variable
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "LTPlayer.generated.h"
class ALTWeapon;
UCLASS()
class LASERTAG_API ALTPlayer : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values
ALTPlayer();
// Player weapon
UPROPERTY(EditAnywhere)
TSubclassOf<ALTWeapon> WeaponClass;
};
Now I'll move into my ALTPlayer.cpp file. Here I'm trying to create an ALaserGun object that's stored in WeaponClass. (I'm also not sure if this is exactly how I'm supposed to do this)
#include "LTPlayer.h"
#include "LaserGun.h"
// Sets default values
ALTPlayer::ALTPlayer()
{
// Creating Weapon
this->WeaponClass->GetDefaultObject<ALaserGun>();
}
At this point, I expect to see an ALaserGun component in my blueprint child of ALTPlayer. Although, since I have the pointer issue that's crashing my editor, I don't know if that's what this code produces.
If anyone has any insight on how to fix my pointers so that I don't get an access violation, that would be awesome!

You're attempting to dereference WeaponClass when you try to access its default object but it hasn't yet been assigned to anything.
You can initialize it in the constructor initializer list, like so:
ALTPlayer::ALTPlayer()
: WeaponClass(ALTWeapon::StaticClass())
{
}
If this is a class that can be set in a Blueprint default, you can also ensure that it has a value by setting it in PreInitializeComponents:
Declaration:
//~ Begin AActor Interface
virtual void PreInitializeComponents() override;
//~ End AActor Interface
Definition:
void ALTPlayer::PreInitializeComponents()
{
Super::PreInitializeComponents();
// Fallback to default Weapon class if none was specified.
if (WeaponClass == nullptr)
{
UE_LOG(LogGameMode, Warning, TEXT("No WeaponClass was specified in %s (%s)"), *GetName(), *GetClass()->GetName());
WeaponClass = ALTWeapon::StaticClass();
}
}

Related

Why can't I create a TSubclassOf<> to use in a SpawnActor() function?

I'm making a laser tag game in UE4 and I'm having a ton of difficulty using TSubclassOf<>.
First, I'm declaring LaserClass in my LaserTagCharacter.h file like this. I'm also creating a function called OnFire() that's called when the player uses the "Fire" action binding.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "LaserTagCharacter.generated.h"
UCLASS()
class LASERTAG_API ALaserTagCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values
ALaserTagCharacter();
UPROPERTY(VisibleAnywhere, Category = "Laser")
TSubclassOf<class ALaserTagLaser> LaserClass;
protected:
// Called when player fires a laser beam
void OnFire();
};
Now I want to implement my OnFire() function to create a laser from my ALaserTagLaser class using a SpawnActor<> function. I'm doing that like this.
#include "LaserTagCharacter.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "LaserTagLaser.h"
#include "Engine/World.h"
// Sets default values
ALaserTagCharacter::ALaserTagCharacter()
{
}
// Called when player uses fire action binding
void ALaserTagCharacter::OnFire()
{
UWorld* World = GetWorld();
FVector SpawnLocation = GetActorLocation();
FRotator SpawnRotation = GetControlRotation();
FActorSpawnParameters SpawnParameters;
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
World->SpawnActor<ALaserTagLaser>(LaserClass, GetActorLocation(), GetActorRotation(), SpawnParameters);
}
All of this code compiles, but when I click play, open the output log, and use my "Fire" action binding I get this error.
LogSpawn: Warning: SpawnActor failed because no class was specified
I'm confused because I clearly specified what class I wanted to be spawn. If anyone can offer some insight that would be awesome.
TSubclassOf is just a UClass*. In your code, you never assign it. So it's always LaserClass == nullptr.
For the actor to spawn correctly, you need to assign the LaserClass variable to the class you intend to use. For example, if you want to spawn a ALaserTagLaser call LaserClass = ALaserTagLaser::Static_Class() before your SpawnActor.
If you want to assign a BP class to LaserClass, then set it in the Unreal editor. For this, you need to either set it with a set LaserClass node in the Blueprint graph, with the target being an instance of ALaserTagCharacter, or by selecting a default value in a child class of ALaserTagCharacter in details panel in the dropdown.
You need to assign LaserClass a valid class or subclass. In your BP, you can set it in the details panel. If you don't want to use it like that in a BP and always want to spawn a ALaserTagLaser, you can just give SpawnActor a class reference instead.
World->SpawnActor<ALaserTagLaser>(ALaserTagLaser::StaticClass(), GetActorLocation(), GetActorRotation(), SpawnParameters);

C++ object method calling methods from another class that includes it's

First of all, sorry for the title. I didn't know exactly how to give name to the situation I'm facing.
I am developing a project in C++ that will run over QNX (so answers that recur to Windows libraries are not good).
I have one class that holds and manipulates all my data, and a few other classes that are responsible for dealing with my UI.
The UI manipulating classes include my data class, and when they are initialized, they all get a pointer to the same data object (each one uses different parts of it, though). And the normal flow of the program is the UI receiving events from the user, and then making calls to the data class and updating itself, according to the data class replies. That all works just fine.
The problem is, sometimes it might happen that this data class object receives calls from other sorts of external events (let's say a call from a class responsible for communication), asking it to change some of it's values. After doing so, it would have to update the UI (thus, having to make a call to the UI classes).
The actual objects to all the classes (UI and data) are contained by the "main" class. But as the UI classes include the data class to be able to call it's methods, the data class including UI classes in order to be able to call their methods would fall into mutual inclusion.
The problem resumes, in a very simplistic way (I am just trying to give a visual example of the information flow), to something like this:
main.cpp
#include "interface.h"
#include "data.h"
Data data_;
Interface interface_;
// Initialize all data from files, etc
data_.Init();
// Call the interface that will use all of this data
interface_.Init(&data_);
while(1);
interface.h
#include "data.h"
class Interface
{
Data *data_;
void Init(Data *data);
void ReceiveEvent();
void ChangeScreen (int value);
};
interface.cpp
#include "interface.h"
void Interface::Init(Data *data)
{
// Get the pointer locally
data_ = data;
}
// Function called when a (for example) a touch screen input is triggered
void Interface::ReceiveEvent()
{
ChangeScreen(data_->IncreaseParam1());
}
void Interface::ChangeScreen (int value);
{
// Set the value on screen
}
data.h
class Data
{
int param 1;
void Init();
int IncreaseParam1();
void ReceiveExternalEvent();
};
**data.cpp"
#include "data.h"
void Data::Init()
{
// The value actually come from file, but this is enough for my example
param1 = 5;
}
int IncreaseParam1()
{
param1 += 5;
return param1;
}
// This is called from (for example) a communication class that has a
// pointer to the same object that the interface class object has
void ReceiveExternalEvent()
{
IncreaseParam1();
// NOW HERE IT WOULD HAVE TO CALL A METHOD TO UPDATE THE INTERFACE
// WITH THE NEW PARAM1 VALUE!
}
I hope I made myself clear enough.
Can someone please give me ideas on how to deal with this situation?
Thanks a lot in advance!
Both Data and Interface are singletons. You expect to only have one instance of each class in existence. So:
Class Data {
public:
static Data *instance;
Data()
{
instance=this;
}
// Everything else that goes into Data, etc...
};
Class Interface {
public:
static Interface *instance;
Interface()
{
instance=this;
}
// Everything else that goes into Data, etc...
};
Now, ReceiveExternalEvent() will simply invoke Data::instance->method() and/or Interface::instance->method(), and so on...
This is a classical singleton design pattern.
Also, you might find some additional Google food of likely interest to you: "model view controller" and "mvc".

Pointer to incomplete class type is not allowed.( In combination with classes referring to each other.)

I am stuck with something and I seem to keep running against different problems over and over again. It should be pretty simple, I just don't know exactly what I am doing here because I am pretty new to C++.
I have a main class that creates a manager for GUI items. The manager will create the GUI items and update them etc.
The GUI items have their own code that controls their own behavior. But for some things I would like to have a pointer to the GUI manager from these GUI items.
This means my GUI manager needs pointers of the items to be able to create the items. But those items also need a pointer to this manager.
Because it is not possible to include each other I only included the item inside the manager. Like this in the header file of the manager:
erGuiManager.h
#pragma once
#include "ofMain.h"
#include "erGuiItem.h"
class erGuiManager {
public:
erGuiManager();
void update();
void draw();
void setup();
erGuiItem* btn;
};
I create items like this in the erGuiManager.cpp, and send a reference from the manager to the item.
#include "erGuiManager.h"
void erGuiManager::setup() {
btn = new erGuiItem();
btn->setup(this); //THE SETUP GETS A REFERENCE TO THE MANAGER
}
// and update them etc
Now I create a pointer to the manager in the erGuiItem.h, and I do not include the Manager.h, but I only declare it so the compiler knows it is a class:
#pragma once
#include "ofMain.h"
#include "ofImage.h"
class erGuiManager; //DECLARING THE MANAGER
class erGuiItem {
public:
erGuiItem();
void setup(erGuiManager* GuiManager);
protected:
erGuiManager* GM;
};
Then in the setup function I get the pointer send by the manager and declare it to the pointer in the erGuiItem.cpp:
#include "erGuiItem.h"
void erGuiItem::setup(erGuiManager* GuiManager) {
GM = GuiManager;
}
void erGuiItem::update() {
GM->somevariable = variable; //HERE IS WHERE THE ERROR OCCURS
}
Then I try to do something with this pointer to the manager somewhere in my code from my item, as you can see above. And that is where I get the error Pointer to incomplete class type is not allowed..
Now I know where this problem is coming from, I only declared the class erGuiManager, and I did not define it properly. But I have no clue how to do this otherwise. Normally I would have to #include the manager to fix this, but because the manager already includes erGuiItem, I can't.
Can someone explain to me how to-do this properly?
I will keep searching for a solution, if I find one myself I will post it here. Thanks for any help in advance!
Alexander
In erGuiItem.cpp you #include "erGuiManager.h".

Inheritance in Arduino Code

I'm writing some Arduino code and attempting to use inheritance in some classes. I have a class "Actor" (my base class) and a class "Marble" (which inherits from Actor). Here are the header files:
Actor.h:
#ifndef Actor_h
#define Actor_h
#include "Arduino.h"
class Actor
{
public:
Actor();
void speak();
private:
};
#endif
Marble.h:
#ifndef Marble_h
#define Marble_h
#include "Arduino.h"
#include "Actor.h"
class Marble : public Actor {
public:
Marble();
virtual void speak();
private:
};
#endif
Actor.cpp:
#include "Arduino.h"
#include "Actor.h"
Actor::Actor()
{
}
void Actor::speak() {
Serial.println("Actor");
}
Marble.cpp:
#include "Arduino.h"
#include "Marble.h"
void Marble::speak() {
Serial.println("Marble");
}
And finally, in the loop function I do:
void loop() {
Marble marble;
Actor children[2];
children[0] = marble;
children[0].speak();
Which results in "Actor" being printed.
I discovered this nice link which seems similar to my issue, but the resolution does not seem to work for me:
http://arduino.cc/forum/index.php?topic=41884.0
So. It seems like when I create my array of "Actors" and try and stick Marble in there it gets cast to an Actor, or something like that. Problem is, I'll have a few different characters that will all inherit from "Actor" and I'd like an array of them to iterate over and call overridden methods on them.
So, perhaps the problem is how I'm approaching this problem, or maybe there's some syntax errors? I don't know!
Thanks for your help,
Kevin
You need to declare speak as virtual in the Actor class, not just in the Marble class; without that, Actor::speak is a non-virtual function, so you will always be called in preference to the virtual Marble::speak.
For what it's worth, this has nothing to do with the Arduino: it's just a straight C++ issue.
Your problem is that children is an array of type Actor. The line children[0] = marble is taking a Marble object, converting it to an Actor object and copying the results to children[0]. Since the call to children[0].speak() is on an Actor, you get the Actor version.
In order for this to work the way you want, you need to copy a pointer or reference to the object rather than the object itself. That is, you want something like `Actor* children[2]':
Marble marble;
Actor* children[2];
children[0] = &marble;
children[0]->speak();
Of course if children has scope outside of loop, this will fail utterly and you'll need to use new to create your marbles.
Better yet, assuming Arduino has the STL, you should use vector and shared_ptr or something similar.
[Update] As Philip notes, this will also require that the speak method in Actor be declared virtual.

Segfault when using std::set of pointers... can anyone explain this?

In my game I created a base class called Entity which I store in a set for processing. All my game objects derive from this class, and I have no problem adding the derived pointer types to the set in my initialization function.
The problem lies in adding new elements from within an Entity's Step() function. Now, before I get too far into it I'll show you some simplified code:
class GameState
{
public:
GameState();
~GameState();
...
set<Entity*> entities;
void Add(Entity* e);
void Remove(Entity* e);
protected:
set<Entity*> added, removed;
};
class Entity
{
public:
Entity();
Entity(GameState* parent);
virtual ~Entity();
virtual void Step(const sf::Input& input);
...
virtual void Destroy();
protected:
GameState* game;
};
The functions Add and Remove in GameState simply add the argument e to the added and removed sets respectively. In the main loop (elsewhere in GameState), I move the elements from added to entities before processing and after processing I remove elements from removed from entities. This ensures that entities is not modified during iteration.
The Add/Remove functions are very simple:
void GameState::Add(Entity* e)
{
added.insert(e);
}
void GameState::Remove(Entity* e)
{
removed.insert(e);
}
Every derived Entity is passed a pointer to GameState in it's constructor that it keeps as game. So theoretically from the Step function I should be able to Add and Remove entities with a simple call like game->Remove(this);, but instead I get a segfault. After a night of googling and coming up with nothing, I was able to work around (part of) the problem by implementing Entity::Destroy() like so:
void Entity::Destroy()
{
game->Remove(this);
}
So my first question is: Why does this work when I'm in the base class but not in the derived class?
Even more puzzling to me is Add(). Why does Add(new Explosion(16,16,this)) work in GameState but game->Add(new Explosion(16,16,game)) doesn't work inside my object?
I ran it through gdb and it tells me:
Program received signal SIGSEGV, Segmentation fault.
At c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:482
The code that throws the error is:
_Link_type
_M_begin()
{ return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } //this line
So to sum it up I have no idea why my pointers break the STL... and I get that grave feeling that I'm missing something very basic and its causing all these headaches. Can anyone give me advice?
Why does Add(new Explosion(16,16,this)) work in GameState but
game->Add(new Explosion(16,16,game)) doesn't work inside my object?
If that is the case then the only possible explanation is that the Entity's game member doesn't actually point to the GameState. Check that it is being set properly on construction and verify before you use it.
This has nothing to do with std::set. The problem is that you are using an std::set that is part of a class that you are accessing via a corrupt pointer.