Download

Switching possession between two pawns.

Hello!

I need your help with possessing pawns in my game.

I have two pawns in my game:

  • the main player
  • the pawn that will appear when certain key is pressed and gets destroyed after 5 seconds after it’s created.

I’ve added the possession code in my gamemode class, where I use TObjectIterator to iterate over my PaperCharacters I have - there are and there will be only two of them in my game.

I was wondering whether I could add some boolean setters and getters in my playercontroller class, but I can’ t understand how to overwrite the playercontroller in my player class (derives from APaperCharacter class) for example… or create some kind of class which hold the information about possessing.

I also wondered I could use somekind of PaperCharacter counter. Everytime when there are 2 PaperCharacters, the other character will be controlled and when there’ s 1 PaperCharacter, the player character will be controlled. However, it might use too much resource when it would have to count PaperCharacters every frame.

The real problem with this is that I don’ t know how to hold possession for 5 seconds before the created object gets destroyed.

I’ve trying to understand this logic for 1 day already. Don’ t know what to do… Thanks in advance!

I would say that you are going about your process of discovery badly. First, before you want to make a game with characters and objects, you need to learn how to use classes and functions. To me your question of whether a certain process will take too much resources, indicates your problems lie in planning too many steps without focusing on a given aspect adequately. It is important that you test a particular aspect with the simplest case possible, in order to ensure you fully grasp necessary concepts like variable scope. Many times people want to skip ahead to things like transformation matrices, without first seriously asking themselves why they are using classes in the first place. People are taught in school and everywhere else that classes are necessary, and that they are in fact what c++ is all about. This is actually false. I did not have anyone tell me this, I discovered it on my own. Classes make thinks slower, more complicated and more tedious. Unless you are smarter than me and can use them in a manner I do not understand.
OK then, if we should not use classes, then how do you make a program? A program is actually only functions and variables. The thing classes introduce is neither of these things. Classes control, or they were intended to control the scope of functions and variables together as a single local group. If this sounds confusing, its because it is confusing. Functions already had local scope for any variables declared within a function, while all variables declared outside functions (generally in header file) have global scope. The reason this was important in the 80s and 90s, was the limited amounts of RAM computers had then made it possible to run out of memory. This is still an issue, however, it is a different situation. The problem lies with a thing called the stack. It has a limited memory, I think 1Mb. It is essentially a form of fast processer cache. If more memory is returned from a function than this 1MB limit allows, it produces a stack overflow, and the program crashes. This was not really a problem in the 80s and 90s, because games were less sophisticated. Anyway got lost on a tangent there, and yes I am aware that nearly every human being on the planet writes their software using classes, so everyone who thinks I’m wrong can save their time and just consider the possibility that you don’t know everything.

That has got to be the longest non-answer I’ve ever read. The only way you’ll get anywhere modding unrealengine is if you understand classes, all that talk of not needing them is irrelevant here.

Rasponien: It looks like you’ve got some research to do, you are confusing the controller and the character.

The controller = the interface between the human and the world
The character = the pawn/avatar that the controller (and hence the human) moves.
The game mode = the rules for the game (start state, in progress state, winning state)

The unreal engine already possesses you a pawn by default, the game rules and the controller handle that. Embrace that functionality, don’t try and change it :slight_smile:

Your request read as I need to be able to press a button, spawn a copy of my character, possess it, then have it die and return to the original character.
So…

  1. Create a method called “Deposess” on the character class. IT should
  • Call a method on the controller to revert to the previous character
  • Call its destroy method to delete the character
  1. Create a method on the character class that will run a timer.
  • The timer should call the “Deposess” function after 5 seconds.
  1. Create an exec method on the controller that will spawn a new character. This function should
  • Spawn the new character
  • store a reference to the currently possessed character
  • possess the new character
  • call your timer method
  1. Create a method on the controller that will restore the originally possessed character
  • This should call posess on the referenced character you stored off in 3

Obviously this is just a vague hand wavey bullet list of tasks. You’ll need to research EXEC functions, timers, possess, unpossess and destroy stuff within the unrealengine codebase. On the plus side, it saves you having to count things, and you now have a rough plan for how you could do what you are trying to achieve :cool:

Come back and ask about each one as you find documentation for it and as the question will be more focused on how to use it, you’ll get more specific answers on each bit.

Hey! Thanks a lot for providing help, GeekyPayback, I truly thank you.
Paul88, you clearly didn’ t answer to my question rather pointed out that I shouldn’t separate my code into classes? - you know how this will end - the code will be ugly and there will be problems understanding the code you wrote… Also… your code will turn into a large spaghetti code monster.
I know about the principles of OO programming, but then again… yes, I’ve got much to learn as UE4 is a really large quantity of stuff I’ve not been aware of, but offers so much at the same time.

Now about the problem I have. I have to ask few things for clarification:
Should I write the possession logic into gamemode class - is this basically the main class where the game logic stays?
I created my own playercontroller and I understood it is not neccessary. How am I supposed to get the exact instance of the playercontroller when I want to switch possession? there are two PaperCharacters in the game, they both have different playercontroller instances then?

Here’s how I’ve written my possession code in my gamemode class now - I call this function frame by frame in Tick function. Right now I’ve eliminated some dumb extra conditions I was trying to create there. So right now, it’s just running this function over and over.
d6f1d127ae5d0490d02d5b894647c74b86b8620d.png
I’ve overriden this function to use my playercontroller.
fb3281ad1fb24a251cb62886f080084402aa2e07.png
Here’s the destroy function I wrote. I read that K2_DestroyActor() function calls out DestroyActor() function (and is somewhat better than DestroyActor() function), so I should use this instead… and after that I of course use garbagecollection. Otherwise there will be some kind of empty object (which I had problem with) till the next garbagecollection.
3b36f97fc074de58748724567d8fac16f0e90f5c.png

Oh and if I create those functions in my character classes, how am I supposed to call them in my gamemode class? I don’ t create any objects in my gamemode right now. One of them is created by setting the class as defaultpawn and the other gets spawned once I press a certain button.

Anyways. Here’s the stuff I’ve been doing lately. I need answer for my first questions. This could show me alot what to do next :slight_smile:
Thanks again!

I forgot to mention I already created a spawn function:
c2e1f0f52e566178dbd560ed00266b5c.png

Oh. And I’ve got this timer event created. It’s being called whenever the object is spawned in world.
7e0c2587ef0785a6920e1abfd369b1ef.png

How to do the following:
“store a reference to the currently possessed character”

EDIT:
I think I found an answer to the last question - it’s the Instigator of the bullet, right? I could use the Instigator pawn as the reference to my actual player character.

Should I write the possession logic into gamemode class - is this basically the main class where the game logic stays?
No. The gamemode logic covers - where the game starts, where the game ends, whether there is a warm up time. Who is winning, who is loosing etc. This is totally the wrong place.

Your custom player controller is absolutely necessary. It is the interface between the player and your game world. One of the things you want to do is trigger spawning a second character. This should go into the controller class (if you want to repeately spawn bullets no matter what pawn you are currently controlling) or the pawn class if its a skill specific to the pawn (so bullets cant spawn more bullets).

Your spawnplayercontroller function is pointless, it creates a character, casts it to a subclass and then returns it as a pointer the parent class anyway (making everything you’ve written there redundant).

In your function that creates the bullet you have the perfect opportunity to do your work.

First though, an UnrealEngine forum tip - use the


 tags to put your code in, then we can copy and paste it back with fixes. I'm having to rewrite your code from images :p.  You on the otherhand, will be able to just copy and paste what I've written back into your game :)



void AMyPlayerCharacter::UseTeleportGun() {
… All your stuff I cant be bothered to type out…
projectile->GetMovementComponent()->Velocity = FVector(20.f, 0.f, 0.f);

AMyPlayerController* PC = Cast(GetController());
PC->BecomeBullet(projectile);
}




Then in that controller you claim you dont need ;)



//MyPlayerController.h

class AMyPlayerController{

… Your code here …

private:

APawn *PreviousPawn; // Create a variable to store a reference to the pawn we will repossess after we finish with the bullet
}






// MyPlayerController.cpp

void AMyPlayerController::BecomeBullet(ATeleportGunBullet* Bullet)
{
PreviousPawn = GetPawn(); // Store a reference so we can repossess this pawn
Possess(Bullet);
}

void AMyPlayerController::BecomeCharacter()
{
if (PreviousPawn == nullptr)
return;

Possess(PreviousPawn);
PreviousPawn = nullptr;
}




Then in your bullet class



void ATeleportGunBullet::destroyActor()
{
AMyPlayerController* PC = Cast(GetController());
PC->BecomeCharacter();
… Your code here (but I think its pointless as calling Destroy should do the same) …
}




And there you go, thats all the steps I outlined and you didnt need to use a tick or count characters to achieve it.

Thanks alot… :slight_smile:

I’m very sorry I didn’ t add my code between code tags. It seems I’m very dumb right now in understanding UE4, it seems there’s alot to learn.
I’m very pleased with this answer. I think I might have done this very differently when you hadn’ t helped me with this. Thanks again :slight_smile:

Anyways, could you tell me how did you manage to get that far understanding UE4? I’m struggling hard to get there, but can’ t really find code examples to understand where I should do/not do something. I’ve used game templates as one of my information source, but yea - there’s lack of information about C++ programming in UE4 :frowning:

Isn’t it easier to do the same thing using the following code:



void AMyPlayerCharacter::UseTeleportGun() { 

                // code for spawning a turret...

		FActorSpawnParameters spawnParameters;
		spawnParameters.Owner = this;
		spawnParameters.Instigator = Instigator;

                class ATeleportGunBullet *projectile = GetWorld()->SpawnActor<ATeleportGunBullet>(bulletPosition,
			Controller->GetControlRotation(), spawnParameters);

                Cast<AMyPlayerController>(Controller)->Possess(projectile);

}




void ATeleportGunBullet::destroyActor()
{
	if (this->IsValidLowLevel())
	{
		Cast<AMyPlayerController>(Controller)->Possess(GetInstigator());
		K2_DestroyActor();
		GetWorld()->ForceGarbageCollection(true);
	}
}


What I mean, I don’t use any of the functions that you told me to use. Instead of using my playercontroller’s PossessBullet function I just possess the spawned bullet directly in the void AMyPlayerCharacter::UseTeleportGun() function.
Instead of using my playercontroller’s PossessPlayer function I just possess the spawned bullet Instigator right before I destroy it in void ATeleportGunBullet::destroyActor() function.

Is this better solution or I should split my code into the playercontroller I created?

It comes down to what you plan to do with the game. If it’s single player your approach will work, means less code to maintain, so is better and you can probably ditch the controller (unless you get onto more advanced stuff)

If you are thinking of adding multiplayer then you need the controller as there will be multiple pawns in the world.

As for how I know this stuff. I’ve been playing with the Unreal engines since the year 2000. Entered the make something unrealengine contest with Action Unreal Tournament, that was the last serious thing I released. The point is the concept of game mode, player controller, pawn hasn’t changed for 16 years :). Pretty much anything you want to do you can find an example in c++ in the shootergame source or the Unreal tournamenet source. What you are trying to do is very similar to the redeemer missile in the UE games, which is how I knew what to tell you :slight_smile:

Any tutorial you find for blueprints can be cast over to c++.

Thanks alot for sharing your thoughts with me. I appreciate it :slight_smile:

Just a small tip, don’t use dynamic_cast, use the engines static ‘Cast’ function instead.