Movie like camera system
by Thomas \"Man of Ice\" Lund · 03/21/2004 (2:15 pm) · 56 comments
Updates
2004-05-08 Had wrong code that didnt draw the camera sphere in the editor - added now
Description and background
While working on my current game project I felt the need for a little more spectacular camera system. My game is a little adventure game where one moves through various scenes and has to find items/solve puzzles/evade obstacles.
The camera system I wanted was something similar to LOTR:ROTK and other games - a very movie like camera where I could set up a camera to track the player from a fixed point. When the player moved into a new scene/area the camera then switched to that new scene.
I browsed through the resources and quickly found 2 resources that enabled me to easy accomplish this.
Resources needed
The 2 resources that needs to be put together are
Reactive Mission Regions and Using a Separate Camera Object
Add both resources to your engine/scripts and then follow my additions below.
What does this look like?
I made a small video (9 mb) that shows the system in use. I have a small tech demo level that contains 2 islands connected with a bridge (and some AI controlled sharks in the water). Within the level I added 5 mission regions. When the player enters either of these the camera switches to the center of the area and tracks the player. The height of the camera can be adjusted for each region. More on all this later after the movie
Camera demo movie (9 mb)
Showing mission regions in the world editor
To make it easier to create the regions we need to hack the editor to show the regions as well as the camera position.
In common/editor/EditorGui.cs find
and in objectBuilderGui.gui find
Regions can now be created/edited/deleted in the world editor. I still need to figure out how to get them to draw with a box ingame, but this makes it a little easier
We need to add a console function to the engine, and then call that from the editor when selecting a worldregion. Here we go:
In the engine\editor\editTSCtrl.cc add this below the existing console functions:
Recompile the engine
Now open common\editor\editorRender.cs and add this to the end of the file:
Beware the wrapped lines in this forum - you should have no trouble spotting them, but here is a friendly reminder.
Its not perfect, as it would be nice to have a little handle like the other objects to drag/rotate/resize. But it all works as is.
Modifying the regions to save the camera height
I first started out with having a global setting for the camera height. But I soon realized that for most maps there would be a need for setting the height individually. I therefore modified the region code to save a height float for the camera.
In the missionArea.h code I added the cameraHeight float as well as a set/get method.
Find
and change it to
In the missionArea.cc change
to
add this method:
add this to the MissionRegion::onAdd() just before the return true;
add this to the MissionRegion::initPersistFields() just before the endGroup("Dimensions");
Expose the get/set methods to the console by adding
and last but not least make sure we pack/unpack the cameraHeight by mdifying the unpackUpdate() and packUpdate() to include the cameraHeight variable like this:
Phew - so far so good.
The separate camera object
There really are no changes to the camera code to make this work. Add the resource, compile and then its all ready to run.
Making the connection between player, region and camera
Tying it all together is quite simple.
Its all a matter of adding this code to the onEnterMissionRegion() function in the player.cs server script
Seeing it all in effect
Now load up your favorite level in the mission editor. Add 2 mission regions that are next to each other and set the height of the camera for each. There is an orb that represents the camera, so you can easily see where its placed. In my code I set the x,y coordinates to be in the middle of the region.
Now go back to the game, press the tab button so you are using the tracking camera and then run back and forth between the 2 regions. Every time you enter the region the camera moves its position.
Done! :-)
Back to my story
Well - I quickly discovered that this camera system is not usable for platform games. It is damn hard to jump over my little bridge (as my video shows). But besides that it gives a very very nice feeling to the game, that is radically different from 1st and 3rd person views.
I will be using this system in my game for the areas where puzzles are to be solved and items to be found, but not where one needs to jump/evade things. There I'm moving the camera down to 3rd person again.
Nifty future enhancements
* It would be great to move the camera along a spline when the camera moves between regions - keeping its view on the player.
* Another thing I am thinking about is making the x,y coordinates setable too for a region and not only the height, as this would further enable one to make "more movie like" camera placement
* When the player leaves the region (and not enters a new) the camera should move itself to 3rd person behind the player (again along a spline or similar)
* Being able to set fov for a region - especially with the player very close to the camera
* If the player is far away from the camera, it could zoom in on the player automatically and zoom out again when he gets closer
And I bet there are tons of other things one could integrate into the system.
I hope I didnt forget to paste any code or explaination in here, and feel free to comment on this. The major credit for this should go to Cory Osborn and Mark Owen for their resources. I just put it together and added a link between the 2.
2004-05-08 Had wrong code that didnt draw the camera sphere in the editor - added now
Description and background
While working on my current game project I felt the need for a little more spectacular camera system. My game is a little adventure game where one moves through various scenes and has to find items/solve puzzles/evade obstacles.
The camera system I wanted was something similar to LOTR:ROTK and other games - a very movie like camera where I could set up a camera to track the player from a fixed point. When the player moved into a new scene/area the camera then switched to that new scene.
I browsed through the resources and quickly found 2 resources that enabled me to easy accomplish this.
Resources needed
The 2 resources that needs to be put together are
Reactive Mission Regions and Using a Separate Camera Object
Add both resources to your engine/scripts and then follow my additions below.
What does this look like?
I made a small video (9 mb) that shows the system in use. I have a small tech demo level that contains 2 islands connected with a bridge (and some AI controlled sharks in the water). Within the level I added 5 mission regions. When the player enters either of these the camera switches to the center of the area and tracks the player. The height of the camera can be adjusted for each region. More on all this later after the movie
Camera demo movie (9 mb)
Showing mission regions in the world editor
To make it easier to create the regions we need to hack the editor to show the regions as well as the camera position.
In common/editor/EditorGui.cs find
%Mission_Item[5] = "Camera";and add the line
%Mission_Item[6] = "MissionRegion";
and in objectBuilderGui.gui find
function ObjectBuilderGui::buildMissionArea(%this)
{
%this.className = "MissionArea";
%this.addField("area", "TypeRect", "Bounding area", "0 0 1024 1024");
%this.process();
}and add the blockfunction ObjectBuilderGui::buildMissionRegion(%this)
{
%this.className = "MissionRegion";
%this.addField("area", "TypeRect", "Bounding area", "0 0 20 20");
%this.addField("cameraHeight", "TypeFloat", "Camera height", "100.0");
%this.process();
}Regions can now be created/edited/deleted in the world editor. I still need to figure out how to get them to draw with a box ingame, but this makes it a little easier
We need to add a console function to the engine, and then call that from the editor when selecting a worldregion. Here we go:
In the engine\editor\editTSCtrl.cc add this below the existing console functions:
ConsoleMethod( EditTSCtrl, renderBox, void, 3, 3, "(RectI area)")
{
if(!object->mConsoleRendering)
return;
if(!object->mConsoleFrameColor.alpha)
return;
RectI area;
dSscanf(argv[2], "%i %i %i %i", &area.point.x, &area.point.y, &area.extent.x, &area.extent.y);
TerrainBlock * terrain = dynamic_cast<TerrainBlock*>(Sim::findObject("Terrain"));
if(!terrain)
return;
GridSquare * gs = terrain->findSquare(TerrainBlock::BlockShift, Point2I(0,0));
F32 height = F32(gs->maxHeight) * 0.03125f + 10.f;
//
Point2F min(area.point.x, area.point.y);
Point2F max(area.point.x + area.extent.x, area.point.y + area.extent.y);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ColorI a(255,0,0,20);
ColorI b(255,0,0,128);
for(U32 i = 0; i < 2; i++)
{
//
if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
glVertex3f(min.x, min.y, 0);
glVertex3f(max.x, min.y, 0);
glVertex3f(max.x, min.y, height);
glVertex3f(min.x, min.y, height);
glEnd();
//
if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
glVertex3f(min.x, max.y, 0);
glVertex3f(max.x, max.y, 0);
glVertex3f(max.x, max.y, height);
glVertex3f(min.x, max.y, height);
glEnd();
//
if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
glVertex3f(min.x, min.y, 0);
glVertex3f(min.x, max.y, 0);
glVertex3f(min.x, max.y, height);
glVertex3f(min.x, min.y, height);
glEnd();
//
if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
glVertex3f(max.x, min.y, 0);
glVertex3f(max.x, max.y, 0);
glVertex3f(max.x, max.y, height);
glVertex3f(max.x, min.y, height);
glEnd();
}
glDisable(GL_BLEND);
}Recompile the engine
Now open common\editor\editorRender.cs and add this to the end of the file:
function MissionRegion::onEditorRender(%this, %editor, %selected, %expanded)
{
%area = %this.getArea();
if(%selected $= "true")
{
// Region box
%editor.renderBox(%area);
// Region camera
%dx = getWord(%area,2);
%dy = getWord(%area,3);
%x = getWord(%area,0) + %dx / 2;
%y = getWord(%area,1) + %dy / 2;
%z = %this.getCameraHeight();
%editor.renderSphere(%x SPC %y SPC %z, 1, 1);
}
}Beware the wrapped lines in this forum - you should have no trouble spotting them, but here is a friendly reminder.
Its not perfect, as it would be nice to have a little handle like the other objects to drag/rotate/resize. But it all works as is.
Modifying the regions to save the camera height
I first started out with having a global setting for the camera height. But I soon realized that for most maps there would be a need for setting the height individually. I therefore modified the region code to save a height float for the camera.
In the missionArea.h code I added the cameraHeight float as well as a set/get method.
Find
private:
typedef NetObject Parent;
RectI mArea;
public:
MissionRegion();
static const MissionRegion * getServerObject();
const RectI & getArea(){return(mArea);}
void setArea(const RectI & area);and change it to
private:
typedef NetObject Parent;
RectI mArea;
F32 mCameraHeight;
public:
MissionRegion();
static const MissionRegion * getServerObject();
const RectI & getArea(){return(mArea);}
void setArea(const RectI & area);
const F32 getCameraHeight(){return(mCameraHeight);}
void setCameraHeight(const F32 cameraHeight);In the missionArea.cc change
MissionRegion::MissionRegion()
{
mArea.set(Point2I(768, 768), Point2I(512, 512));
mNetFlags.set(Ghostable | ScopeAlways);
}to
MissionRegion::MissionRegion()
{
mArea.set(Point2I(768, 768), Point2I(512, 512));
mCameraHeight = 0;
mNetFlags.set(Ghostable | ScopeAlways);
}add this method:
void MissionRegion::setCameraHeight(const F32 cameraHeight)
{
mCameraHeight = cameraHeight;// set it
if( isServerObject() )
mNetFlags.set(UpdateMask);// pass it along..
}add this to the MissionRegion::onAdd() just before the return true;
setCameraHeight(mCameraHeight);
add this to the MissionRegion::initPersistFields() just before the endGroup("Dimensions");
addField("cameraHeight", TypeF32, Offset(mCameraHeight, MissionRegion));Expose the get/set methods to the console by adding
ConsoleMethod( MissionRegion, getCameraHeight, F32, 2, 2, "()"
"Returns 1 field: camera z")
{
return object->getCameraHeight();
}
ConsoleMethod( MissionRegion, setCameraHeight, void, 3, 3, "(F32 z)")
{
F32 z = dAtoi(argv[2]);
object->setCameraHeight(z);
}and last but not least make sure we pack/unpack the cameraHeight by mdifying the unpackUpdate() and packUpdate() to include the cameraHeight variable like this:
void MissionRegion::unpackUpdate(NetConnection *, BitStream * stream)
{
// ghost (initial) and regular updates share flag..
if( stream->readFlag() ) {
mathRead(*stream, &mArea);
stream->read(&mCameraHeight);
}
}
U32 MissionRegion::packUpdate(NetConnection *, U32 mask, BitStream * stream)
{
if( stream->writeFlag(mask & UpdateMask) ) {
mathWrite(*stream, mArea);
stream->write(mCameraHeight);
}
return 0;
}Phew - so far so good.
The separate camera object
There really are no changes to the camera code to make this work. Add the resource, compile and then its all ready to run.
Making the connection between player, region and camera
Tying it all together is quite simple.
Its all a matter of adding this code to the onEnterMissionRegion() function in the player.cs server script
function Armor::onEnterMissionRegion(%this,%obj,%rgn)
{
// Inform the client, if the client is a real player
if (isObject(%obj.client.player)) {
%obj.client.onEnterMissionRegion(%rgn);
// Set camera for area
if( %rgn && %obj.getDataBlock().getName() $= "PlayerBody") {
%area = %rgn.getArea();
%dx = getWord(%area,2);
%dy = getWord(%area,3);
%x = getWord(%area,0) + %dx / 2;
%y = getWord(%area,1) + %dy / 2;
%z = %rgn.getCameraHeight();
%obj.client.trackCamera.setPosition(%x SPC %y SPC %z);
}
}
}Seeing it all in effect
Now load up your favorite level in the mission editor. Add 2 mission regions that are next to each other and set the height of the camera for each. There is an orb that represents the camera, so you can easily see where its placed. In my code I set the x,y coordinates to be in the middle of the region.
Now go back to the game, press the tab button so you are using the tracking camera and then run back and forth between the 2 regions. Every time you enter the region the camera moves its position.
Done! :-)
Back to my story
Well - I quickly discovered that this camera system is not usable for platform games. It is damn hard to jump over my little bridge (as my video shows). But besides that it gives a very very nice feeling to the game, that is radically different from 1st and 3rd person views.
I will be using this system in my game for the areas where puzzles are to be solved and items to be found, but not where one needs to jump/evade things. There I'm moving the camera down to 3rd person again.
Nifty future enhancements
* It would be great to move the camera along a spline when the camera moves between regions - keeping its view on the player.
* Another thing I am thinking about is making the x,y coordinates setable too for a region and not only the height, as this would further enable one to make "more movie like" camera placement
* When the player leaves the region (and not enters a new) the camera should move itself to 3rd person behind the player (again along a spline or similar)
* Being able to set fov for a region - especially with the player very close to the camera
* If the player is far away from the camera, it could zoom in on the player automatically and zoom out again when he gets closer
And I bet there are tons of other things one could integrate into the system.
I hope I didnt forget to paste any code or explaination in here, and feel free to comment on this. The major credit for this should go to Cory Osborn and Mark Owen for their resources. I just put it together and added a link between the 2.
#2
03/21/2004 (4:59 pm)
VERY NICE :D
#3
If your having problems controlling the player, perhaps you should make the movement relate to where the current camera position is (if is doesn't already)?
I've played a few games with this sort of camera system (give or take a few extra features, such as zooming). Pretty nice system (especially if you use a gamepad) if you ask me :)
03/21/2004 (9:54 pm)
Neato resource :)If your having problems controlling the player, perhaps you should make the movement relate to where the current camera position is (if is doesn't already)?
I've played a few games with this sort of camera system (give or take a few extra features, such as zooming). Pretty nice system (especially if you use a gamepad) if you ask me :)
#4
Off topic: What program did you use to capture that moive?
03/22/2004 (6:55 am)
It looks like you have some control problems with that type a view. I'm using the same camera object for my 3rd person cam, but I use a script loop to update its position. The camera is trasnformed to behind and above the player whenever the player is behind or too far away from the camera.Off topic: What program did you use to capture that moive?
#5
Yes - the controls need to be refined. In the movie my controls are the usual ones wsad and mouse for look = unplayable. But I've remaped the keys to
w = forward
s = backward
a = turn left (NOT sidestep)
d = turn right (NOT sidestep)
no mouse
and that seems to work perfect also with this camera angle. So its all a matter of rethinking the controls to fit the camera system. Its still very hard to jump over things as the perspective element is "lost". But for running and solving puzzles its quite good.
Josh: Ben Garney was so friendly to point me to FRAPS. It can capture any opengl and directx window. You assign a key to start/stop the grabbing, and it dumps an uncompressed avi file on your harddisk. Then you load those avi into MS Movie Maker (comes with all XP installations) and you put the scenes together, add some music and export to a compressed format (typically wmv). Works like a charm.
03/22/2004 (8:04 am)
Thanks all for the comments.Yes - the controls need to be refined. In the movie my controls are the usual ones wsad and mouse for look = unplayable. But I've remaped the keys to
w = forward
s = backward
a = turn left (NOT sidestep)
d = turn right (NOT sidestep)
no mouse
and that seems to work perfect also with this camera angle. So its all a matter of rethinking the controls to fit the camera system. Its still very hard to jump over things as the perspective element is "lost". But for running and solving puzzles its quite good.
Josh: Ben Garney was so friendly to point me to FRAPS. It can capture any opengl and directx window. You assign a key to start/stop the grabbing, and it dumps an uncompressed avi file on your harddisk. Then you load those avi into MS Movie Maker (comes with all XP installations) and you put the scenes together, add some music and export to a compressed format (typically wmv). Works like a charm.
#6
03/22/2004 (12:56 pm)
Oh, I've tried the fraps demo, but it only take 15 sec moives. The registered one must beable to take longer movies.
#7
03/22/2004 (6:16 pm)
Ahhh - on their download page there is a link to the "last free fraps". Thats the one I used. It can record unlimited
#8
I am also developing an arcade style adventure game. This will be very handy for small buildings and rooms.
How are you handling the 3rd person camera when not in a mission region? I know the default 3rd person view effects the direction the player is looking up or down which isn't want I want to do. Do you have a solution for this yet in your game?
03/23/2004 (1:26 am)
This is an awesome resource! Good job Thomas.I am also developing an arcade style adventure game. This will be very handy for small buildings and rooms.
How are you handling the 3rd person camera when not in a mission region? I know the default 3rd person view effects the direction the player is looking up or down which isn't want I want to do. Do you have a solution for this yet in your game?
#9
I'm planning on releasing that too as a resource (if/when I get it done). Look and post comments here:
www.garagegames.com/mg/forums/result.thread.php?qt=16995
I basically want to move the camera into a 3rd person view when leaving a region (provided the player doesnt enter a new one). That 3rd person camera should be attached to a spring and align itself with the terrain.
If I'm able to pull this off (my first "major" change to the engine of my own), then the camera will be able to move back and forth between a fixed point (track) and behind the player without anything else but flipping a switch in the script block.
If you want to help, then feel free to contact me. I'm a bit shacky to start it, but I bet 80% of the code is already done simply by enabling the camera object in gameConnection
03/23/2004 (1:42 am)
@Eric - not yet, but this week I'll try to either extend the TrackingCamera resource or write my own camera resource on top of the "camera object" in GameConnection.I'm planning on releasing that too as a resource (if/when I get it done). Look and post comments here:
www.garagegames.com/mg/forums/result.thread.php?qt=16995
I basically want to move the camera into a 3rd person view when leaving a region (provided the player doesnt enter a new one). That 3rd person camera should be attached to a spring and align itself with the terrain.
If I'm able to pull this off (my first "major" change to the engine of my own), then the camera will be able to move back and forth between a fixed point (track) and behind the player without anything else but flipping a switch in the script block.
If you want to help, then feel free to contact me. I'm a bit shacky to start it, but I bet 80% of the code is already done simply by enabling the camera object in gameConnection
#10
This might be a step in the right direction.
03/23/2004 (2:44 am)
Have you seen the godview resource? www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3435This might be a step in the right direction.
#11
03/23/2004 (3:20 am)
Would it be difficult to seperate the camera from the region as a seperate object calling it a RegionCameraNode? This node could provide the camera height and location information to the region for the camera placement. This would give you total control on where the camera is located within the region and you could visually see it in the editor as well. A field in the region would specify which camera node to use as a default. This would also give you the ability to have multiple camera nodes in a region and to swtich which one to use through script. For example Let say I have a region defined for a room and a default camera postion in a corner of this room and another camera node over a chest in the room. When the player opens the chest the script could change the camera to the node over chest to show what is in it close up. When the chest is closed or the player moves away it goes back to the default. What do you think of this idea?
#12
Yeah - thats exactly what I had in mind when I first set out to "play" with this. A very movie like feeling where the camera is as important to the gameplay as the player himself.
Having a separate camera node within a region would be most desireable, but I do not know how to implement it in the editor.
Having multiple cameras I think would be better handled with triggers or multiple regions (e.g. a very small "chest region" inside the "chest room region"). One way to accomplish this very easy would be to embed the MissionRegion within a SimGroup, and having some dummy object in the world (could be a spawnsphere or marker) within the same simgroup. Then one can query the group for a camera node. By having multiple dummy objects or spawnspheres one could even have a "pick random camera within this region" to get a more non-static feel to the game.
A more beautiful approach would be to directly have a camera object node attached to the region, but I have no clue on how to do that except by a simple x,y,z coordinate input field. Its also entirely possible to have dynamic fields in the region as you say with names of the camera objects + a marker at the default one.
03/23/2004 (4:28 am)
Hey EricYeah - thats exactly what I had in mind when I first set out to "play" with this. A very movie like feeling where the camera is as important to the gameplay as the player himself.
Having a separate camera node within a region would be most desireable, but I do not know how to implement it in the editor.
Having multiple cameras I think would be better handled with triggers or multiple regions (e.g. a very small "chest region" inside the "chest room region"). One way to accomplish this very easy would be to embed the MissionRegion within a SimGroup, and having some dummy object in the world (could be a spawnsphere or marker) within the same simgroup. Then one can query the group for a camera node. By having multiple dummy objects or spawnspheres one could even have a "pick random camera within this region" to get a more non-static feel to the game.
A more beautiful approach would be to directly have a camera object node attached to the region, but I have no clue on how to do that except by a simple x,y,z coordinate input field. Its also entirely possible to have dynamic fields in the region as you say with names of the camera objects + a marker at the default one.
#13
03/23/2004 (5:05 am)
I would make some dynamic variables in the region that are x y z coorinates. You could activate a "chest" camera veiw with a trigger.
#14
I use this technique for zoning from one mission to another using a trigger and having a unquely named spawn sphere in the next level that is used as a location to spawn the player after the mission loads.
Since we are doing similar games maybe we could work together on some basic features that our games need. I have tried to seek other people and groups doing similar projects but without much success. I will email you so we can discuss it.
03/23/2004 (6:05 am)
The idea behind having a seperate physical node that is placed with the editor was so you could visually place it when editing your level so you could see exactly where it was. Having multiple dummy objects in a Sim group is a great idea. That should be very easy to implement. Picking a random camera would be cool but might make the player confused or disoriented. Another idea would be to have it pick the closest camera from the player when he enters the region. There are definately alot of posibilities.I use this technique for zoning from one mission to another using a trigger and having a unquely named spawn sphere in the next level that is used as a location to spawn the player after the mission loads.
Since we are doing similar games maybe we could work together on some basic features that our games need. I have tried to seek other people and groups doing similar projects but without much success. I will email you so we can discuss it.
#15
03/23/2004 (7:49 am)
Looks like theres 3 of us working on RPG/Adventure games. I've got a cool trigger that spawns static objects inside it(so I can have details wherever I want). I have another trigger that spawns enemies in a certain zone. I started this project like 2 weeks ago, so I don't have that much stuff in it. I have RW based melee system , its posted as a resource.
#16
03/23/2004 (10:09 am)
We aught to join forces and work together on some of these systems. You all have really great ideas. Josh, your item and enemy spawn regions sound cool. Would you care to share them? Feel free to email me or better yet post them as a resource.
#17
you'll need to customize this a little bit for your project. The trigger needs a dynamic variable called "enemies" to set the bot count.
03/23/2004 (10:43 am)
The item spawn trigger needs to be improved, but heres my enemy spawn trigger.datablock TriggerData(EnemeyTrigger)
{
// The period is value is used to control how often the console
// onTriggerTick callback is called while there are any objects
// in the trigger. The default value is 100 MS.
tickPeriodMS = 100;
};
//-----------------------------------------------------------------------------
function EnemeyTrigger::onEnterTrigger(%this,%trigger,%obj)
{
// This method is called whenever an object enters the %trigger
// area, the object is passed as %obj. The default onEnterTrigger
// method (in the C++ code) invokes the ::onTrigger(%trigger,1) method on
// every object (whatever it's type) in the same group as the trigger.
if(%obj.getdatablock().getName() $= "botSwordsman")//change to bot DB
return;
%x = getWord(%trigger.scale, 0)/2;
%y = getWord(%trigger.scale, 1)/2;
%rad = (%x + %y) / 2;
error("enemy trigger spawn radius is: " @ %rad);
for(%i = 0; %i < %trigger.enemies; %i++)
{
%pos = getTerrainLevel(%trigger.getWorldBoxCenter(), %rad);
%trigger.obj[%i] = spawnEnemyAi(%pos, %trigger.getWorldBoxCenter(), %rad);
%trigger.obj[%i].startFade(50, 0, true);
%trigger.obj[%i].schedule(100, "startFade", 1000, 0, false);
}
Parent::onEnterTrigger(%this,%trigger,%obj);
}
function EnemeyTrigger::onLeaveTrigger(%this,%trigger,%obj)
{
// This method is called whenever an object leaves the %trigger
// area, the object is passed as %obj. The default onLeaveTrigger
// method (in the C++ code) invokes the ::onTrigger(%trigger,0) method on
// every object (whatever it's type) in the same group as the trigger.
if(%obj.getdatablock().getName() $= "botSwordsman")// change to bot DB
return;
for(%i = 0; %i < %trigger.enemies; %i++)
{
%Tobj = %trigger.obj[%i];
if(isObject(%Tobj))
{
%Tobj.startFade(600, 0, true);
%Tobj.schedule(700, "delete");
}
%trigger.obj[%i] = "";
}
Parent::onLeaveTrigger(%this,%trigger,%obj);
}
function getTerrainLevel(%pos,%rad)
{
while(%retries < 500)
{
%x = getWord(%pos, 0) + getRandom(5, %rad-15);
%y = getWord(%pos, 1) + getRandom(5, %rad-15);
%start = %x @ " " @ %y @ " 1000";
%end = %x @ " " @ %y @ " -100";
%ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType, 0);
%z = getWord(%ground, 3);
error ("Spawn Position : " @ %x SPC %y);
error ("Ground Level : " @ %z);
%z += 3.5;
%position = %x @ " " @ %y @ " " @ %z;
%mask = ($TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | $TypeMasks::StaticShapeObjectType |
$TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType);
if (ContainerBoxEmpty(%mask,%position,3.5))
{
error ("Spawn Position Is Good");
return %position;
}
else
%retries++;
}
return VectorAdd(%pos, getRandom(0, 5) SPC "0 8");
}you'll need to customize this a little bit for your project. The trigger needs a dynamic variable called "enemies" to set the bot count.
#18
03/23/2004 (11:22 am)
Cool, thanks for posting it!
#19
03/23/2004 (11:35 am)
Waht kind of game are you planing on making? I'm going for a midevil melee action adventure rpg.
#20
It has certain commercial aspects that I cannot discuss at the moment, but I am most certainly interested in sharing code and ideas. Your games are not competing with me at all, so I cannot see any reason not to help each other on base code.
03/23/2004 (6:59 pm)
I'm in for a adventure style non-violent game. "Puzzles, collect items, beat the clock" kind of game. It is not a single player game, but online with others. But the players are not interacting, so gameplay is very single player like.It has certain commercial aspects that I cannot discuss at the moment, but I am most certainly interested in sharing code and ideas. Your games are not competing with me at all, so I cannot see any reason not to help each other on base code.
Torque 3D Owner Edward F. Maurina III
Roaming Gamer LLC.
That was a spanking good idea! Loved the movie by the way.
[HOW]-EdM