sega 500 camera transitions using delegates jeff “ezeikeil” giles [email protected] jgiles

62
Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles [email protected]

Upload: isabelle-eagleton

Post on 15-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Sega 500

Camera Transitions using Delegates

Jeff “Ezeikeil” [email protected]://gamestudies.cdis.org/~jgiles

Page 2: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Last day

We discovered how to do some really cool stuff with the camera Through the playercalcview function. Modification of the user.ini to create

executable functions. How to manipulate the game speed to create

“bullet time”.

Page 3: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Today

Our goals are a bit more modest. Well be expanding on last days class by creating camera transitions on key presses & events.

Page 4: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

So to get started, were going to make the player the focus of the camera.

Then well build functionality to make the camera move from one location to another while watching the player.

Page 5: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

In effect, we’ll be creating a camera which can view the player from the front, back, left or right side and remain locked to this new position.

Page 6: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

The first thing to do is set the camera to a new position in space from which to view the player.

Making some adjustments to the code, I’m after behind and above POV to start.

Page 7: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

Using a vector…which means how we calculated it is going to be a bit different

cameraOffset=vect(-200,0,50) // behind & above

More on this in a moment…

Page 8: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

In effect, you can consider this offset to be in model space i.e. relative to the player and not the world origin.

200 units back 75 units up

70

200

Page 9: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

At the moment, we’ll keep this as a fixed distance until we’re setup.

Now, here’s an odd note. One would think that, being a variable declared in this class, that we should be able to set its values in the default properties

…sounds reasonable right?

Page 10: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

Well, welcome to more UT oddness. We can set *most* variables in the

defaults…except vectors. If you do this:defaultproperties{ cameraOffset=vect(-200,0,50) // behind & above}

It won’t work, nor will it log an error. Your vector gets set to (0,0,0)

Page 11: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

Now I’ve not tested it with all the variable types, but I would expect that this occurs with rotators and most of the structs…If not all.

You’ll have to set them up in a initialization function such as PostBeginPlay()

However, setting individual properties of a struct works fine.

Page 12: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

Now we set our Camera’s location to that of the player & offset it by the desired amount…

I’m not using the cameraOffset here just for clairity

CameraLocation = ViewActor.Location;

CameraLocation += vect(-200,0,75);

Page 13: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

The next step is to set up the camera’s rotation to ALWAYS look at the player.

CameraRotation = rotator( ViewActor.Location-CameraLocation );

Remember what we’re doing here? We’re getting a vector between the locations & casting to a rotator (or unit vector) to get it’s direction.

Page 14: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

Now if we run it, we should have a camera that always focuses on the player.

And we do…

Page 15: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

But notice that I can rotate the pawn but not the camera.

Page 16: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

So the next step, now that we’ve our distance right, is to lock the camera to a specific location in relation to the player.

This takes a bit more effort & re-modeling of the code.

However, essentially, we just need to combine the camera offset with the rotation of the player.

Page 17: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

To start with, we’ll just lock it behind the player.

Surprisingly, the magic happens in one line. cameraOffset= VSize(cameraOffset) * vector(ViewActor.Rotation);

Page 18: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

And we’re locked in chase cam.

But there’s a caveat… We loose our elevation above the player.

Page 19: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

For why, look back at the code cameraOffset= VSize(cameraOffset) * vector(ViewActor.Rotation);

We multiply a vector by a scalar to get our new vector…no problem…and were casting from a rotator to get the unit vector…a.k.a the direction…fine.

Page 20: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

Look closervector(ViewActor.Rotation)

This is the rotation of the model in world space, e.g. which way it knows is up.

Not it’s line of sight.

Page 21: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

To put this another way, the models pitch is 0…not rotated.

Hence, this zero’s out our elevation rotation.

Page 22: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

To fix is real easy, just store the Z component of the cameraOffset in a variable & re add it to the cameraLocation.z as we’ve been doing to date…

But I’m thinking there is a much more clever way…

Page 23: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Offset relative to the Pawn

As we mentioned earlier, we’re going to use this vector to figure out the offset relative to the pawn and not the world.

This is important to remember, otherwise it’s very easy to get confused by this.

Page 24: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Offset relative to the Pawn

That being said, we have to modify our previous calculations to:

And the end result is an offset relative to the pawn.

cameraOffset=vect(-200,0,75);…cameraOffset= VSize(cameraOffset) * vector(normalize(rotator(cameraOffset)) +viewactor.Rotation+OffsetRotation());

CameraLocation = ViewActor.Location + cameraOffset;

Page 25: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Offset relative to the Pawn

How’s this working? Really we’re doing the same calculation as we did with the Max Payne cam…just with more numbers.

cameraOffset= VSize(cameraOffset) * vector(normalize(rotator(cameraOffset)) + viewactor.Rotation );

Scalar multiplication(how far away we are)

And in what direction

Page 26: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Offset relative to the Pawn

And the net result is the ability to use a vector to define a location relative to the player to view from.

Handy…very handy…

Page 27: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Offset relative to the Pawn

local vector cameraOffset;

cameraOffset=vect(-200,0,75);//model space offset...above and behind

bBehindView=true; ViewActor = ViewTarget;

//calculate offset relative to the pawn cameraOffset= VSize( cameraOffset) *

vector( normalize(rotator(cameraOffset) ) + viewactor.Rotation + OffsetRotation() );

CameraLocation = ViewActor.Location + cameraOffset;

CameraRotation = rotator(ViewActor.Location-CameraLocation);

Page 28: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

Now locked behind at a fixed height behind the player.

Lets do some transitions…

Page 29: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

For now, lets just build a toggle function which will snap the view from front to back.

To do so, we’ll create an exec function & stuff it into the user.ini

Page 30: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

The function is really easy. We just want to add ½ rotation.

exec function SwapViewFrontBack()

{

DirectToCamera.Yaw+= 65535/2; // ½ rotation

}

Page 31: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

An now in playercalcview we modify one line:

Simply adding an additional rotational value to the camera’s relative direction.

cameraOffset= VSize(cameraOffset) * vector(normalize(rotator(cameraOffset)) +viewactor.Rotation + DirectToCamera);

Page 32: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

This now provides us provide us with a ‘snap’ to see who’s behind us.

Page 33: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Transitions

Fine…Dandy…where’s the cool?

Now, now…This is just making sure we’re properly set up.

Now the cool happens. We’re going to build functions which will allow us to snap to the players front, back, left or right

Page 34: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

And we’re going to do this using delegates.

From the UDN: A delegates is a reference to a function bound

to an object.

Can you say “function pointer” boys & girls?...I knew you could.

Page 35: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Their main purpose in life is to provide a callback mechanism, for example to provide event notification in a user interface system.

But this is by NO means their only use.

Page 36: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Now that we know what they are, lets go about building one.

But first, we need some functions to select from…

The plan is simple. 4 functions that return a rotator and set the delegate.

Page 37: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Start by creating a delegate:delegate rotator OffsetRotation();

A delegate must have the same return type and signature as the functions you intend to have it pointing at.

Page 38: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Now we create a set of functions to be called from the user.ini which set the direction to view from.

One for each direction…

Page 39: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

exec function rotator ViewFront(){ local rotator rotammount; rotammount.yaw=0; OffsetRotation= ViewFront; return rotammount;}

exec function rotator ViewBack(){ local rotator rotammount; rotammount.yaw=65535/2; OffsetRotation= ViewBack; return rotammount;}

exec function rotator ViewLeft(){ local rotator rotammount; rotammount.yaw=65535/4; OffsetRotation= ViewLeft; return rotammount;}

exec function rotator ViewRight(){ local rotator rotammount; rotammount.yaw=65535/4*3; OffsetRotation= ViewRight; return rotammount;}

Page 40: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

These function is really straight forward, the only weirdness is:OffsetRotation= ViewLeft;

Which just sets the delegate to point at this function…just like function pointers in C++

Page 41: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

And now we set up our user.ini to deal with the new exec functions.

Don’t forget to give the delegate a default function to use in the default properties. If you don’t, you get some weird screen flickering until one the Viewfrom functions is played.

Page 42: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Once we give our delegate a default function to point at ( like viewBehind ) we change our rotational calculation to use the delegate and not the absolute vector.

cameraOffset= VSize(cameraOffset) * vector(normalize(rotator(cameraOffset))

+viewactor.Rotation + OffsetRotation(););

The delegate

Page 43: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Page 44: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

As you can see, we can use delegates to snap the camera to a given position saving us from several if cases, switches or math headaches.

Page 45: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

In addition, like C++ function pointers, we can pass in variables as well.

So long as the delegate has the same signature, as mentioned earlier.

Just to demonstrate the point…

Page 46: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

The code can modified the code to calculate the camera position for us.

delegate rotator OffsetRotation( optional rotator rot);

This new definition allows us to optionally pass in a rotator…thus we can still use the same function in the user.ini.

Page 47: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

What the UDN says about optional: The optional keyword, allows you to make

certain function parameters optional For UnrealScript functions, optional

parameters which the caller doesn't specify are set to zero.

Page 48: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Modify a line in PlayerCalcView

cameraOffset= VSize(cameraOffset) * vector(normalize(rotator(cameraOffset)) +viewactor.Rotation + OffsetRotation(ViewActor.Rotation););

Page 49: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

And slight modifications to the viewfrom functions

Page 50: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

exec function rotator ViewFront(optional rotator rot)

{ local rotator rotammount; rotammount.yaw=0; OffsetRotation= ViewFront; return rotammount+rot; }exec function rotator ViewBack(optional

rotator rot){ local rotator rotammount; rotammount.yaw=65535/2; OffsetRotation= ViewBack; return rotammount+rot;}

exec function rotator ViewLeft(optional rotator rot)

{ local rotator rotammount; rotammount.yaw=65535/4; OffsetRotation= ViewLeft; return rotammount+rot;}exec function rotator ViewRight(optional

rotator rot){ local rotator rotammount; rotammount.yaw=65535/4*3; OffsetRotation= ViewRight; return rotammount+rot;}

Page 51: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Delegates are incredibly powerful tools to have at your fingertips. In effect, there almost like miniature states.

Having different functionality based on how they were set.

Page 52: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Just to further illustrate this, there’s one more, really cool trick we can use.

We can actually place the delegate itself in the user.ini.

Thus causing a keypress to have a different functionality.

Page 53: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

So, in order to demonstrate this, we’re going to use an enumeration to keep track of what view mode we’re currently in.

The best part is, using enum’s is really similar to c++. The only thing is that they have to be declared at the top of the class I the global space.

Page 54: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Here’s mine

var enum viewfromdir{ E_FRONT, E_BACK, E_LEFT, E_RIGHT}V_Ddir;

Just like in c++, you can append a variable declarationto the definition.

Page 55: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

And to get this to work, we’re simply going to use a case statement.

exec function rotator NextView(optional rotator pawnRot){ local rotator rot;

switch (V_Ddir) { case E_FRONT: V_Ddir=E_BACK; //next view from OffsetRotation= ViewFront; break; case E_BACK: V_Ddir=E_LEFT; OffsetRotation= ViewBack; break;

Page 56: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Nothing fancy… The only thing to note is that we have the same signature and gave it a default value.

case E_LEFT: V_Ddir=E_RIGHT; OffsetRotation= Viewleft; break; case E_RIGHT: V_Ddir=E_FRONT; OffsetRotation= Viewright; break; } return rot+pawnRot;}

Page 57: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

And, in the user.ini, we set it up exactly the same as any other exec function…

Aliases[30]=(Command="NextView",Alias=Offsetdelegate)

…<snip>…

F11=Offsetdelegate

Page 58: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Page 59: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

And just by repeatedly hitting the F11 key, we cycle through different views.

But just remember…we are in fact executing different functions! All that we’ve done here is implemented a “pointer” to which function to execute.

Page 60: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

So, once again, I hope you can see the power behind these things and that their usefulness can extend far beyond what they were originally designed to do.

Page 61: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

Delegates

Very… very handy for implementing things like changes to thinks like weapon functionality or AI decision making…or even something so small as what to display to the HUD.

All it takes is a little bit of for thought and planning.

Page 62: Sega 500 Camera Transitions using Delegates Jeff “Ezeikeil” Giles jgiles@artschool.com jgiles

That’s a wrap for today!

I hope you can see the usefulness and coolness that comes with this bad boys.