Friday, December 2

Unrealscript Overview Part Two : NPC Pawn

The second class to look at is Pawn. The Pawn class extends the Object and Actor class and is responsible for most in-game entities. PostBeginPlay() is the method that is called when all engine-side initialisation of an actor is complete, so we usually do setup in here. In the case of the player, this means also spawning a default controller.


In BubblePawn, we are also initalising a material instance, an instance of a Material created with the Material Editor and given some named parameters within that editor. Creating a Material Instance lets us vary those parameters on a per-instance basis without creating a whole new material. This is what this looks like in the content browser.

..and in the Material Editor.



Tick() is the routine called every time the game state is updated. Overriding it enables you to completely alter the behavior of a given Pawn. In our case we are simply moving the bubble upward and varying it's scale to give a throbbing effect.


We are using dynamic lighting in our environment and thus we define properties for dynamic lighting of the object in our default properties. To aid speed we also turn off as many collision checks as possible. The static mesh component that we add is the mesh drawn by the renderer for this Pawn. The components are simply entries in a dynamic array of components and may be created or destroyed dynamically. The sprite removal is to simply remove a default placeholder sprite automatically added by the system, as this is a placeable and can actually be placed in the editor in the scene.






class BubblePawn extends Pawn placeable;



var float   accumulatedTime;

var StaticMeshComponent BubbleMesh;

var MaterialInstanceConstant MatInst;



simulated event PostBeginPlay()

{

 local LinearColor specularColor;



 accumulatedTime = FRand() * 180.0;

 super.PostBeginPlay();

 `log("spawning bubble ... ");

 SpawnDefaultController();

 MatInst = new(None) Class'MaterialInstanceConstant';

 MatInst.SetParent(BubbleMesh.GetMaterial(0)); 

 BubbleMesh.SetMaterial(0, MatInst);

 MatInst.SetScalarParameterValue('LavaEmissiveMultiplier', FRand());

 MatInst.SetScalarParameterValue('LavaSpecularPower', FRand() * 16.0); 

 specularColor = makeLinearColor(FRand(), FRand(), FRand(), 1.0);

 MatInst.SetVectorParameterValue('LavalSpecularColor', specularColor);

}



event Tick(float DeltaTime) 

{

 accumulatedTime += DeltaTime;

 SetDrawScale( 1.0 + 0.75 * Sin(accumulatedTime) );

 Move(self.Velocity);

 super.Tick(DeltaTime);

}





defaultproperties

{

 WalkingPhysics=Phys_NONE

 bCollideActors=false

 bCollideWorld=false

 DrawScale3D=(X=32.0,Y=32.0,Z=32.0)

 bNoEncroachCheck = true

 bIgnoreEncroachers = true

 ControllerClass=class'LavaLamp.BubbleController'

Begin Object Class=DynamicLightEnvironmentComponent Name=BubbleLightEnvironment

 ModShadowFadeoutTime=0.25

 MinTimeBetweenFullUpdates=0.2

 AmbientGlow=(R=.25,G=.25,B=.25,A=1)

 AmbientShadowColor=(R=0.15,G=0.15,B=0.15)

 LightShadowMode=LightShadow_ModulateBetter

 ShadowFilterQuality=SFQ_High

 bSynthesizeSHLight=TRUE

End Object

Components.Add(BubbleLightEnvironment)

Begin Object Class=StaticMeshComponent Name=InitialMesh

 StaticMesh=StaticMesh'Lava.Meshes.Bubble'

 bOwnerNoSee=false

 LightEnvironment=BubbleLightEnvironment;

 BlockRigidBody=false

 CollideActors=false

 BlockZeroExtent=false

 BlockNonZeroExtent=false

End Object

Components.Add(InitialMesh);

Components.Remove(Sprite);

BubbleMesh = InitialMesh

name='Bubble';

}

2 comments:

Steffen Rye said...

Hello!

Nice tutorial! I'm actually just looking for a little help when it comes to a very little part of the tutorial :P
How can you animate that material instance you create? I would most likely like to know if I can "call" that material inn kismet / matinee in the editor so I can animate it using Matinee.

You see, I have this problem: I can easily animate material instances I create in matinee if it's on something that's not the Pawn. But putting the same material on the pawn and it won't work.
I can drag the skeletalmesh I use for the pawn out in the world and see that the material is animated there as well. But not on the pawn.

I do not have that much uScript experience, but what I suspect is that whenever the pawn is created, it puts the material the skeletalmesh uses (if no other specified) in an array. And since it's inside an array it's automatically some sort of instance that I don't see in the content browser. Do you know if there is some way to use that material in kismet / matinee? Or do I have to animate them in uScript? I would rather use matinee because there I know how to gradually change parameters, not just instant.

John Connors said...

The lines you are looking for are the SetXXXParameter (eg SetScalarParameter) ones. The SkeletalMesh goes into the components array of the Pawn, and the Materials array is a member of SkeletalMesh. Hence I can see it might be awkward outside of Unrealscript; although I'm no expert on Matinee or Kismet. I've also assigned a reference to the mesh to a member variable 'BubbleMesh' to make it easier to reference. Pawn has a Mesh member that is also used in a similar way. I'm not sure if all this helps with Matinee/Kismet, but it's relatively easy in Unrealscript.