I've tweaked Doug's new template orbit camera by adding two new toys and enhancing another.

1. The camera can now be controlled with the mouse OR the keyboard via a flag. If it is set to 0..keyboard only as before. If it is set to 1..mouse only.

2. Instead of a hardcoded value for each multiplier within the various camera functions(rotation, zoom, and height change), they are now generic. Simply change the initial value of the appropriate vars and all of the speed formulas are updated at once. This is a huge time saver.

3. I ported the smoothing factor from the new template 3rd person camera. It can be activated by making the smooth value greater than "0". The larger the number(up to 100), the less smoothing that is applied to the view. You can change this value during gameplay, but as coded you will have to use a number between "0"(which is off) and 1(maximum). You can always move the pre-while loop smoothing conversion to the beginning of the while loop if you want to keep it to 0-100.

When using smoothing, there is a strange quirk that will cause the camera to move closer to the player object when you are rotating the view. I don't know how to stop it from doing this. There are 7 lines of code controlling this feature, and the last three are responsible for the problem. However, eliminating them will cause unwanted violent camera wobble.

4. All of the new vars are accessible via the Customize panel in WED.

Copy & paste the code, below, into a new script file and save as "cameraOrbit01.wdl". You can save over over the original in the "..template_6/code/" folder if you want, but make sure to back up your original if you do this.



Code:
  

ifndef cameraOrbit01_wdl;
define cameraOrbit01_wdl;

// ver: Orange Brat
// date: 042807


// title: Orbit Camera
// image: cameraOrbit01.pcx
/*
help: The Orbit Camera is an external camera that follows the current "camera target".
The camera's inital pan and height values can be set. These values can be
changed by the player during the game.
*/

// uses: display_active_camera_vec
// needs: display00.wdl, miscInput01.wdl

// needs: cameraSelect.wdl, cameraTarget.wdl

// prefix: cameraOrbit01_
// idcode: 007


// General Camera Entries



// entry: Hide Focus when Inside? (1-yes, 0-no)
// id: 1
var cameraOrbit01_hide_focus_b = 0;

// entry: Identification number for this camera (used in cameraSelect)
// entry_help: NOTE: Action not defined if two camera share a single value
// id: 2
var cameraOrbit01_id = 1;

// entry: Make orbit camera selectable by user? (1-yes, 0-no)
// id: 3
var cameraOrbit01_usr_selectable_b = 1;

// entry: preform collision test? (1-yes, 0-no)
// id: 4
var cameraOrbit01_collide_b = 1;

// entry: Starting follow distance
// id: 5
var cameraOrbit01_dist = 550;

// entry: Maximum Follow Distance
// id: 6
var cameraOrbit01_dist_max = 850;

// entry: Minimum Follow Distance
// id: 7
var cameraOrbit01_dist_min = 200;

// entry: Starting height
// id: 8
var cameraOrbit01_height = 200;

// entry: Maximum height
// id: 9
var cameraOrbit01_height_max = 500;
// entry: Minimum height
// id: 10
var cameraOrbit01_height_min = 100;

// entry: Starting orbit rotation
// id: 11
var cameraOrbit01_rotation = 0;

// entry: Orbit camera rotate clockwise key
// id: 12
string cameraOrbit01_cw_key_c = "J";
var cameraOrbit01_cw_scancode = 0;

// entry: Orbit camera rotate counter-clockwise key
// id: 13
string cameraOrbit01_ccw_key_c = "L";
var cameraOrbit01_ccw_scancode = 0;

// entry: Orbit camera zoom in key
// id: 14
string cameraOrbit01_zoom_in_key_c = "I";
var cameraOrbit01_zoom_in_scancode = 0;

// entry: Orbit camera zoom out key
// id: 15
string cameraOrbit01_zoom_out_key_c = "K";
var cameraOrbit01_zoom_out_scancode = 0;

// entry: Orbit camera increase height key
// id: 16
string cameraOrbit01_inc_height_key_c = "U";
var cameraOrbit01_inc_height_scancode = 0;

// entry: Orbit camera decrease height key
// id: 17
string cameraOrbit01_dec_height_key_c = "O";
var cameraOrbit01_dec_height_scancode = 0;

// entry: Is this an "avatar" camera?
// entry_help: Avatar cameras are cameras who's source/pan are those of the player's eyes
// id: 20
define cameraOrbit01_avatar_q = 0;

// entry: "smoothing" factor (0-snap to position, 1-100 -percent distance covered to target)
// id: 21
var cameraOrbit01_smooth = 0;

// entry: camera panning speed
// id: 22
var cameraOrbit01_rotation_speed = 15;

// entry: camera zooming speed
// id: 23
var cameraOrbit01_zoom_speed = 15;

// entry: camera height change speed
// id: 24
var cameraOrbit01_height_speed = 45;

// entry: use mouse? (0-no; keyboard only -1-yes: mouse only)
// id: 25
var cameraOrbit01_use_mouse = 1;

// Local variables
var cameraOrbit01_pos_vec[3]; // x,y,z postion of orbit camera
var cameraOrbit01_ang_vec[3]; // pan,tilt,roll angles of the orbit camera
var cameraOrbit01_bit_check; // used in bit-compairs to check is this camera is active


/////////////////////////////////////////////////////////////////////////
// desc: Used to attach an orbiting camera to an entity
//
// help: To disable camera features (such as increasing/decreasing the camera
// help:height) simply assign 'nullvalues' to the key comands you don't want
// help:your players to have access to.
starter CameraOrbit01_Init
{
var updated_b; // has the camera been update yet this frame?
var view_number; // the current view being concidered

diag("\nWDL-Loaded:cameraOrbit01.wdl");

// init bit-field value used to check to see if this camera is active
cameraOrbit01_bit_check = 1<<cameraOrbit01_id;

if(1 == cameraOrbit01_usr_selectable_b)
{
// increase the camera select "max_camera" value if this value fall outside the current range
if(cameraOrbit01_bit_check > cameraSelect_max_camera)
{ cameraSelect_max_camera = cameraOrbit01_bit_check; }

// add this camera type to the collection of valid cameras in camera select
cameraSelect_valid_cameras |= cameraOrbit01_bit_check;
}

/////////////////////////////
// Set up keyboard scancodes
/////////////////////////////
// use MiscInput01_Key_For_Str() to convert strings into scancodes
// Rotate CW key
str_cpy(miscInput01_temp_str,cameraOrbit01_cw_key_c);
cameraOrbit01_cw_scancode = MiscInput01_Key_For_Str();
// Rotate CCW key
str_cpy(miscInput01_temp_str,cameraOrbit01_ccw_key_c);
cameraOrbit01_ccw_scancode = MiscInput01_Key_For_Str();
// Zoom in key
str_cpy(miscInput01_temp_str,cameraOrbit01_zoom_in_key_c);
cameraOrbit01_zoom_in_scancode = MiscInput01_Key_For_Str();
// Zoom out key
str_cpy(miscInput01_temp_str,cameraOrbit01_zoom_out_key_c);
cameraOrbit01_zoom_out_scancode = MiscInput01_Key_For_Str();
// Inc height key
str_cpy(miscInput01_temp_str,cameraOrbit01_inc_height_key_c);
cameraOrbit01_inc_height_scancode = MiscInput01_Key_For_Str();
// Dec height key
str_cpy(miscInput01_temp_str,cameraOrbit01_dec_height_key_c);
cameraOrbit01_dec_height_scancode = MiscInput01_Key_For_Str();


if(cameraOrbit01_smooth > 0)
{
cameraOrbit01_smooth /= 100; // get a percentage
if(cameraOrbit01_smooth > 1)
{
cameraOrbit01_smooth = 1;
}
}

while(1)
{
updated_b = 0; // camera hasn't been updated yet this frame
view_number = 0; // start with main view

// for all active views
while(view_number < display_active_views)
{
// check to see if this camera updates the current view
if(display_active_camera_vec[view_number] & cameraOrbit01_bit_check)
{
// if the camera hasn't updated itself this frame...
if(0 == updated_b)
{
// update camera position
CameraOrbit01_Update();

// camera has been updated this frame
updated_b = 1;
}

// update current view
CameraOrbit01_Update_View(view_number);

}

view_number +=1;
}

wait(1); // every frame
}
}


// desc: update the orbit camera
function CameraOrbit01_Update()
{

if(0 == cameraOrbit01_use_mouse)
{
// check and handle input
if(Key_Pressed(cameraOrbit01_cw_scancode))
{
cameraOrbit01_rotation += cameraOrbit01_rotation_speed * TIME;
cameraOrbit01_rotation = cameraOrbit01_rotation%360; //limit to 360 degrees
//IF more efficient than modulo, use this instead!
//cameraOrbit01_rotation = ang(cameraOrbit01_rotation); // keep in range -180 to 180
}
if(Key_Pressed(cameraOrbit01_ccw_scancode))
{
cameraOrbit01_rotation -= cameraOrbit01_rotation_speed * TIME;
cameraOrbit01_rotation = cameraOrbit01_rotation%360; //limit to 360 degrees
//IF more efficient than modulo, use this instead!
//cameraOrbit01_rotation = ang(cameraOrbit01_rotation); // keep in range -180 to 180
}
if(Key_Pressed(cameraOrbit01_zoom_in_scancode))
{
cameraOrbit01_dist -= cameraOrbit01_zoom_speed * TIME;
cameraOrbit01_dist = clamp(cameraOrbit01_dist, cameraOrbit01_dist_min, cameraOrbit01_dist_max);
}
if(Key_Pressed(cameraOrbit01_zoom_out_scancode))
{
cameraOrbit01_dist += cameraOrbit01_zoom_speed * TIME;
cameraOrbit01_dist = clamp(cameraOrbit01_dist, cameraOrbit01_dist_min, cameraOrbit01_dist_max);
}
if(Key_Pressed(cameraOrbit01_inc_height_scancode))
{
cameraOrbit01_height += cameraOrbit01_height_speed * TIME;
cameraOrbit01_height = clamp(cameraOrbit01_height, cameraOrbit01_height_min, cameraOrbit01_height_max);
}
if(Key_Pressed(cameraOrbit01_dec_height_scancode))
{
cameraOrbit01_height -= cameraOrbit01_height_speed * TIME;
cameraOrbit01_height = clamp(cameraOrbit01_height, cameraOrbit01_height_min, cameraOrbit01_height_max);
}
}
else
{
// check and handle input
cameraOrbit01_rotation -= cameraOrbit01_rotation_speed * mouse_force.x;
cameraOrbit01_rotation = cameraOrbit01_rotation%360; //limit to 360 degrees
//IF more efficient than modulo, use this instead!
//cameraOrbit01_rotation = ang(cameraOrbit01_rotation); // keep in range -180 to 180

cameraOrbit01_dist -= mickey.z;
cameraOrbit01_dist = clamp(cameraOrbit01_dist, cameraOrbit01_dist_min, cameraOrbit01_dist_max);

cameraOrbit01_height -= cameraOrbit01_height_speed * mouse_force.y;
cameraOrbit01_height = clamp(cameraOrbit01_height, cameraOrbit01_height_min, cameraOrbit01_height_max);
}

// orbit the target
cameraOrbit01_pos_vec.x = cameraTarget_pos_vec.x + (cameraOrbit01_dist * SIN(cameraOrbit01_rotation));
cameraOrbit01_pos_vec.y = cameraTarget_pos_vec.y + (cameraOrbit01_dist * COS(cameraOrbit01_rotation));
cameraOrbit01_pos_vec.z = cameraTarget_pos_vec.z + cameraOrbit01_height;


// handle collision
if(1 == cameraOrbit01_collide_b)
{
// collide with any object in the way
c_trace(cameraTarget_pos_vec.x,cameraOrbit01_pos_vec.x,(IGNORE_PASSABLE+IGNORE_PASSENTS+IGNORE_MODELS));
if(trace_hit == 1)
{
// offset from that target along the vector
vec_set(cameraOrbit01_pos_vec.x,TARGET.X);
}

}

// face the target
temp.x = cameraTarget_pos_vec.x - cameraOrbit01_pos_vec.x;
temp.y = cameraTarget_pos_vec.y - cameraOrbit01_pos_vec.y;
temp.z = cameraTarget_pos_vec.z - cameraOrbit01_pos_vec.z;
vec_to_angle(temp,temp);
cameraOrbit01_ang_vec.PAN = temp.PAN;
cameraOrbit01_ang_vec.TILT = temp.TILT;
}


// desc: update the view whos ID is passed in to the position/orientation
// of the Orbit Camera
function CameraOrbit01_Update_View(view_number)
{
if(view_number == 0)
{
if(cameraOrbit01_smooth > 0)
{
vec_diff(temp.x,cameraOrbit01_pos_vec.x,camera.x);
vec_scale(temp.x,(cameraOrbit01_smooth * TIME));
vec_add(camera.x,temp.x);
vec_set(camera.pan,cameraOrbit01_ang_vec.pan);
vec_set (temp.x, cameraTarget_pos_vec.x);
vec_sub(temp.x, camera.x);
vec_to_angle(camera.pan, temp.x);
}
else
{
vec_set(camera.x,cameraOrbit01_pos_vec.x);
vec_set(camera.pan,cameraOrbit01_ang_vec.pan);
}

// is this an avatar view?
cameraTarget_avatar_view_q = cameraOrbit01_avatar_q;
}
if(1==cameraOrbit01_hide_focus_b)
{ // hide the target entity from view if inside
camera.genius = cameraTarget_ent;
}
else
{ // show the target entity no matter what
camera.genius = 0;
}

// +++ other views
}

endif;




My User Contributions master list - my initial post links are down but scroll down page to find list to active links