Camera Views when Jumping to a new Area


#1

Hi Guys, I have a question about camera view when jumping to a new area when a conversation ends (Action Taken). Sometimes before jumping to new area the camera will pan away from the characters and start the next area a long way away from the PC forcing a player to mouse scroll closer or keyboard closer into the new area.

Now, sometimes after the conversation ends the camera stays still and the location is perfect when the pc jumps to the next area. I’ve tried experimenting with different camera functions. top down, chase etc. Is there a way to keep the camera from fading out? I know it sounds trivial and it’s nothing game breaking, I just would prefer the camera to be closer when starting in a new area.

I hope I’ve explained my queries correctly. As always, thanks so much in advance!


#2

I’ve only done this when the new area opens with a cutscene, but I imagine the same applies to a transition into normal gameplay.

In the area OnEnter event, the PC’s new location is not yet defined. So, I use DelayCommand and ExecuteScript to run the camera script 2 seconds later. That way, the camera script can rely on the PC’s new location as a basis for the camera position. This also ensures that the camera script overrides the default camera position set by the engine on entry.

In my experience, 2 seconds is long enough to work reliably, but short enough for an immediate transition to the new camera position, without seeing the default first.

The nwscript camera functions work fine, but I have to say that life is much easier with the Gestalt cutscene package (well worth the learning curve). You might consider starting a cutscene to position the camera, then stopping it, using the option to conserve the camera position.

I find myself using GestaltCameraCrane all the time, even when I don’t want the camera to move, as it’s the most general function, which works fine, even if position1 and position 2 are identical.

I should emphasise that if you do use the Gestalt functions, they need to be issued by the camera script 2 seconds after OnEnter. If you issue them directly from the OnEnter script, using the Gestalt delay capability, you will run into the position anomaly mentioned above.

I’m not sure, but you might also be able to overcome the timing issue by setting the camera position in a trigger on arrival, rather than on area entry. However, you’d have to paint a lot of triggers if you wanted that to happen everywhere!


#3

Thanks very much for your response Pro. I actually tried the Gestalt camera set up but to no avail. However I didn’t use the 2 sec delay. I’ll give that a shot as well. Thank you very much for responding.


#4

Pro, for some reason I’m still having trouble: Here’s basically what I have when entering said area: I deleted some of the details in the script as far as whats happening to the PC as to not reveal spoilers. Hopefully you can make me understand it. Thanks again! This is on OnEnter in area properties.

#include “in_g_cutscene”
void main()
{
int nSlot;
effect eVFX;
effect eEffect;
object oPC = GetEnteringObject(); // Change this line for use in other events.

// Make sure oPC is a PC (not necessary in a module's OnClientEnter).
if ( !GetIsPC(oPC) )
    return;

 //something happens



}



 object oArmor = CreateItemOnObject("some_armor", oPC);

// Put on the armor
 AssignCommand(oPC, ActionEquipItem(oArmor, INVENTORY_SLOT_CHEST));

  // Cutscene functions:
BlackScreen(oPC);


// Have the PC perform a sequence of actions.
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 12.0));
eEffect = SupernaturalEffect(EffectAbilityDecrease(ABILITY_STRENGTH, 3));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);







// Cutscene functions:
   // Camera movements
  // Set initial position for camera, facing due north from 10.0m directly above the player




DelayCommand(2.0, SetCutsceneMode(oPC, TRUE));
DelayCommand(2.0, SetCameraMode(oPC, CAMERA_MODE_CHASE_CAMERA));
DelayCommand(3.0, FadeFromBlack(oPC, FADE_SPEED_SLOW));

// Have text appear over the PC's head.
DelayCommand(7.0, FloatingTextStringOnCreature("Ugghhh! My head...So...dizzy..", oPC));
DelayCommand(15.0, FloatingTextStringOnCreature("Wh-Where in the nine hells am I?", oPC));




// Cutscene functions:
DelayCommand(15.0, SetCutsceneMode(oPC, FALSE));

}


#5

To change the camera position to exactly what you need, you’d need to use functions like SetCameraFacing (which also controls the zoom) and possibly SetCameraHeight (or the Gestalt equivalents).

For reasons given previously, I doubt whether camera functions will work in an area OnEnter script. As a rule of thumb, DelayCommand tends to acquire any values it needs immediately, without waiting for the delay. So if today is Sunday, a command delayed until Monday will still think it’s Sunday.

The way to work around this is to put all the delayed camera work into a script. Let’s call it myscript:

DelayCommand(2.0, ExecuteScript("myscript", oPC));

The difference is that values such as the PC’s position will not be acquired until the new script starts. In the new script, OBJECT_SELF will be the PC.


#6

That code you posted shouldn’t even compile. You have an extra close brace ‘}’ just after

// Make sure oPC is a PC (not necessary in a module's OnClientEnter).
if ( !GetIsPC(oPC) )
    return;

 //something happens

}

Another little thing is that you have 2 DelayCommand instructions with the same values that might prove problematic -

DelayCommand(2.0, SetCutsceneMode(oPC, TRUE));
DelayCommand(2.0, SetCameraMode(oPC, CAMERA_MODE_CHASE_CAMERA));

because SetCutsceneMode will need to finish before SetCameraMode fires otherwise there is no guarantee of the results. I would therefore change the delay slightly to 2.5 for the SetCameraMode to be on the safe side. So with a few minor edits your code would look like this

#include “in_g_cutscene”

void main()
{
    int nSlot;
    effect eVFX;
    effect eEffect;
    object oArmor;
    object oPC = GetEnteringObject(); // Change this line for use in other events.

    // Make sure oPC is a PC (not necessary in a module's OnClientEnter).

    if(GetIsPC(oPC))
    {
        oArmor = CreateItemOnObject("some_armor", oPC);

        // Put on the armor

        AssignCommand(oPC, ActionEquipItem(oArmor, INVENTORY_SLOT_CHEST));

        // Cutscene functions:

        BlackScreen(oPC);

        // Have the PC perform a sequence of actions.

        AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 12.0));
        eEffect = SupernaturalEffect(EffectAbilityDecrease(ABILITY_STRENGTH, 3));
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);

        // Cutscene functions:
        // Camera movements
        // Set initial position for camera, facing due north from 10.0m directly above the player

        DelayCommand(2.0, SetCutsceneMode(oPC, TRUE));
        DelayCommand(2.5, SetCameraMode(oPC, CAMERA_MODE_CHASE_CAMERA));
        DelayCommand(3.0, FadeFromBlack(oPC, FADE_SPEED_SLOW));

        // Have text appear over the PC's head.

        DelayCommand(7.0, FloatingTextStringOnCreature("Ugghhh! My head...So...dizzy..", oPC));
        DelayCommand(15.0, FloatingTextStringOnCreature("Wh-Where in the nine hells am I?", oPC));

        // Cutscene functions:

        DelayCommand(15.0, SetCutsceneMode(oPC, FALSE));
    }
}

Hope that helps.

TR


#7

The identical delays wouldn’t be required if broken out into a separate script, of course.

For information, though, identical delays are even worse than you think - the commands are executed in reverse order, according to the Lexicon.


#8

Okay I’m going to give you the script in it’s entirety which compiles and run’s beautifully. Except for the damned camera distance. I tried what I thought I understood in your replies yet to no success. I know it’s me and my novice coding ability(tho’ I’m learning!) I freaking hate asking someone to do the work for me but at this point I’m down to Homer hairs after all the follicles I’ve ripped from my scalp trying to understand this. Here’s the entire script on the OnAreaEnter:

#include “in_g_cutscene”
void main()
{
int nSlot;
effect eVFX;
effect eEffect;
object oPC = GetEnteringObject(); // Change this line for use in other events.

// Make sure oPC is a PC (not necessary in a module's OnClientEnter).
if ( !GetIsPC(oPC) )
    return;

 SetXP(oPC,0);

// Destroy the items in the main inventory.
object oItem = GetFirstItemInInventory(oPC);
while ( oItem != OBJECT_INVALID ) {
    DestroyObject(oItem);
    oItem = GetNextItemInInventory(oPC);
}
// Destroy equipped items.
for ( nSlot = 0; nSlot < NUM_INVENTORY_SLOTS; ++nSlot )
    DestroyObject(GetItemInSlot(nSlot, oPC));

// Remove all gold.
AssignCommand(oPC, TakeGoldFromCreature(GetGold(oPC), oPC, TRUE));
 object oArmor = CreateItemOnObject("slavegarb", oPC);

// Put on the armor
 AssignCommand(oPC, ActionEquipItem(oArmor, INVENTORY_SLOT_CHEST));

  // Cutscene functions:
BlackScreen(oPC);


// Have the PC perform a sequence of actions.
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 12.0));
eEffect = SupernaturalEffect(EffectAbilityDecrease(ABILITY_STRENGTH, 3));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);


// Relieve the PC of its possessions.




// Cutscene functions:
   // Camera movements
  // Set initial position for camera, facing due north from 10.0m directly above the player
    DelayCommand(2.0, SetCutsceneMode(oPC, TRUE));
    DelayCommand(2.5, SetCameraMode(oPC, CAMERA_MODE_CHASE_CAMERA));





SetCameraMode(oPC, CAMERA_MODE_CHASE_CAMERA);

DelayCommand(3.0, FadeFromBlack(oPC, FADE_SPEED_SLOW));

// Have text appear over the PC's head.
DelayCommand(7.0, FloatingTextStringOnCreature("Ugghhh! My head...So...dizzy..", oPC));
DelayCommand(15.0, FloatingTextStringOnCreature("Wh-Where in the nine hells am I?", oPC));




// Cutscene functions:
DelayCommand(15.0, SetCutsceneMode(oPC, FALSE));

}
Spoilers be damned! I really want to understand this. And as I said this OnAreaEnter fires beautifully when introducing the PC into the story. Except for the camera distance:tired_face:

Thanks as always for your patience and courtesy when dealing with my inquires.


#9

Did you see my post that this is a reply to?


#10

After tidying it up and editing it as @Proleric advised you to do your code should look something like this (Note: untested code)

#include “in_g_cutscene”

void DelayCameraMove(object oPC);

void main()
{
    object oPC = GetEnteringObject(); // Change this line for use in other events.

    // Make sure oPC is a PC (not necessary in a module's OnClientEnter).

    if(GetIsPC(oPC))
        DelayCommand(2.0, DelayCameraMove(oPC));
}

void DelayCameraMove(object oPC)
{
    int nSlot;
    effect eVFX;
    effect eEffect;
    object oItem;
    object oArmor;

    SetXP(oPC, 0);

    // Destroy the items in the main inventory.

    oItem = GetFirstItemInInventory(oPC);

    while(oItem != OBJECT_INVALID)
    {
        DestroyObject(oItem);
        oItem = GetNextItemInInventory(oPC);
    }

    // Destroy equipped items.

    for(nSlot = 0; nSlot < NUM_INVENTORY_SLOTS; ++nSlot)
        DestroyObject(GetItemInSlot(nSlot, oPC));

    // Remove all gold.

    AssignCommand(oPC, TakeGoldFromCreature(GetGold(oPC), oPC, TRUE));

    oArmor = CreateItemOnObject("slavegarb", oPC);

    // Put on the armor

    AssignCommand(oPC, ActionEquipItem(oArmor, INVENTORY_SLOT_CHEST));

    // Cutscene functions:

    BlackScreen(oPC);

    // Have the PC perform a sequence of actions.

    AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 12.0));
    eEffect = SupernaturalEffect(EffectAbilityDecrease(ABILITY_STRENGTH, 3));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);

    // Relieve the PC of its possessions.

    // Set initial position for camera, facing due north from 10.0m directly above the player

    SetCutsceneMode(oPC, TRUE);
    SetCameraMode(oPC, CAMERA_MODE_CHASE_CAMERA);
    SetCameraMode(oPC, CAMERA_MODE_CHASE_CAMERA);

    DelayCommand(1.0, FadeFromBlack(oPC, FADE_SPEED_SLOW));

    // Have text appear over the PC's head.

    DelayCommand(5.0, FloatingTextStringOnCreature("Ugghhh! My head...So...dizzy..", oPC));
    DelayCommand(12.0, FloatingTextStringOnCreature("Wh-Where in the nine hells am I?", oPC));

    // Cutscene functions:

    DelayCommand(12.5, SetCutsceneMode(oPC, FALSE));
}

Note 2: Delays in your code have been adjusted to reflect the overall delay.

One other little point.Look at this thread. It tells you how to get more from these threads including how to post code so that it is colourised and retains its original layout.

TR


#11

Thanks to you both. I got the OnEnter to fire nicely with a mini- Gestalt cutscene and using the crane camera function to make a nice view for the player. Funny thing was that when the cutscene ended, the camera view would fade way back outward again. I fixed this by adding a cutscene move to object command which triggered an NPC start conversation that keeps the whole scene compact. I love it. Thanks for your script advice and the link Tarot Redhand.


#12

Thanks Proleric for your help on my OnEnterArea predicament. I ended up using the Gestalt cutscene functions. as you advised and made a nice little OnEnterArea scene once I played with the camera angles. Thanks very much for your help on this issue. You and Tarot will probably forget more about coding than I’ll ever be able to learn so I appreciate the time, folks like you two, take to respond. Thanks again!