17.Apr.07 Lecture 11
Camera Pathing, Camera Control

Motivate

The world will not come to you. You are your network.

28 days left. 2 weeks until screen shots and marketing materials are due.

Camera pathing

Here is a great example of camera pathing. This would be used for flybys in cut scenes, machinima or anything else you might dream up. I was thinking of using some form of it in a puzzle game and created this sample. This is basically the tutorial.base with changes to the server/game.cs and server/camera.cs.

This is another page on moving dts shapes along paths.

Perfect Circle Path

That path isn't very nice as it's just a random bunch of points. My next step for a puzzle style game is to allow a camera to move around the board in a perfect circle. To layout the circle, first I place 8 points at the origin. The first thing you notice about that tutorial.base (which I started with) is that the spawn point is not set at the origin. I then moved it to the origin.

Next is they positioning of each of the path elements in a perfect circle around the origin. I choice a round number of 40 units in the y direction for the first point. Since I have 8 points, 4 of them will be on the axises, but 4 will be inbetween the axises. I used basic trigonometry (yes I'm lame and had to look it up) to find the location of one of these points.

x = sin(45) * 40 = 28.284

y = cos(45) * 40 = 28.284

Once I know the x and y it's just a matter of futzing with the positive or negative sign to move the corner points into the right locations.

This is what I came up with after I had placed them all. I had to make a couple of simple sign mistakes when I placed the rest of the points.

Point x y
p1 0 40
p2 -28.28 28.28
p3 -40 0
p4 -28.28 -28.28
p5 0 -40
p6 28.28 -28.28
p7 40 0
p8 28.28 28.28

This is what the path looked like as I laid it out. You can begin to see the formation of a perfect circle.

Once that was done, I made my camera pathing play through the whole sequence. Notice that the camera says pointed in the direction of the y axis and you have to rotate each axis so the origin points at the center where the puzzle board will be. To rotate the axis simply point at the z axis (blue vertical), hold down the alt key and right click. For this experiment you can simply rotate until you have it close enough, but you are welcome to calculate the actula rotation angle and enter it into the transform. After you do this the path will always point at the center of the circle.

Once I had the paths setup, I started working on geting the camera to move from point to point based on the character press. There are probably a lot of ways to do this. For me, the least amount of code seemed like it would be to use the existing pathing system and just give it a bunch of smaller paths. To create those paths, I simply used the larger circular path and created a bunch of one segment paths.

function buildMovePaths(%client,%FullPath)
{
  // build a list of SimGroup move paths
  // these move from one node to the next in clockwise (left)
  // and counter clockwise (right) directions
  // for my case %FullPath = CamPath;
  //     it could aslo be %FullPath = "MissionGroup/CamPath";

  %group = %FullPath;
  if (%group != -1)
    {
      // build all the move right nodes
      %cur = 0;
      %count = %group.getCount();
      while (%cur < %count)
        {
          %pt = %group.getObject(%cur);
          
          // loop around if needed for the next point
          if (%cur < %count - 1)
            {
            %ptnext = %group.getObject(%cur+1);
            }
          else
            {
            %ptnext = %group.getObject(0);
            }
          
          // create the new path
          %setTmp = new SimSet();
          %setTmp.add(%pt);
          %setTmp.add(%ptnext);
          
          // add the path/set for cleanup
          MissionCleanup.add(%setTmp);
          
          // now add it to our array
          %client.moveRight[%cur] = %setTmp;
          
          //echo("created right path " @ %cur @ " pt1=" @ %pt @ " pt2=" @ %ptnext @ "  set=" @%setTmp);
          
          %cur++;
        }
      %client.moveRightCount = %count;
	  }
	}

I created two paths, one for the right hand movement and one for the left. Take the existing path an iterate through each element creating a new path current and next node. When on the last node, use the first node as the end of the path. With each of these points create a SimSet and add the two points to the set. I could have used Path, but this is just a subclass of SimSet and only includes one element isLooping which I did not plan to use. I added the new set to the MissionCleanup so it is removed when the mission is unloaded, then add the set to the moveRight array. Given the current location, it is a simple matter to tell the engine to follow the rightPath using the current location.

function nextCameraRight()
{
  // move alont the moveRight paths created in buildMovePaths

  if ($conn.PathCamera.moving == false)
    {
    // save the location we are moving from
    %fromCamera = $curCamera;

    // find the next location
    $curCamera++;
    if ($curCamera >= $conn.moveRightCount)
      {
      $curCamera = 0;
      }
    $conn.PathCamera.moving = true;
    $conn.PathCamera.followPath($conn.moveRight[%fromCamera]);
    }
}

We simply tell the camera to follow the path using the current index. We also increment the index for the next keypress. Here is a complete sample of the puzzle game with the rotating camera. The 'a' and 'd' keys move the camera left and right.

One complaint about my implementation might be that I've lost the curvature of the circle and the movement is now a straight line from one point to the next. This wasn't critical to my design so didn't spend any time on it.

Camera Speed

After the last sample I wanted to really speed up the camera as I'm planning a fast action puzzle game. Looking at the camera code in camera.cs:

function PathCamera::followPath(%this,%path)
{
   %this.path = %path;
   if (!(%this.speed = %path.speed))
      %this.speed = 10;


   ...
}

As you can see from this code it's expecting a speed variable. If it doesn't find one, it uses the arbitrary value of 10 for this path. You may think this means that you have to use an official Path instead of SimSet, but it doesn't. We can simply add the speed variable to the SimSet on creation.

In the buildMovePaths method, simply add these two lines after the SimSet is created

// create the new path
%setTmp = new SimSet();
%setTmp.add(%pt);
%setTmp.add(%ptnext);
 
// set the speed
%setTmp.speed = 40;

You have to do this in two locations for the left and the right arrays. I used a variable for 40, but only so it is easier to read and change later.

Mouse Cursor

Since I wanted to be able to click on things in my puzzle game, I also wanted the cursor to show. This is an easy change. I simply opened the playGui.gui file and changed the noCursor value.

noCursor = "0";

This tells the gui to show the cursor. In your own future coding, try to avoid naming your variables in a negative fashion because the double negative thing will tend to hurt your brain. This variable should have been called showCursor and set to 1 to show it and 0 to hide it. Or hideCursor but even that has logic problems because 1 then means it isn't show which is not intuitive. Try using names where 1 is on and 0 is off. 'No' is just causes my brain to go into overdrive and gets really crazy when you start using it in complex if statements.

In Agile programming we are focused on efficiency. Anything that slows us down is to be avoided or refactored. This type of double negative will slow you down and adds up over time. Don't do it.

Mouse clicking and picking

Next up on my list was to be able to select objects in my puzzle area with the mouse and interact with the object in the puzzle through mouse clicking while moving the viewpoint around the field with the keyboard.

After a bunch of trying with script, it looks like I'll have to modify the gameTSCtrl. While I'm not looking for a complete WoW interface, there are specific elements in here that I'll need for what I'm doing. In looking at the default gameTSCtrl it only catch mouse move events.

Math Extension

Bill made some changes to the engine to avoid some string to floating point number conversions. Let's talk about these changes.

Particle Effects

I'm still having trouble with this lecture. It's coming I promise.

CPSC240 - Games Development
Chapman University
Instructor: W. Wood Harter
(c) copyright 2006-2007 - W. Wood Harter - All Rights Reserved
Screen shots on banner (c) copyright their resprective owners