PDA

View Full Version : calling functions from other classes



mafiadude1
01-23-2010, 05:29 PM
Hi everyone,

I was just wondering, how would i 'activate' a function from another class

i.e

exec function Jump()
{
//Tell other class to activate jump function
Class.Jump(); //???
}


The other class

simulated function Jump()
{
StaticMeshComponent.AddImpulse(Vect(0,0,3));
}


Everytime I attempt to do this i get a accessed none error...

Splat
01-23-2010, 05:37 PM
Hey, First you need a variable holding that class

depending on what you are trying to do most of the vars are already created for you

so for example if your pawn controller needs to tell your pawn to execute a non native function you then need to cast the object

like: MyPawnClass(Pawn).Jump();

chess
01-23-2010, 05:38 PM
I don't understand exactly what you're trying to do, and this question was already answered a lot of times. To acces a function from another class you have to typecast (i think that's the word xD) the class instance where the function is.

For example it you want to acces the player controller you have to look for something that relates the class you're in and the player controller, if there's no relation you can always look in the world info, for example:



foreach GetWorldInfo().AllControllers(class'YourPlayerCont roller', PC) {
break;
}


Then the variable PC is a link to your player controller.

Hope it helps, sorry for my english, and try searching the forums a little more...

chess
01-23-2010, 05:39 PM
Ok, splat !·%$&&·!$· xDDDDDDDD you're fast sir xD.

Splat
01-23-2010, 05:41 PM
hehe lol :)

mafiadude1
01-23-2010, 05:43 PM
Hey, First you need a variable holding that class

depending on what you are trying to do most of the vars are already created for you

so for example if your pawn controller needs to tell your pawn to execute a non native function you then need to cast the object

like: MyPawnClass(Pawn).Jump();

what if im extending my 'player' from KActorSpawnable and not Pawn?
would the concept be the same?

chess
01-23-2010, 05:48 PM
Well, the variable Pawn is a class Pawn variable , so no, what controller are you using?

mafiadude1
01-23-2010, 05:49 PM
currently im using PlayerController

chess
01-23-2010, 05:53 PM
And are you able to control the kActor with it? I ask because almost every function from Controller to UTPlayerController refers to the variable Pawn, wich as i said is a class pawn variable :S.
(I'm not even close to being an expert on uscript, but i don't see how that would work).

Splat
01-23-2010, 05:54 PM
Pawn is an extended actor so.....

how are you possessing the KActorSpawnable?

mafiadude1
01-23-2010, 05:55 PM
well my plan was to use exec functions to activate movement functions in the KActorSpawnable class but im constantly bombarded with accessed none errors in the log..
should i use Pawn instead?

Splat
01-23-2010, 05:55 PM
yeah chess, I was just thinking that controllers are designed for pawns

Splat
01-23-2010, 05:57 PM
yes, change to a pawn, I thank that is fundamental

mafiadude1
01-23-2010, 05:58 PM
ok thanks.
ill let you guys know if i have any problems with it.

chess
01-23-2010, 06:02 PM
If you need the properties (i never know if i say this right xD) of a kActor, you should start to build a kPawn (a Pawn from kActor instead of Actor) and to control it you'd have to start from zero, extending object to create a kPlayerController.

I think xD.

I believe that this was discussed in this forums, you should look for "kPawn" or something like that.

Hope you get it to work :P.

Blade[UG]
01-24-2010, 03:35 PM
I don't understand exactly what you're trying to do, and this question was already answered a lot of times. To acces a function from another class you have to typecast (i think that's the word xD) the class instance where the function is.

For example it you want to acces the player controller you have to look for something that relates the class you're in and the player controller, if there's no relation you can always look in the world info, for example:



foreach GetWorldInfo().AllControllers(class'YourPlayerCont roller', PC) {
break;
}


Then the variable PC is a link to your player controller.

Hope it helps, sorry for my english, and try searching the forums a little more...

This code shouldn't work in UE3, as "PC" would be reset to whatever it was before the iterator was called. There is a function in WorldInfo for returning the Local player controller, anyway, though.

If you need to control something that isn't a Pawn, you're going to need to extend PlayerController (since PlayerController is what handles the input), and basically write your entire control system to deal with it there.

chess
01-24-2010, 04:21 PM
:S i use that code and it works :S
About the kPawn i searched it and the last entry of the post was someone proposing that they change the code of pawn and extend it from kActor instead of actor, but i didn't try it and neither didi the person who posted that.

lordofduct
01-24-2010, 05:02 PM
wow a bit of confusion in here of what type casting is actually for.



1) most important... CLASSES ARE NOT OBJECTS! You can not access a function of a class unless it is a static function. You create instances of a class and then access those objects made from the class (object oriented...?)

2) when you store a reference to an object, you store it as a type. You don't have to store it as its direct type, you can store it as one of it's super types.

PlayerController doesn't know exactly what kind of Pawn you are using, it just knows it's a Pawn... so the object is stored as a class'Pawn' in a field names 'Pawn'. Yes it may be confusing that both the name of the field/property is the SAME as the class name, just get used to it, it's the way Epic did it (no matter how hard it makes me want to punch them in the face for confusing the hell out of people, then again I've meet game scripters... and they're an odd bunch).

3) Typecasting is for if you have a reference to an object as a type that you KNOW it is, but isn't already casted as that type.

Again in PlayerController the Pawn is stored as a class'Pawn'... but you KNOW that your pawn is going to be a class'MyPawn'... or atleast you hope it will be (I don't know, it all depends on how you design your game).

So you can typecast that reference to class'MyPawn' so that you can gain access to the interface defined by class'MyPawn'.

If the function is already defined on the interface of the known type (in this case Pawn), that there is NO need to typecast it.




Which leads me to one specific thing to this question...

Pawn already has a jump function defined:

Pawn.DoJump( bool bIsUpdating )

why not override that instead of creating yet another function to do the same thing. Yeah you don't have an exec function anymore... but your Pawn shouldn't have a exec function on it... put that on your PlayerController instead and PlayerController can then tell the Pawn to jump... why? Because there could be 10, 20, 100 different Pawns on screen (multiplayer???)... which Pawn are you trying to tell to jump when you 'exec' Jump through the command prompt (exec are for functions that can be typed into the command prompt)

immortius
01-24-2010, 05:22 PM
exec functions only get called on the Pawn controlled by the local player (or possibly only pawns that are authoritative on a given machine, which is often the same), so that last bit is a non-concern. It is actually handy to have pawn specific exec functions on the pawn so you don't have to worry about them when a player is controlling different pawns - or no pawn at all.

Proof of course is that whenever a pawn feigns death in UT3 it doesn't cause all pawns to feign death.

chess
01-24-2010, 05:27 PM
Uhmmmm but the problem here was that he was trying to possess a kActor instead of a pawn. Again, i don't know if that's the word i ment (i said so in my post), but if you have to access the playercontroller's pawn you (like i call this xD) typecast the player controller into a variable and you access the pawn with Variable.Pawn (i call typecasting holding a reference to an object in a variable, maybe it's something else, english is not my native language, i didn't learn to program in english, and i just recently started to work with uscript :S).

On another note, he cannot acces the DoJump function in his pawn because he isn't using one xD, like i said he was using a kActor.

Anyways... i thought this was already solved-ish, Mafiadude was going to experiment with the info we gave him :S.

Splat
01-24-2010, 05:30 PM
Stop making excuses chess we all know you are from england :p

immortius
01-24-2010, 05:32 PM
Uhmmmm but the problem here was that he was trying to possess a kActor instead of a pawn. Again, i don't know if that's the word i ment (i said so in my post), but if you have to access the playercontroller's pawn you (like i call this xD) typecast the player controller into a variable and you access the pawn with Variable.Pawn (i call typecasting holding a reference to an object in a variable, maybe it's something else, english is not my native language, i didn't learn to program in english, and i just recently started to work with uscript :S).

Typecasting is explicitly converting from one type to another. The word you're looking for is probably assign or assigning, as in "You must assign the pawn to a variable" or some such.

chess
01-24-2010, 05:40 PM
@Splat: Can't you tell i'm Oostralian? xD.

@Immortius: Thanks for the info xD As if speaking a foreign language isn't hard enough i have to learn technical words :S xD.

Well besides all that i still don't really know what lordofduct's post was about :S.
Maybe my misunderstanding of the word typecasting, well... c'est la vie xD.

LennardF1989
01-24-2010, 07:26 PM
Hi everyone,

I was just wondering, how would i 'activate' a function from another class

i.e

exec function Jump()
{
//Tell other class to activate jump function
Class.Jump(); //???
}


The other class

simulated function Jump()
{
StaticMeshComponent.AddImpulse(Vect(0,0,3));
}


Everytime I attempt to do this i get a accessed none error...
But to answer your original question, this is how it should go in any case you don't already have a pointer.


exec function Jump()
{
local OtherClass clsOther;

//Spawn the other class
clsOther = Spawn(class'OtherClass');

//Tell other class to activate jump function
clsOther.Jump();
}

Note that I first make an instance of "OtherClass" before calling its function. If OtherClass were an extension of Object (and not Actor, as above), you do:



//Spawn the other class
clsOther = new(self) class'OtherClass';


Now say OtherClass has a parent called SuperClass and the pointer is stored like that, but your Jump-function is in OtherClass. In that case you do:


exec function Jump()
{
local OtherClass clsOther;

//Cast Super to Child and save the pointer
clsOther = OtherClass(SuperClass);

//Tell other class to activate jump function
clsOther.Jump();
}


Say your class shouldnt be instanced at all (which can happen), then you can choose to make the Jump function in OtherClass static, like so:

static exec function Jump()

In that case, the code in your calling class looks like this:

exec function Jump()
{
//Tell other class to activate jump function
class'OtherClass'.static.Jump();
}


I hope this illustrates the fundamentals, together with lordofduct's great post: http://forums.epicgames.com/showpost.php?p=27098552&postcount=18

The same tricks apply to most native functions, except for the ones in UIScene's, you need to use InitializeScene then.

PS. You might want to look up some OOP-readingfood.

chess
01-24-2010, 07:50 PM
ok thanks.
ill let you guys know if i have any problems with it.

With emphasis on the "ok thanks." part of the post... this was already solved!!!!!! Geez.

LennardF1989
01-24-2010, 08:00 PM
He never got an answer to what he originally asked, which was how to call functions in other classes.

chess
01-24-2010, 08:09 PM
Yes he did, lot's of times, and lots of answers, and that's why he said:

ok thanks.
ill let you guys know if i have any problems with it.

¬¬ :P

CaptAmazing
01-24-2010, 10:18 PM
LordofDuct's post solved this. His problem was not that he was using a KActor as a Pawn (though that could have led him into strife further down the road) but rather that he was never creating an object of the class for which he wanted to call 'Jump()'. Hence, when he tried to access through that class, unrealscript found no object on which to call Jump() and threw "Accessed None".

chess
01-25-2010, 08:07 AM
I don't understand exactly what you're trying to do, and this question was already answered a lot of times. To acces a function from another class you have to typecast (i think that's the word xD) the class instance where the function is.

For example it you want to acces the player controller you have to look for something that relates the class you're in and the player controller, if there's no relation you can always look in the world info, for example:



foreach GetWorldInfo().AllControllers(class'YourPlayerCont roller', PC) {
break;
}


Then the variable PC is a link to your player controller.

Hope it helps, sorry for my english, and try searching the forums a little more...

That didn't solve his problem? Besides the already overlydiscussed misunderstanding of the term typecast ¬¬.

mafiadude1
01-30-2010, 05:27 PM
ok ive changed over to Pawn instead of KActorSpawnable but now im having another problem. Im trying to use the AddImpulse Command within a static function but im not sure how to do this with a Pawn. can someone help me?



Class RollingBall Extends Pawn;


Simulated Event Tick( Float DT )
{
Super.Tick(DT);
}


Static Function AddImpulseUp()
{
`log("ImpulseUP REACHED!!"); //for debugging purposes

SkeletalMeshComponent.AddImpulse(Vect(0,10,0)); //<----Does not work---
}

DefaultProperties
{
Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
bEnabled=true
TickGroup=TG_DuringAsyncWork
End Object

Components.Add(MyLightEnvironment)

Begin Object Class=SkeletalMeshComponent Name=SkeletalMeshComponent0
SkeletalMesh=SkeletalMesh'RollingBallGame.PlayerBa ll'
RBChannel=RBCC_GameplayPhysics
BlockRigidBody=FALSE
LightingChannels=(bInitialized=True,Dynamic=True)
LightEnvironment=MyLightEnvironment
PhysicsAsset=PhysicsAsset'RollingBallGame.PlayerBa ll_Physics'
End Object

Components.Add(SkeletalMeshComponent0)

Begin Object Name=CollisionCylinder
CollisionRadius=+0080.00000
CollisionHeight=+0100.00000
BlockActors=true
CollideActors=true
End Object

Components.Add(CollisionCylinder)


bCollideWorld=true
bCollideActors=true
bBlockActors=true

AvgPhysicsTime=+00000.100000
bPushesRigidBodies=false
RBPushRadius=10.0
RBPushStrength=50.0

Physics=PHYS_Falling
bStatic=false
bMovable=true
}

LennardF1989
01-30-2010, 06:24 PM
Because a static doesn't know anything about instance variables, it's part of the class, not the object. Make the function non-static, cast whatever is calling AddImpulse to RollingBall and call it.

Really, read about OOP, you're knowledge is failing which will make you start hate making your game because you'll keep getting errors you don't understand off why.

Look up things like call-by-reference, static functions and variables, instances, objects and classes.