The Ultimate Resident Evil Camera

Posted By: Orange Brat

The Ultimate Resident Evil Camera - 12/20/04 02:32

A huge thanks to "tesanders". Without him most of this code wouldn't exist, so if you use this, give him a nice, huge credit.

This is what I consider to be the finest Resident Evil style camera system around. Of course, you can use it for other types of games....point & click adventures for example....but most of us associate them with survival horror type acton adventures.

The system sets up a "voronoi field". If you don't know what that means, you can find an explanation, complete with browser demo, here: http://www.cs.cornell.edu/Info/People/chew/Delaunay.html This type of environment sets up hot zones for each trigger and allows you to disconnect the camera from the trigger. This means you can place the camera 150000 miles away from its trigger or 150 inches for that matter. This opens up the creative possibilities and gives you, the level designer, much more breathing room. It does have a quirk or two. For example, it doesn't work very well with multifloored levels. You CAN use them with them, but it can be tricky at first. Once you get the hang of it, you'll find the right way but it can still be a royal hair pulling exercise to get the triggers in just the right spot.

It requires 3 objects to work(or 2 if you use the commented out alternate version of camera_move), and you can have cameras that always look at the player, always look at an offset between the player and another object, or completely still views like prerendered backgrounds.

Each camera has a camera entity and its corresponding trigger entity. You assign the "set_cam" and "set_cam_trigger" actions and set each entities skill1 to a value. Both entities must have the same skill1 value and you can use up to 200 cameras, by default, but you can use any total you want by changing the array value. Do not assign "0" as a skill1 value or it'll return without switching cameras. You can also use more than one trigger entity for each camera. This is useful when you need to extend the influence of a specific camera. You can insert an "island" of influence inside the zone of another camera's hotzone, too.

The 3rd object is a look at entity. It is used for an offset(if desired) based on the "cam_factor" variable. If you set it to 0, the camera will always look directly at the player. If you set it to 1, it will always look at the look at entity and will never move...a perfectly still camera. If you set it to any value between 0 and 1, it will always watch the "lerped" spot between the player and the look at entity and will move when the player moves. The downside to this setup is, as is, you can only have one look at object per level. It can easily be adapted so that each camera has its own look at object, but if you don't require an offset, you can comment out the camera_move function and uncomment the other. Using the alternate function, you can still achieve a perfectly still camera by setting the camera entities' flag1 to on. If you want it to follow the player, set it to off.

Code:
/////////////CAM

entity* cam_look_at; //the look at object pointer
entity* cam_ptr; //the camera object pointer
var cam_array[200]; // a maximum of 200 cameras...increase/decrease for your needs
var cam_closest_distance;
var cam_active; //0 = not active; 1 = active
var cam_target[3];  //temp camera storage
var cam_factor = 1; //0 = always follows player
  		    //1 = always look at cam_look_at
  		    //between 0-1 looks at offset between player and cam_look_at

function init_cameras()  //gets first camera
{ 
   get_cam(1); 
}

starter cam_poller() //controls the camera trigger array
{
    proc_kill(4);
    while(1) 
    {
       cam_closest_distance = 100000;
       wait(1);
    }
}

function get_cam(cam_number)  //retrieve fixed view
{ 
    proc_kill(4);
    if(cam_array[cam_number] == 0) { return; } 
    cam_ptr = ptr_for_handle(cam_array[cam_number]);
}

action set_cam //store fixed view
{
    my.invisible = on;
    my.passable = on;
    cam_array[my.skill1] = handle(me);
}

action set_cam_trigger //trigger for fixed view
{ 
    while(player == null) { wait(1); }
    my.passable = on;
    my.invisible = on;
    while(1) 
    {
      if(vec_dist(my.x, player.x) < cam_closest_distance) 
      {
         cam_closest_distance = vec_dist(my.x, player.x);
         get_cam(my.skill1);
      }
     wait(1);
    }
}

action set_cam_look_at //assign to look at object
{
  my.passable = on;
  my.invisible = on;
  cam_look_at = me;
}

function camera_move() //camera looks at cam_look_at or player or inbetween them depending on cam_factor
{
  while(cam_ptr == null) { wait(1); }
  while(cam_active == 1)
  {
    if(cam_look_at != null)
    {
      vec_set(camera.x, cam_ptr.x);
      vec_lerp(cam_target.x, player.x, cam_look_at.x, cam_factor); //get offset based on cam_factor
      vec_set(temp, cam_target.x); //assign to temp
      vec_sub(temp, camera.x);  //get cam_target's distance from camera
      vec_to_angle(camera.pan, temp); //camera looks at cam_target
    }
    wait(1);
  }
}

/*function camera_move() //alternate method...no offset funtionality
{
  while(cam_ptr == null) { wait(1); }	
  while(cam_active == 1)
  {
  	if(cam_ptr.flag1 == 1) //still camera
  	{
   	   vec_set(camera.x, cam_ptr.x);
   	   vec_set(camera.pan, cam_ptr.pan);
  	}
  	else //pivot camera
  	{
           vec_set(camera.x, cam_ptr.x);
     	   vec_set(temp, player.x); //assign to temp
      	   vec_sub(temp, camera.x);  //get player's distance from camera
      	   vec_to_angle(camera.pan, temp); //camera looks at player
        }
   wait(1);
  }
}*/

action player_action //assign to player
{   
   wait(1);
   if (player == null) { player = me; } 
	
   my.narrow = on;	
   //my.fat = on;
   //my.shadow = on;
   //my.cast = on;
	
   //put any other player flags here
	
   cam_active = 1;
   camera_move();
   init_cameras();
   
   //player while loop will go here
}

Posted By: Helghast

Re: The Ultimate Resident Evil Camera - 12/20/04 02:40

nice one (y).

though soon you will get to see my re style camera, which doesnt has the multifloored bug, only a little bit more of code :P

contact mr by PM or mail if you want more info.

regards,
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/20/04 03:07

Well, it's not really a bug...it's just the way the process works. I suppose some code could be added that checks the player's Z and turns off a trigger's influence depending on that value. I'm not really working with multifloored levels anymore(doesn't work too well with adventures), but I'd like to see what you have if it's some other method.
Posted By: Helghast

Re: The Ultimate Resident Evil Camera - 12/20/04 03:16

yeah, well basically all it does, is checking if you are in some content (only downside is that it has to be a map entity), then sets the camera (has to be a model) assigned to the map entity to it...
it is just a lot of code, cuz if you want 10 camera area's, it need 20 pointers.

regards,
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/20/04 03:23

I see then. My version only requires the one pointer and one other if you use the look at object version. You also don't have to come in contact with the trigger object itself. You just have to be within it's field of influence. I think a really cool feature would be if you could actually see this influence field while in game and to be able to edit the triggers in realtime. This would make tweaking either multifloored or levels with a lot of nooks and crannies(and lots of close together cameras) a whole lot easier.
Posted By: Helghast

Re: The Ultimate Resident Evil Camera - 12/20/04 03:39

yeah i know all those pointers suck, but heck, it works flawless, and there is no useless point about them:P

i have had that idea since ever, i dunno if you remember (together with ayrus in A5 later period time it was) i was the guy that made that "resident evil" alley, and i tried to explain this idea to you once too, but you didnt understood really. well now i took the time to learn c script and can realise my own idea's.

atm i am working on a resident evil style tut, alltogether with zombie "ai".

as one of the first things, the camera gets covered (busy with that atm), so if it's finished (if ever, this tut was started for the tutorial A6 contest :P) you'll get the scripts to see

regards,
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/20/04 03:44

Quote:

and i tried to explain this idea to you once too, but you didnt understood really.




I was a dummy back in the A5 early A6 days. I've come a long way in understanding and writing code...at least cameras anyway. Studying different types of cameras is a great way to get into cscript. I learned a ton and it was a fun way to practice.
Posted By: Helghast

Re: The Ultimate Resident Evil Camera - 12/20/04 03:50

yup, same over here.
though i didnt practise camera's in particular, i did study on c script.
come at a stage now, that i can script like hell:P

but that aside, i am glad there are still some people around here that like to play re games, and are willing to make something with it ^^

regards,
Posted By: Rhuarc

Re: The Ultimate Resident Evil Camera - 12/20/04 04:08

Quote:

it is just a lot of code, cuz if you want 10 camera area's, it need 20 pointers.




Actually, this isn't true . A little known fact is that you can store pointers in an array and draw them back out into a "real" pointer to access an object, so:

Code:
define MAX_CAMERAS,20; //hold up to 20 cameras

var camera_objects[MAX_CAMERAS];
var camera_index=0;

function register_camera()
{
if(camera_index>=MAX_CAMERAS){beep; return(0);}
camera_objects[camera_index]=my;
camera_index+=1;
return(1);
}

action my_camera
{
register_camera();
// ... rest of code here
}

entity* temp_camera;

function get_closest_camera() //finds the closes camera object to PLAYER
{ //returns the pointer to the nearest camera
var i;
var best_dist;
var best_pointer;
while(i<camera_index)
{
temp_camera = camera_objects[i];//temp_camera now points to the next camera registered in the array
if(vec_dist(temp_camera.x,player.x)<best_dist)
{
best_dist=vec_dist(temp_camera.x,player.x);
best_pointer=temp_camera;
}
i+=1;
}
return(best_pointer);
}

function test_best_cam() //moves the camera to the closest camera object to the player and rotates to the same angle as the camera object.
{
temp_camera=get_closest_camera();
vec_set(camera.x,temp_camera.x);
vec_set(camera.pan,temp_camera.pan);
}
on_b = test_best_cam;



That should be enough to get you started
-Rhuarc
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/20/04 04:32

I haven't tested this, but one way to have more than one look at object per level may be to change its action to this:

Code:
  

action set_cam_look_at //assign to look at object
{
my.passable = on;
my.invisible = on;
while(1)
{
if(my.skill1 == cam_ptr.skill1)
{
cam_factor = my.skill2;
cam_look_at = me;
}
wait(1);
}
}



You'd have to make sure to include 1 entity per each camera/trigger and make sure each trio's skill1 matches. The entities' skill2 would be your cam_factor value, so you could assign different offsets to each one if desired.

Like I said I haven't tested it, but I don't see why it wouldn't work. If for whatever reason it failed, you'd have to set it up using an array with handles like with the cams and triggers. When you call the get_cam function would be when you called out for a new look at entity.
Posted By: Helghast

Re: The Ultimate Resident Evil Camera - 12/20/04 04:54

@ [rhuarc]

yeah, thanks, i've never been that good at pointers, but i need 10 pointers for the camera, and 10 for the camera switch..

so i'd get 2 arrays, but still i dont get those, i am glad it works for me like this allready:P
maybe someone can explain those better for me??

regards,
Posted By: Error014

Re: The Ultimate Resident Evil Camera - 12/20/04 06:19

In this topic I wrote something about Pointers and handle arrays.
Be sure to read Grimbers Post as well.

LINK
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/21/04 00:53

You might want to give that URL a label..it's going off the screen.

Here's a quick and dirty demo. I commented out the look at object parts and just stuck with the alternate method. You can play with the other one to try and figure it out. There are a couple of cameras with more than one trigger and you might run into a few dead spots, but the demo does its job. WASD moves the player.

The movement code is an unfinished camera relative scheme I've been trying to finesse into shape. It's almost there but a little rough. If you're holding down a movement key when a camera switches, the player's pan locks until you let off of it. If you didn't lock it, the player would spin in place forever(while the key was pressed) at the point of a camera switch.

All the base movement and animation code are from or are derived from scripts provided by KeithBAmbit and/or Gnometech. The playerinput and miscinput scripts are custom versions of Doug's new template files.

Also, there were a couple errors in the code in the first post. Mainly missing brackets or spelling mistakes, but there was a vec_set missing, too. My own version of this code doesn't require it but removing certains parts of it required the additional of an extra line and I had forgot to do so. Everything should be corrected now.

http://www.geocities.com/hainesrs/tester3.zip
Posted By: Rhuarc

Re: The Ultimate Resident Evil Camera - 12/21/04 03:55

Quote:

In this topic I wrote something about Pointers and handle arrays.
Be sure to read Grimbers Post as well.

LINK




Yes, but the thing I was pointing out is that using handle and ptr_for_handles is completely pointless, you can store the pointer itself rather than a handle into the array .

-Rhuarc
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/21/04 08:48

I like your method but it always looks for the closest camera to the player. With the setup I posted, it goes after the closest trigger and the camera can be anywhere at any distance.
Posted By: Evil_Level_Designer

Re: The Ultimate Resident Evil Camera - 12/21/04 09:40

I now see what you mean , and i'm getting it , but one thing i see is , there is no cameras in the scene (Positions). I map in max and import to GS , I have all my maps already set in max , and they export fine , but they arent entities, would there be a way to get this script to work with those cams ?
Posted By: qwerty823

Re: The Ultimate Resident Evil Camera - 12/21/04 09:59

Quote:

Quote:

In this topic I wrote something about Pointers and handle arrays.
Be sure to read Grimbers Post as well.

LINK




Yes, but the thing I was pointing out is that using handle and ptr_for_handles is completely pointless, you can store the pointer itself rather than a handle into the array .

-Rhuarc




Only if you dont want to save/load your game. If you store the pointers and do a save/load, expect a crash.
Posted By: Rhuarc

Re: The Ultimate Resident Evil Camera - 12/21/04 10:08

Of course, but for general purposes, it is extremely useful... Besides, handles work the same way

-Rhuarc
Posted By: qwerty823

Re: The Ultimate Resident Evil Camera - 12/21/04 10:20

No, handles will save properly, so when you do a gameload, they will still be just as valid before the save. Pointers will not (cept maybe when using "entity *", since the engine could do the handle()/ptr_for_handle() internally at save/load time).
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/21/04 12:35

Quote:

I now see what you mean , and i'm getting it , but one thing i see is , there is no cameras in the scene (Positions). I map in max and import to GS , I have all my maps already set in max , and they export fine , but they arent entities, would there be a way to get this script to work with those cams ?




Do you use the MAX2GS plugin? If so, doesn't it allow you to export entities with the level? I was under the impression that it exported just about everything. The only other thing I can offer is after you load your MAX level into WED, simply place the camera entities from there. All you have to doing is update entities which takes no more than a couple seconds.



To address the demo, the main reason I didn't implement the look at object code intoit is because it was giving me some problems. The camera wasn't switching correctly but I now realize this was because of the missing vec_set I mentioned in the demo post. That line is what sets the cam_ptr pointer to the camera, so...uh yeah...that's why there was no change. My own personal version takes care of that in the functions I took out, so my own senile mind got in the way(again) when porting this over to the contributed version.
Posted By: Evil_Level_Designer

Re: The Ultimate Resident Evil Camera - 12/21/04 14:05

yes i'm using Max2Gs , and it exports all the cameras perfectly. But it doesnt export them as entities , it exports them as cameras (like when you right click on a wed window and select add position and sets a camera) , but i dont see an option to add any actions to them. So I'm not sure if there's something i'm doing differently or if i'm just missing something. Here's a pic of a very small and basic test level , you can see the cams i have on there , it goes to camera1 when i run it , but dont really understand how to implement the code because i cant set an action for the cameras when i right click them .

http://home.rgv.rr.com/demonicdynasty/temp.html
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/21/04 14:38

Unless there's a way to access a position, via cscript, and assign something to it, then you'll have to either make sure to include your camera/trigger entities at the camera's position before exporting or go through and replace all of the positions with them in WED.
Posted By: myrlyn68

Re: The Ultimate Resident Evil Camera - 12/21/04 14:48

A quicker way of handling that is to change out one of the cameras in WED (or place an entity at nearly the exact location of the camera) and then pop open the WMP with a text editor. You should be able to see clearly how the entity position is identified compared to a camera. Then just run a Find/Replace Routine and reopen in WED. You should now have the appropriate entities where the cameras used to be. Assign the camera action to them (again you can do that in the text editor if you feel comfortable with it), and you are good to go.

Works well with other things too - especially if you have a lot of entities to change out for one reason or another.
Posted By: Evil_Level_Designer

Re: The Ultimate Resident Evil Camera - 12/22/04 07:58

Would it be possible to do something like , have an invisible model used for the trigger , and have the trigger set view to one of the cameras already in the level , say if coliision with me , set view = cam01 , and make another one for camera 2 that would say if collision with me , set view = cam02. So that it would just point to use the other cam as oppossed to creating one.
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/22/04 09:48

Nothing gets created in the script....it takes what you've placed in the level and uses the skill1 values to keep everything paired up and working right. You can also use any kind of entity that can have an action assigned to it for the camera, so that means models, map entities, or sprites.

I think the only way you can get access to an actual "position" would be to use "str_for_entname"(I think that's it) to get the name of the position(pos_000, pos,001, etc) and get that into the array in the "set_cam" action some how.

I think it would be less hassle to simply replace the positions themselves with an entity and use the scripts as designed. Since you are using MAX2GS, I know you can export non-level block models and sprites with the level itself, or you can do it like myrlyn68 suggested.
Posted By: Evil_Level_Designer

Re: The Ultimate Resident Evil Camera - 12/23/04 09:33

Well I did what Myrlyn68 sujested , but the cameras are nowhere close to the original ones , the script does work though , as cameras do change , but things dont look right at all , I guess i'll keep on fiddling with it.
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 12/23/04 11:17

Sometimes during runtime you'll find that a camera will get skipped when there's no reason for it to. I don't know why it does this, but the way to fix it is to group all of your cameras and triggers together, save, delete the group, update entities build, undo to undelete them, and then update entities again. The missing camera will magically work again. It did it to me when I was creating the demo and that was the first time it had happened in quite some time.
Posted By: Orange Brat

Re: The Ultimate Resident Evil Camera - 02/20/07 05:34

I completely gutted this and updated the scripts to more reflect that used in The Disenfranchised, as well as newer engine commands (time_step and c_instructions although it is setup to still use the equivalent of the old ent_move). It still lacks the smooth transition from node to node that the game has, but this is a bit better.

I also updated the controls, animation, and player's physics scripts so they're consistent with those found in the 3rd person cameras I have floating around. I also reduced the test level play area and the number of cameras (from 7 to 3).

Finally, you can set all of your camera parameters from WED, now.

http://www.geocities.com/hainesrs/tester3.zip
Posted By: DuaneDawson

Re: The Ultimate Resident Evil Camera - 09/05/16 17:22

how do you use this code?
what do i need to place in med and had what action to what?
© 2024 lite-C Forums