Skip to content

Mass Effect 3: Camera Modding, From Noob to Not So Noob

Fernando Quant edited this page Jun 28, 2021 · 86 revisions

Hello there,
The goal of this guide is to help you understand the basics and not so basics of camera modding for Mass Effect 3.
This guide has been written and tested with Mass Effect 3, but its probably applicable to the Legendary Edition version, and for the other games as well. However, more testing is required.

Content

The Basic Concepts

Before we begin, let's clear some points so you understand a bit better what we'll be talking about.

Types of Cameras

In the games, cameras appear in two types of situations: Animcutscenes and BioConversations.
Animcutscenes are cinematic situations, done in-game, where the player has no control or interaction. Editing these are not covered by this guide.
BioConversations, on the other hand, are cinematic situations where conversations happen and the user may have input either in the form of dialogue choices or paragon/renegade interrupts. Sometimes no interaction happens, but generally this a sign of them. These can be Ambient conversations, where no camera work happens, or enter into Conversation mode, where camera work does happen.

Now, if in a conversation there is no BioStage (more on them later), or no valid Switch Camera, the game will create Behavior cameras, which are cameras created out of nowhere to try to automatically show the appropriate stuff. We have no control over them and are a last resort type of thing. However, if a BioStage is present, two types of cameras can coexist:

  1. Switch Cameras: These are pre-built cameras with their position and other values already set in the BioStage. Think of them as premade cameras you can choose from. These can not be manipulated, but you can select which "angles" to use, so they provide a quick solution.
  2. Matinee Cameras: These are cameras for which you can control their position, rotation, and FOV. Given that you can control them manually, these are the ones you can get the most out of, but take the most effort out of the cameras we've discussed.

Through this guide, we'll be working with switch and matinee cameras under the assumption that you've found a conversation that has a BioStage, or that you've added one. If you want to learn how to identify if your conversation has one or you want to learn how to add it if it's missing, please refer to the appropriate Other Topics section.

Opening the InterpData

To do anything with the switch or matinee cameras we need to open the InterpData that is played during the piece of dialogue. To put it in simple terms, an InterpData is a container that can hold the controls for stuff related to the dialogue, cameras included.
You can learn how to find the appropriate file that has the dialogue and open it in the Miscellaneous section, and get a more in-depth explanation of the Dialogue Editor in the Overview of the Dialogue Editor guide, by beccatoria.

Suffice it to say, after you open your dialogue file in the Dialogue Editor, you'll find a screen like the following:

Figure 1 Figure 1

In there, select the dialogue node you want to edit, and then click on the marked icon in the image above, which will open its associated InterpData in the Interp Viewer tool. You'll end up with a window that will look like the following, minus or plus some extra elements:

Figure 2 Figure 2

  1. The InterpGroups area. This area displays the InterpGroups that the InterpData references. An InterpGroup is like a sub-container inside the InterpData for different elements related to the conversation.
  2. The Conversation InterpGroup. For our purposes, this InterpGroup is where you'll be able to switch between switch cameras, but it's also used to play audio lines, and/or control pawns animations and related things.
  3. The InterpGroupDirector. This group is responsible for controlling which matinee camera is being displayed, switching between matinee cameras and the Conversation group, and controlling the Depth of Field (DOF).
  4. The Camera InterpGroup. Every one of these (there can be multiple) controls one camera actor, which is what we call a matinee camera. Inside this group, you can control the position, movement, and Field of View (FOV) of the matinee camera.
  5. The Interpreter. This area displays the InterpDatas, InterpGroups, and Tracks' properties. What is displayed depends on what you have selected. When launching from the Dialogue Editor, you'll see the InterpData's properties.
  6. The InterpData list. A list of all the InterpDatas contained in the file, which you can use to quickly switch between them if you know their number.

A lot of the time, InterpDatas will only have the Conversation group, which means that only switch cameras are being used for that part. You can go to the Other Topics section to learn how to add the InterpGroupDirector and matinee camera groups if you don't want to just rely on switch cameras.

Add/Remove/Reorder Keys/Items in a Track

Through this guide, we'll find multiple times arrays that hold the Items that control things like which camera is active, their position, rotation, and other similar things, like the following:

Figure 3
Figure 3

In order to not repeat the same concept multiple times, let's learn how to add, remove, and reorder array items. If you don't completely understand this right now don't worry, you can always come back to take another look later.

To add a key, click on your desired array, and then in the Interpreter's toolbar, you should see an option that says "Add Array Element", click on it.

Figure 4
Figure 4

This will add a new array element to the end of the array, with the same values as the last element. You can then edit it to the values you want it to have.

To reorder the array items you can click on the element, and then on the toolbar click on the arrows.
To remove an item just click on the item, and from the toolbar click on "Remove Array Element".

Figure 5
Figure 5

Changing Values

If you find a value that you want to change, changing it is pretty simple.

Figure 6
Figure 6

  1. Click on the property you want to change.
  2. Input the new value in the toolbar, or select it from the dropdown.
  3. Click on set. (You'll need to save the file for the changes to be final)

Pay special attention to the Index. In this example, a camera group named Cam1 is not the same as Cam, with index 2, which is displayed as Cam_1 (the index is 0-based).

The InterpGroupDirector

Here's where you switch between matinee cameras, go back and forth between them and the Conversation group, and control the DOF.

If you expand this group, the following Tracks will be displayed:

Figure 7
Figure 7

  1. The InterpTrackDirector track. This is where you control which camera is active and when.
  2. The BioEvtSysTrackDOF track. Here is where the Depth of Field (DOF) is controlled.
  3. The track's keys. These are the points in the timeline where values are set to happen. Multiple keys allow for different values to be set in the timeline.
  4. The InterpTrackEvent. This, along with other tracks, are tracks that may or may not be present in your group. They allow for more specific effects like fades, rumbles, opening doors, and others.

Camera Switching

Clicking on the InterpTrackDirector track will reveal the following properties in the interpreter area:

Figure 8
Figure 8

The important part here the CutTrack array, which is where you can set the keys to control the camera switching. Inside an Item of the CutTrack you'll find:

  1. TargetCamGroup: Here you can input the exact name of the matinee camera group (from the current InterpData)that you want to be active at that key in time. Alternatively, if you want to display the switch camera selected in the Conversation group, you can set the property to "Conversation".
  2. Time: Controls when the game is gonna switch to the given camera.
  3. TransitionTime: This sets the length of the transition between the previous camera and the current one. A value of 0 seconds makes the change instantaneous, while a higher number of seconds makes the transition longer. This transition is done by moving the previous position of the camera until it matches the current one, rather than by a fade in/out or a blend.
  4. bSkipcameraReset: Setting this property to true makes it so that the camera actor won't return to its default position once the InterpData is over. Most of the time it's better to leave this as false to avoid weird bugs or not knowing why the camera is in X or Y position.

So, you can change or add new items and the game will activate those cameras at the appropriate times.

Depth of Field

The Depth of Field controls the area in focus and the area out of focus.
This can be edited from the BioEvtSysTrackDOF track.

Figure 9
Figure 9

From here you can add and edit any of the DOF items inside the m_aDOFData array.
The properties you can control are the following:

Figure 10
Figure 10

  1. fFocusDistance: The distance from the camera to the center of the focused area. A higher value pushes the focused area away from the camera.
  2. fFocusInnerRadius: The radius of the area in focus. A higher value makes the area bigger.
  3. fFallofExponent: In theory it controls how abrupt or gradual the focused area extends/ends at the edge of its area. However, its effects are either not entirely clear or a bit too subtle, but lower values seem to reduce the focused area.
  4. fMaxNearBlurAmount: The amount of blur between the center of the focused area and the camera. It can go from 0 to 1, where 0 is no blur and 1 is max blur.
  5. fMaxFarBlurAmount: Similar to fMaxNearBlurAmount, but it affects the area from the center of the focused area and away from the camera.
  6. fBlurKernelSize: Controls how strong the blur is in the affected areas.
  7. fInterpolateSeconds: Controls how long it takes for the item's values to be at full effect. It serves as a transition from the previous DOF item to the current one. A value of 0 seconds will make the change instantaneous, while a bigger number of seconds allows for a transition. Keep in mind that the transition will begin before the item, and end at the item's time. So a value of 2 seconds will start transitioning 2 seconds before the item.
  8. bEnableDOF: Enables/disables the DOF for that key.
  9. vFocusPosition: In theory it should control the position, in the X, Y, and Z-axis, of the focused area from the center of it. However, changes to these don't seem to show any change.
  10. cModulateBlurColor: Its effects are unknown.

Here's a visual help for the effects of these values:

Figure 11
Figure 11

Figure 12
Figure 12

Switch Cameras

These are the easiest cameras to use because their information is already set and all you need to do is select the proper one. However, their limitation is the same: they are already prebuilt in the BioStage and you can't change their values. But, in order to truly get all of this, let's first understand what a BioStage is.

What is a BioStage?

When dialogue occurs between actors, either in an ambient conversation or in conversation mode, the game can have them perform the dialogue where they stand, and create automatic behavior cameras (in conversation mode), or it can have a BioStage.
This, like the name suggests, is a sort of stage that contains Nodes and switch cameras. These nodes are predetermined locations where actors can stand and be set at. The switch cameras are cameras set at specific angles to focus on the nodes.
In-game we do not have a way of visualizing where the nodes or switch cameras are, aside from trial and error, but here is how a BioStage looks like when exported and viewed in a 3D modeling program like Blender:

Figure 13
Figure 13

The blue triangles are the nodes, and the brown bones are the switch cameras. A BioStage can contain more than two nodes, either to have more actors set at specific places or because through an animation you want the actors to reach those nodes and be set in them with switch cameras ready to focus on them.
The red rectangle is the boundary area of the stage, which can sometimes lead to collision issues if it clashes with a blocking volume, but more on that in the Adding a BioStage section.

To figure out what BioStage your dialogue is using and what nodes your actors are into, in-game start the conversation you want to edit, open the console and input the playersonly command to freeze the game (this is not really required, but it is helpful to have things frozen). Then open the console again and input profile conversation. This will display on-screen information related to the conversation like the following:

Figure 14
Figure 14

The information we care about is the one surrounded in colored boxes:

  1. Light-blue box: This is the name of the file that contains the BioStage. Most of the time it's the "base" file of the conversation, meaning that if the conversation is in the BioD_Something_LOC_INT.pcc file, then the BioStage will be in BioD_Something.pcc one.
  2. Green box: The location of the sequence in the file. If you open it with the Package Editor tool this is the exact package path, but if you open it via the Sequence Editor you can ignore the TheWorld.PersistentLevel part.
  3. Blue box: The nested sequence has the relevant elements.
  4. The purple box: The name of the sequence object that starts the conversation.
  5. The red box: The nodes in which the actors are placed. Keep these in mind for choosing which cameras to use, which we'll talk about in the next point.

Now that you know in what sequence your BioStage is, search for it in the Package Editor and then open it in the Sequence Editor, or more easily, open the file with it directly and look for the StartConversation object.
Once you find it you will have something like the following:

Figure 15
Figure 15

The colored boxes are referring to the same things as in Figure 14. And surrounded by black and numbered are:

  1. The BioStage's tag name. ST_citpres_tali_talk1_d in this case.
  2. The BioStage's object name (click on the object from point 1 to get this). The previous thing was the tag name, which we'll use later, but this is the name BioStage object itself.

After getting the previous information, open the file in the Package Editor and go into the Tree View tab.
Let's first take a look at the BioStage object, which is located inside TheWorld.PeristentLevel. After finding it click on it and you'll see something like this:

Figure 16
Figure 16

On the Interpreter, you can see the BioStage's location and rotation. This dictates where it is located in the level. You can also see the tag, which is what was used in the Sequence Editor.

Now let's take a look at the BioStage itself. The easiest way to find it is, from the Tree View, to type the tag's name into the search box and click "Search". This should directly take you to the BioStage.

Figure 17
Figure 17

On the Interpreter you can see the BioStage's properties. From which m_aCameraList is the one we care about since it contains the list of available switch cameras and their properties. You can safely ignore the other properties since we won't be messing with them.
Also, on the left, right under (Exp) 780 ST_citprs_tali_talk1(BioStage) is the SkeletalMesh, which is the 3D mesh that has the nodes and bones that were shown in Figure 13.

If you click on the SkeletalMesh, go to the Binary Interpreter tab, and expand its RefSkeleton part, you can see the name of the nodes and cameras it contains.

Figure 17.5
Figure 17.5

Now that you know what the BioStage elements look like, in the future, you can look for it directly in the Package Editor without having to go into the Sequence Editor, but we've gone through the longer route to show all the basics.

Choosing a Switch Camera

Having learned what a BioStage is, we can talk about how to choose the switch cameras and switch between them.

Operations on switch cameras are done in the BioEvtSysTrackSwitchCamera track inside the Conversation InterpGroup. Expanding one and clicking on the proper track will reveal the following information:

Figure 18
Figure 18

  1. The m_aCameras array: An array that contains the Items that decide which switch camera is used.
  2. The m_aTrackKeys` array: An array whose items control when the items in the previous array occur in time. The number of items in this array must correspond to the one in the previous one, in the same order.
  3. nmStageSpecificCam: Here's where you write which switch camera to use for that item.
  4. bForceCrossingLineOfAction: Setting this to true should, in theory, allow the camera to cross the action line between the characters, but its exact behavior is unknown to me at the time of writing this guide.
  5. bUseForNextCamera: Setting this to true will queue the switch camera to take effect after the InterpData ends. Why would one want to enable this behavior is covered in the Controlling Dialogue Wheel Cameras section.

Now, you may be wondering how can you know which cameras you have available, what do their names mean, and how to know how they look.
To know which ones are available you have to check the items in the m_aCameraList array, which are part BioStage object. After getting to the object and expanding the list in the Package Editor, as seen in the BioStage section, you'll get something like the following:

Figure 19
Figure 19

  1. tDOFData: The DOF values for this camera. It only displays the fFocusInnerRadius and fFocusDistance values.
  2. nmCameraTag: The name tag of the camera. This is what you want to input into the BioEvtSysTrackSwitchCamera. Do note that the last number of the tag is set via the index, rather than the name itself.
    Figure 19a
  3. fFov: The FOV value of the camera.
  4. fNearPlane: Determines the radius around the camera that will erode (clips) other objects that may obstruct it. The lower the value the less objects that will be affected. Usually, this value will be set to 0 or a very low value, but if it has a high value and it's affecting your scene in undesired ways, there are solutions for it, as explained in the Dealing with Camera Clipping section. By the way, actors are also affected by this setting, including Shepard.
  5. bDisableHeightAdjustment: Usually switch cameras adjust for the height of the actors, but if you can use this property to disable that behavior.

An important note: While it's certainly possible to edit all of these properties, due to how the game handles memory and clones of the same object, it's better to leave them as-is if you don't want to be surprised by the changes affecting other conversations as well unless you change the name properties of the BioStage in all of its occurrences of the file to make it independent. But we won't be covering this since for the situations where you'd want to edit them, it's probably better to just use a matinee camera.

Knowing which switch cameras are available, let's proceed to understand what their name means.
A switch camera' name follows a name pattern of camX_Y_Z, where X is the node number from which the camera is looking from, Y is the node number of the node the camera is looking at, and Z is a number (set by the index) to differentiate between multiple cameras looking at the same node from the same node.
To give an example, cam2_1_4 would be a camera looking from node 2, at node 1, and possibly being the fourth one set with this configuration. We say possibly because sometimes for some reason you'll have cam2_1_1, cam2_1_2, cam2_1_3, and cam2_1_21.

So far we know which switch cameras area available, and how to know which ones you may be interested in based on their name and the nodes your actors are set into. However, to know how the angles will actually look like there's no other option rather than to try them in-game.
A very simple way to do this is to set keys for all the available switch cameras in a single InterpData, and then run it in-game and take screenshots/videos of how they look.

Before concluding this section, one last thing that you need to know is that if you just want to use one switch camera, your InterpData does not have a BioEvtSysTrackSwitchCamera in the conversation group, and you don't want to bother adding one, you can choose a camera by using the Camera Intimacy setting of the dialogue nodes in the Dialogue Editor:

Figure 20
Figure 20

Here you have to set the last number of the switch camera, with the caveat that the node from which it looks from and the one it looks at (the first two numbers in the switch camera) will be decided by what node the dialogue bit happens in.
Usually, a Reply Node will look from the BioStage node of whoever is the owner of the conversation, to the BioStage node of whoever is the listener (usually the Player); while an Entry Node will usually look from the BioStage node of whoever is the listener (usually the Player), to the BioStage node of whoever is the owner.

Matinee Cameras

This type is the one for which you can control their position, rotation, and FOV.
To get a bit more of a technical understanding, matinee cameras are actors, just like the player or any of the actors that appear in a conversation, but without a mesh. So, you can control their position and rotation and then "look through their eyes".
What we're gonna explore is how to control them from and during our InterpDatas (their position, rotation, and FOV, get reset after the InterpData ends).

While you can switch to different switch cameras (pun intended) from a single track in the Conversation InterpGroup, for each matinee camera you want to use you'll need a new Camera InterpGroup. We'll cover how to add new ones in the Ading a new Matinee Camera section, and right now will limit ourselves to work with only existing Camera InterpGroups.

Opening an InterpData that contains a matinee camera and its group, the following elements will be displayed:

Figure 21
Figure 21

  1. m_nmSFXFindActor: The matinee camera actor's tag name. In simple words, the name of the matinee camera to control.
  2. GroupName: The name of the InterpGroup. It's good practice to keep it the same as the matinee camera name to avoid future confusion.
  3. The InterpTrackMove track: The track that controls the position and rotation of the camera.
  4. The FOVAngle track: The track that controls the Field of View (FOV) of the camera.

Remember that both the m_nmSFXFindActor and the GroupName can have indexes reflected in the name, so Cam1 is not the same as Cam, with index 2.

Position and Rotation

Click on the InterpTrackMove track of your chosen camera, and you'll see the following:

Figure 22
Figure 22

  1. PosTrack: This track contains the controls for the camera's position.

Figure 23
Figure 23

As with most other arrays, each key in the timeline maps to an item in the Points array. Expanding an Item reveals the controls for the camera's position:

  • The InVal controls when the item happens on the timeline.
  • The OutVal contains the X, Y, and Z positional values. X or Y control the position to the right or to the left, while the other controls how far or near the camera is; which is which depends on the point you're looking at the plane at, but using the profile camera command (more on that later) and looking at the value changes in-game will give you the answer. The Z value controls the vertical position of the camera.
    We'll discuss the ArriveTangent, LeaveTangent, and InterpMode in the Controlling Interpolation section, but these control how change between values happens.
  1. EulerTrack: This track controls the camera's rotation.

Figure 24
Figure 24

  • The InVal controls when the Item happens in the timeline.
  • The Outval contains the X, Y, and Z rotational values. The X value is the rotation along the Roll axis, the Y value is the rotation along the Pitch axis, and the Z value is the rotation along the Yaw axis.

Figure 25
Figure 25

  1. LookupTrack: This track adds the keys to the timeline.

Figure 26
Figure 26

  • Time is where you set at what time to add the key.
    Without the keys in this track, you won't see any keys. For every key in the PosTrack or EulerTrack there must be a corresponding one here. Make sure the number of them and times match with each other.

IMPORTANT NOTE: DO NOT, I repeat, DO NOT add a name in the GroupName property of an Item in the LookupTrack. This will impede the controls to take effect and you'll spend hours debugging why it isn't working. Totally not talking from experience...

Make sure that if you add a new array key in the InterpTrackMove, that is, to either the PosTrack, EulerTrack, or LookupTrack, you also add a new key to the other ones, or else the game will crash. Also, remember that if you make a change of the InVal (the time) of any of these tracks, or you reorder its elements, you should do the same in the other tracks as well. The FOV, DoF, and InterpTrackDirector tracks are independent and not subject to these observations.

If you want to have your camera move or rotate from one point to another, simply add an item where you want your movement/rotation to start, and one where you want it to end, and set the appropriate values.

A small caveat about rotation: If you're trying to set a small rotation from something like 355° to 5°, which should be a 10° turn, tweak it to be from -5° to 5°. A turn from 355° to 5° will actually translate to a 350° turn, which is probably not what you want.

Getting Precise Camera Position and Rotation

When editing the matinee camera's position and rotation, you could try setting it by trial and error, but there's a better way to get the position and rotation coordinates in-game that also allows you to see how your changes will look.

First of all, make sure you have tweaked your Coalesced file to allow for mouse control during conversation mode, as explained in the Setting Up the Coalesced for Camera Editing section.

With that set-up, launch Mass Effect 3 and get into the conversation you want to edit.
You'd probably want to pause the conversation with playersonly when the camera you want to edit is active.
With the game paused, type toggleflycam into the console, and then profile camera. Now the game is paused, you have control of the fly camera, and you are able to see the camera's position and rotation in the HUD:

Figure 27
Figure 27

Surrounded by colored boxes, you have the following information:

  • Rotation: The rotation of the camera in Y, Z, X form. The first value is the Y value, the second the Z, and the third the X. These values are in unreal degrees, where 1 degree equals 182.04 unreal degrees, so it's easy to convert them back and forth. You can also use the Hex Converter tool in the latest ME3Explorer build, which has a built-in converter between degrees and unreal degrees.
    If when trying to find the rotation of a camera, you convert the unreal degrees to normal degrees and find that the values go outside the 360/-360 range, take that value, divide it by 360, and use the remainder as the value. This is the same as doing yourVal modulo 360. This happens sometimes when the rotation displayed in-game does not account for whether or not you've rotated the camera more than once and leads to crazy spinning, which in this case is not a good trick.
  • Position: The position of the camera in X, Y, Z form.
  • FOV: The current FOV. You can change the camera's FOV by typing fov [0-n] into the console. Sadly, this does not display the proper value when in flycam mode, so you need to write down which value you changed the FOV to.
    To reset the FOV to be controlled by the game normally, type fov 0.

It may be the case that you'll get positional values from the flycam that are much higher than what's displayed by the InterpTrackMove, like in this case:

Figure 28
Figure 28

This happens because the Interp (a sequence object to which the InterpData is connected) has something as its anchor. So, the camera profiler displays the absolute values, that is, the anchor's position plus the local value set in the InterpTrackMove, while the Interpreter only displays the local values.
To figure out what the anchor is, from the Dialogue Editor click on the dialogue node and then on the marked icon:

Figure 29
Figure 29

This will open the Sequence Editor and display the appropriate Interp. (You could skip the previous step by opening the file in the Sequence Editor, but you then have to figure out which Interp is the relevant one).

Figure 30
Figure 30

Now follow the line coming into the Anchor link to its source object, which in this case is the ST_End001_Shuttle_Down_M BioStage, then search for the object, get its position, and add/subtract it to the values displayed by the profiler.

Field of View

The Field of View controls how much area the camera is able to capture.
Clicking on the FOVAngle track reveals the following:

Figure 31
Figure 31

  1. PropertyName: This tells the game that this track controls the FOV. The name must be FOVAngle without typos, or it won't have any effect.
  2. TrackTitle: The name displayed for the track, keep it to FOVAngle to keep things consistent.
  3. FloatTrack: The property containing the array holding the items that control the FOV. Expanding this property you'll see the following:

Figure 32
Figure 32

  1. InVal: The time at which the item takes place.
  2. OutVal: The FOV value.
  3. InterpMode: The interpolation mode for the item. We'll discuss them in the Controlling Interpolation section.

Do note that the items in the FOVAngle track don't necessarily need to be the same amount or match those in the InterpTrackMove. You can have the same FOV during multiple cameras, or have multiple FOVs keys during the same camera.

A low FOV value will result in less area being captured by the camera, while a high one will make the camera capture a bigger area.

Figure 33
Figure 33

Without any change in the camera position, this gives the impression that it has made the camera be farther away from the subject, but if you check the position values or move the camera closer to the subject, you'll see that what has changed is, in fact, the area captured by the camera.

Figure 34
Figure 34

As you can see, an effect of a higher FOV value is that the elements closer to the camera seem to become thinner and stretched back, while a smaller FOV value makes the elements appear wider. This is an effect that you can use to your advantage depending on what you want to do, but usually, for face close-ups, a value between 23 to 33 FOV works the best.

To compare the FOV to real-life lenses, a high FOV value is similar to using a short lens, while a low FOV value is similar to using a long lens, minus the depth of field effects.

Other Topics

Here are some topics that are not necessarily complicated, but definitely beyond the basics that were covered before.

Controlling Interpolation

When you have multiple keys in the InterpTrackDirector or BioEvtSysTrackDOF the game changes to them automatically, without transition, unless you manually set a transition time. However, for the FOVAngle and InterpTrackMove tracks, the game changes between them in a progressive linear fashion, but how this happens is something that can be controlled, for each item in them, via the InterpMode property. Pay attention to the fact that items in the InterpTrackMove also have the ArriveTangent and LeaveTangent properties.

Figure 35
Figure 35

Items of the PosTrack and EulerTrack of the InterpTrackMove track by default have their InterpMode set to either CIM_CurveAutoClamped or CIM_Linear, meaning they'll progressively change from one item to another in a linear fashion, while items of the FloatTrack of the FOVAngle track are set to CIM_Constant, meaning changes will occur only once the key is reached, and then remain until the next one.

The real power of these interpolation modes lies in the Curve Editor, where you can visualize and easily manually control the changes.
To access the Curve Editor click on it under the Interpreter tab, and you'll see the following:

Figure 36
Figure 36

The x-axis of this graph corresponds to the time, while the y-axis corresponds to the value of the keys. Numbered in Figure 36 we have:

  1. The Tracks' arrays: Clicking on any of them will display in the graph the keys contained in that array.
  2. The Interpolation modes: From here you can change between interpolation modes.
  3. The Keys: These are the individual keys set by the track, with the added bonus of having handles that control the arrive and leave tangents of the key. Moving a key up/down in the viewer will increase/decrease its value while moving it right/left will change its placement on the timeline.
  4. The Key's Value: Here you can see and edit the actual value of the key.

The available interpolation modes are:

Figure 37 Figure 37

  • Constant: Keep the value constant until it reaches the next key, when it instantly changes the value to the next one.
  • Linear: Makes the change between values be linear without any ease-in or ease-out.
  • Auto: Makes the key's arrive and leave tangents smoother. Usually, Auto/Clamped works better.
  • Auto/Clamped: Makes the key's arrive and leave tangents smoother.
  • User: Allows for a custom-made curve. The mode will automatically switch to this whenever you manually tweak the handles of the key.
  • Break: Allows you to control the arrive and leave tangents independently with the handles. Other modes have them linked.

Changes to a key's handles are reflected in the ArriveTangent and LeaveTangent properties of the Item (for PosTrack and EulerTracK ones) in the Interpreter, which gives you finer control over them. However, it's usually easier to modify them from the Curve Editor.

So, to change the interpolation mode of an item just select the appropriate one from the InterpMode property in the Interpreter, or click on the key and then on the mode in the Curve Editor. The selected interpolation mode will affect the part of the curve after the key.

Identifying Available Matinee Cameras

Before being able to add a new matinee camera you need to know which camera actors are available to assume direct control of. The idea is to go through the pcc files that are loaded at the time of the conversation and look for the tags of CameraActors that are in them.

The easiest way to know which cameras are available is to go check the InterpDatas in the same dialogue and see if any uses a matinee camera, then write down the name of the camera actor. Take into account that the group name and the camera actor names may sometimes not be the same.

Figure 38
Figure 38

If there are no matinee cameras in the conversation, or you need to use an extra one, to know which files are loaded you can use the Streaming Levels HUD ASI mod, which you can install via the ASI Manager tool.

Figure 39
Figure 39
You can toggle this HUD by pressing Ctrl + T.

Camera actors are usually located in the more general files. If your conversation is in BioD_CitHub_WardsFluxP3_LOC_INT.pcc, chances are that the cameras will be in either BioD_CitHub.pcc or BioD_CitHubWardsFlux.

Figure 40
Figure 40

Now, an even easier way once you get the hang of it (although not as easy as the first method) is using the LiveLevelEditor (LLE) tool. I won't go into much detail since this is not a guide about it, but the following should get you to what you need:

Figure 41
Figure 41

  1. Open the LLE before starting the game. You may be asked to install extra files if it's the first time you use it.
  2. Open the game and load the conversation.
  3. Go back to the LLE and click on "Initialize Editor". It will take a couple of seconds for any change to happen, but if it doesn't work repeat steps 1 to 3.
  4. Click on "Regenerate Actors List", this will make the tool display the list of loaded files. This may take a couple of seconds to work, but if it doesn't work click "Cancel" and repeat this step.
  5. Click on a file on the left, then on the right, a list of actors contained in that file and active in-game will be displayed on the right.
  6. Look through the files for any CameraActor_n.
  7. Right-click on a camera actor, and then click on "Open in Package Editor".
  8. Now you just need to write down the name tag! Remember to check the index value too.

And there you have it, now you know how to figure out which camera actors are available to use as a matinee camera, all you have left is to test it in-game.
Remember that if you load into a different level while the LLE is open, you'll need to repeat steps 3 through 8.

Adding a New Matinee Camera

Technically, "adding" is the wrong word to use here, since what we'll do is just add the InterpGroup and InterpTrack to control a camera actor, but let's roll with "adding".
So, to add the controls for a matinee camera, follow these steps:

  1. Open the InterpData you want to add the controls to in the InterpViewer.
  2. On the top left, click on "Add InterpGroup".
  3. A prompt will be launched asking you for a name for the InterpGroup. Input the name of the camera actor and click "Ok". If the name has an index, write it without the index and then tweak the GroupName property for the index.

Figure 42
Figure 42

  1. With the new InterpGroup selected, click on "Add Property" from the Interpreter toolbar.
  2. In the new window select the m_nmSFXFindActor property and then click "Add Property".

Figure 43
Figure 43

  1. Change the added property to be the camera actor you want to target.

Figure 44
Figure 44

  1. Right-click on the newly created camera InterpGroup, select "Add New InterpTrack".
  2. Search for "InterpTrackMove" in the window that will pop up, and then click "Add". Don't confuse it with "BioInterpTrackMove".

Figure 45
Figure 45

  1. Repeat steps 7 through 8, but this time select "InterpTrackFloatProp".

Figure 46
Figure 46

  1. Select the newly added InterpTrackFloatProp track, and add the "PropertyName" property from the "InterpTrackFloatProp" class.

Figure 47
Figure 47

  1. Set that property to "FOVAngle". Make sure it is exactly that or else the game won't recognize it.
  2. Now add the "TrackTitle" property from the "InterpTrack" class and set it to "FOVAngle".

Figure 48
Figure 48

And that's it! If you've done everything correctly the result will look like this:

Figure 49
Figure 49

The InterpTrackFloatProp track will change its name to "FOVAngle" after you save the file.

Adding the InterpGroupDirector

If your InterpData does not have an InterpGroupDirector (I don't know what happens if you have more than one xD), follow these steps to add one:

  1. Open the InterpData you want to add the director to in the InterpViewer.
  2. On the top left, click on the "Add InterpGroupDirector".

Figure 50
Figure 50

  1. Right-click on the newly created InterpGroupDirector interpgroup, then click on "Add New InterpTrack".
  2. From the pop-up window select the "InterpTrackDirector" track, then click "Add".

Figure 51
Figure 51

  1. Repeat steps 3 and 4, but this time add the "BioEvtSysTrackDOF" track.

Figure 52
Figure 52

And there you go, it's that easy! The end result should look like this:

Figure 53
Figure 53

Adding the Conversation InterpGroup

If your InterpData does not have a Conversation InterpGroup, follow these steps. If you just want to add the track that controls the switch cameras, jump to step 4.

  1. Open the InterpData you want to add the director to in the InterpViewer.
  2. On the top left, click on "Add InterpGroup".
  3. A prompt will be launched asking you for a name for the InterpGroup. Input "Conversation" as the name.
  4. Right-click the newly created Conversation InterpGroup, select "Add New InterpTrack".
  5. Search for "BioEvtSysTrackSwitchCamera" in the window that will pop up, and then click "Add".

Figure 54
Figure 54

And we're done! The result will look like this:

Figure 55
Figure 55

Controlling Dialogue Wheel Cameras

You've set your beautiful matinee camera shots, used the right switch cameras, and created a nice flow and pacing of the shots. However, as soon as your conversation hits a dialogue wheel everything goes down the drain with an ugly camera angle. How can you fix this? This is the question we'll be answering in this section.

The basic gist of how dialogue wheels work is that you have Dialogue Node A (DNA), which plays InterpData A. This DNA then has 3 branches that branch into other dialogue nodes. The game will set a dialogue wheel right after the end of InterpData A and will be in this state until you select a dialogue choice, in which case it will proceed to play the InterpData associated with your dialogue choice.
So, while it's waiting for you to choose, the game will automatically select an available switch camera that it thinks will work the best.
Here's a visual explanation viewed in the Dialogue Editor:

Figure 56
Figure 56

Now, to control the camera that plays during the dialogue wheel limbo there are two options:

  • Use switch cameras, which is the simplest method, but again, you're limited by the preset cameras.
  • Use a matinee camera, which is a bit more involved, but gives you the most control.

Dialogue Wheel with Switch Camera

This method is very simple: Go to InterpData A, add a switch camera right at the end of it, and then set its bUseForNextCamera property to true.

Figure 57
Figure 57

This tells the game to use that camera for whatever it does next, which in our case is the dialogue wheel. Setting the bUseForNextCamera to true also makes it so the game ignores the key for the InterpData it's inside of. If you placed it a bit before the ending of it or earlier, the game would not switch to that camera, but setting it at the end makes it easier to know what it's for just by looking at the timeline.

If you want to use a custom angle though, or for some reason this method is not taking effect (which happens sometimes for some reason, and the solution is to create a whole new InterpData), you can use a matinee camera for the dialogue wheel.

Dialogue Wheel with Matinee Camera

Since this method is a bit more involved, let's put hands to work and the explanation of what exactly it is doing will come a bit later.

  1. From the Dialogue Editor open in the Sequence Editor the dialogue node that triggers the wheel or just open the file directly in the Sequence Editor and look for the appropriate Interp.
  2. From the Sequence Object Toolbox add 2 SeqAct_Interp and 2 InterpData objects (double click on them in the toolbox).

Figure 58
Figure 58

  1. Connect the created InterpData objects into the Data Variable Links of the SeqAct_Interps.
  2. Click on one of the SeqAct_Interps, then on _Interpreter_ add a new array element to the VariableLinks` array.
  3. Go to the newly added array element, and set its LinkDesc to the name of the matinee camera you're gonna use.

Figure 59
Figure 59

  1. In the same SeqAct_Interp, add the bClientSideOnly, bLooping, and bRewindOnPlay properties from the SeqAct_Interp class.

Figure 60
Figure 60

  1. Set the newly added properties to true.

Figure 61
Figure 61

  • OPTIONAL: Remove the OutputLinks property to get a neater look since we won't need it.
  1. Repeat steps 4 to 7 for the other SeqAct_Interp.
  2. Add the InterpLength property from the InterpData class to both InterpDatas, and then set said properties to how long you want them to last. They will loop and restart after the end.

Figure 61.5
Figure 61.5

  1. Add to both SeqAct_Interps a m_aObjComment property from the SequenceObject class. And add a new array element to the property of both after you add it.
  2. Set the comment of one of the SeqAct_Interps to something like "WheelDirector", and set the other one to "WheelCam" or something more distinctive if you plan to use different cameras for different wheels. This is merely for visual purposes.

Figure 62
Figure 62

  1. Right-click the InterpData linked to the "WheelDirector" and select "Open in InterpViewer".
  2. Inside the InterpData add an InterpGroupDirector with its respective tracks.
  3. Add a new Camera InterpGroup, using the same camera name as in step 5. DO NOT add any track to this. This group will be empty.
  4. Add a key in the InterpTrackDirector to target the _Camera InterpGroup` you created. You can also add and set the DOF.

Figure 63
Figure 63

  1. Close the InterpViewer. Right-click on the InterData linked to the "WheelCam" and open it with the InterpViewer.
  2. Add a new Camera InterpGroup, using the same camera name as in steps 5 and 14. This time do add all its required InterpTracks and properties.

Figure 64

  1. Set any of the position and rotation values you want, but make sure that if you add movement, said movement ends in the same position it began, or else the camera is gonna jump since this movement will be looping.

Alright, we're almost done and so far so good. Why we've placed the InterpGroupDirector and the camera InterpGroup in separate places will come at the end.
Before we proceed to the next steps, allow me to explain what the sequence for a conversation Interp is:

Figure 65
Figure 65

When a dialogue node in the conversation (as seen in the Dialogue Editor) is reached, it triggers the BioSeqEvt_ConvNode that references it in the sequence, this is marked by "Start" in Figure 65. This in turn triggers the Play input of an Interp, which starts playing whatever is in its related InterpData. Then, when the InterpData ends, the BioSeqAct_EndCurrentConvNode is triggered, marked by "End" in Figure 65, which ends the dialogue node so the game can proceed to the next thing, in our case the dialogue wheel.

What we are going to do to control tell the game to use our matinee camera for the wheel is to start playing the Interps we set before right after the InterpData that triggers the wheel ends, and then stop them whenever a branch starts.

  1. Select the EndCurrentConvNode of the Interp that triggers the branches (not the one from the branches themselves), and add the OutputLinks property from the SequenceOp class.

Figure 66
Figure 66

  1. Add a new array element to the OutputLinks property, and connect it to the "Play" input of both the "WheelDirector" and "WheelCam1".

Figure 67
Figure 67

  1. Now you need to look for the Interps that correspond to each of the branches that occur from the dialogue wheel, and then connect the output of their ConvNode to the "Stop" input of both the "WheelDirector" and "WheelCam1". While on the following image I placed them close to each other for visual purposes, most of the time they will be far from each other, so you'll have to play a bit with the zoom.

Figure 68
Figure 68

And that's it! Now your dialogue wheel will use your matinee camera. This does look like quite a lot of steps, but once you get the hang of it it's not too difficult.

Going back to answering why the InterpGroupDirector and the actual camera InterpGroup are in separate InterpDatas, it is so that if later you want to have a different camera angle for another wheel, you can create a new InterpData as in steps 4-8 and 17, while reusing the same director InterpData.
The director is always targeting the same camera group, in our example Cam1, but the actual values of that camera are in a "remote" InterpData. So which values get used just depends on which camera InterpData you trigger in step 20, as long as it has the camera group.
Basically, you get a universal director, and multiple separate "remote" cameras you can trigger at will.
And remember, you need to start them by the end of the branching Interp, and you need to stop them by each start of the different branches.

Dealing with Camera Clipping

You are casually going through your conversation and then you get scared the heck out of by this:

Figure 69
Figure 69

This happens because of the NearPlane property of switch cameras. As explained in the section related to them, they have a radius that erode/clip what's inside in order to clear any obstacles, which is the NearPlane value. Usually, it is either low or 0, which means little to no clipping, but sometimes it is higher, which leads to the problem in question.
This problem can happen with a matinee camera during the dialogue wheel, or during a switch camera at any point.

Clipping During Matinee Cameras

If clipping happens during a matinee camera at the dialogue wheel, the solution is to go to the InterpData that triggers the dialogue wheel and add a switch camera that has a low NearPlane to it, with the bUseForNextCamera property set to true. You can go to the Choosing a Switch Camera section to learn how to know the NearPlane values of the cameras.
You don't need to switch to the Conversation group in the InterpGroupDirector, this will not change your camera but will take care of the clipping.

Clipping During Switch Cameras

If the clipping happens during a normal InterpData or the dialogue wheel, and the camera you have set is a switch camera, the solution is to:

  1. Add a SFXInterpTrackSetPlayerNearClipPlane track into the Conversation InterpGroup.
  2. Add an array element to the m_aNearClipKeyData. Its m_fValue default value will be 0, which is what we want to override the switch camera's NearPlane property. Don't forget to also add an array element to the m_aTrackKeys array.

Figure 70
Figure 70

Adding a BioStage

If you've found out that your conversation lacks a BioStage, follow these steps to add one:

  1. First you gotta figure out which stage to use, so open the Asset Database. You may need to generate the database if this is your first time using the tool.
  2. Go to the "Meshes" tab, and look into the meshes that begin with "ST_", these are the BioStages. Make sure to toggle on Wireframe and Toggle Mesh Rendering.
  3. Once you've found a BioStage you think will work, right-click any of the files listed on the "Usages" column on the right, and select "Open Usage". This will open a pcc file that contains the BioStage.

Figure 71
Figure 71

  1. In the opened filed, look for the BioStage object inside TheWorld.PersistentLevel.
  2. Open the pcc file that contains the StartConversation object that triggers the dialogue, and expand its PersistentLevel.

Figure 72
Figure 72

  1. Drag and drop the BioStage object from one file into the PersistenLevel of the file you want to add it to.
  2. In the "Package porting options" window that will pop up, click "Clone All References (Experimental)".

Figure 73
Figure 73

If everything went well, your file should look something like this (remember the export number of the BioStage object:

Figure 74
Figure 74

  1. Open the file's sequence in the Sequence Editor, and look for the StartConversation object that triggers the dialogue.
  2. From the "Sequence Object Toolbox" add a SeqVar_Object.
  3. Add an ObjValue property to it from the SeqVar_Object class.
  4. Set the value of this property to the export number of the added BioStage object.
  5. Connect the SeqVar_Object to the Stagevarlink of the StartConversation object.
  6. Make sure that the Player and your other actors are connected to nodes. If you need more nodes or want to change the name of one so it matches the proper node in the BioStage (you'll probably figure this after trial and error), go to the VarLinks property of the StartConversation object.

Figure 75
Figure 75

At this point, we've added the BioStage to the file and added it to the sequence so it gets used by the conversation. We still need to place it in the correct location, and make sure it doesn't clash with any Blocking Volumes.

  1. Open the game, go where the conversation takes place, then type showlocation into the console. This will display the player coordinates, which is where we'll place the BioStage, so write down the coordinates. If you can't physically go to where you'll place the BioStage, use the flycam with profile camera and use the camera position values.

Figure 76
Figure 76

  1. Go back to the newly added BioStage object in the Package Editor, and change the values inside its Location property to match the coordinates you got. If it doesn't have a Rotation you may want to add it to change its orientation if needs be. Note that this time the rotation values are inputted in normal degrees.

Figure 77
Figure 77

  1. Load the conversation and make any necessary adjustments to the BioStage's location and rotation. You may also try placing the actors in different nodes, as mentioned in step 13.

Many times this will be the end of the story. Things should be in place and working. However, it may be the case that you find your actors stepping over other meshes or weird clashes with objects and stuff. The solution for this is to disable their collisions or blocking volumes, which is in the next section.

Disabling Blocking Volumes

The steps to identify the involved meshes/volumes and disable them is as follows:

  1. Go right beside the mesh/are that's causing trouble, then type profile pawn self into the console. This will display information related to the player pawn, but most importantly, what you are standing on. If it says anything besides "BlockingVolume..." you can ignore it, but if it is a blocking volume write down its name.

Figure 78
Figure 78

  1. Finding which file contains the blocking volume takes a little bit of patience. However, they are usually located under TheWorld.PersistentLevel in BioA files that refer to the place where the conversation takes place, and are kinda similar to the dialogue file name. For example, our conversation happens in BioD_End001_481HubQuarians.pcc in the command room, and BlockingVolume_0 happens to be inside BioA_End001_460Command.pcc.
  2. With your target found, add a UniqueTag property from the Actor class and give it a unique name to ALL the blocking volumes present in the file, EXCEPT the one you found in step 1. You'll be asked if you want to add the new name, click "Yes".

Figure 80
Figure 80

  1. Go to the sequence that triggers the StartConversation of your dialogue.
  2. Add 2 SeqAct_Toggle objects (from the "Actions" tab), and a BioSeqVar_ObjectFindByTag object (from the "Variables" tab). as blocking volumes to which you added unique tags.
  3. Connect the ObjectFindByTag object (same number as unique tags) to one the Toggles.
  4. Add the m_bSearchUniqueTag and m_sObjectTagToFind properties from the BioSeqVar_ObjectFindByTag class to the ObjectFindByTag object. Set the m_bSearchUniqueTag property to true.
  5. Clone the ObjectFindByTag objects to have one per blocking volume to disable.
  6. Set the m_sObjectTagToFind properties to the unique tags you've added to the blocking volumes. You'll be asked if you want to add the new names, click "Yes".
  7. Clone all of the ObjectFindByTag objects once more to have two sets.
  8. Connect one set to one of the Toggles and the other set to the other one.

Figure 81
Figure 81

Right now what we've done is prepare 2 toggles that are going to disable and then reenable all the blocking volumes we need.

  1. Connect the Out link of the StartConversation object to the Turn on input of one of the toggles.

Figure 82
Figure 82

In the next steps, we're gonna reroute whatever objects trigger the conversation.

  1. Break the Output links of all the nodes that hit the Play input of the StartConversation object.

Figure 83
Figure 83

  1. Link the Ouput links of the nodes you just modified to the Turn off input of the free toggle.

Figure 84
Figure 84

  1. Finally, link the Out link of the toggle to the Play input link of the StartConversation object.

Figure 85
Figure 85

And there you go! You can test if you had success with toggledebugcamera command during the conversation and then trying to go through the areas. If it goes right through them it means you had success.
The reason we are disabling almost all the blocking volumes is because aside from trial and error, we have no reliable way to know which blocking volumes are the ones that do the trick, so we just do them all. This process may require a bit of trial and error. Sometimes the problematic volumes may be in a different file than what you thought, so you may need to repeat some of the steps, but with patience, blood, and tears, it is doable and worth it.

Small note: Using the debug camera makes it so that you'll need to close and open the game again before being able to load a file, otherwise, the game will crash.

Creating Linear Camera Motion Across Multiple InterpDatas

During your camera modding journey you may come across a situation where you'll want a linear camera movement to span multiple InterpDatas. There are two solutions to have it be precise and smooth.

Linear Camera Motion with Dedicated Tool

One method is to use the Mass Effect Camera Motion Calculator tool. It is a small external tool I built that asks you for information regarding what you want to do, and then calculates and tells you where and what values to set.
You can download it from the GitHub repo: https://github.com/Exkywor/MECamMotionCalc/releases.

After downloading it, double-click MECamCalc.exe and a terminal window will launch. There you'll be prompted to input the required information to calculate the values.
This is what a normal example usage will look like:

How many InterpDatas does the camera movement span? 4
InterpData 1 length in seconds: 5 
At what time in InterpData 1 does the movement begin? 3.75
InterpData 2 length in seconds: 4.16 
InterpData 3 length in seconds: 2.1 
InterpData 4 length in seconds: 7.212 
At what time in InterpData 4 does the movement end? 4.4
Starting position as comma separated values (x,y,z): -2391.71, -51000.11, 1431.7
Starting rotation as comma separated values (x,y,z): 0, 19.1693, -117.4392
Ending position as comma separated values (x,y,z): -2408.41, -51032.3, 1444.4
Ending rotation as comma separated values (x,y,z): 0, 25.35, -113.74
For how many time points do you want to calculate values? 3
In which InterpData (1 to n) does time point 1 happen? 1
At what time of it does time point 1 happen? 5
In which InterpData (1 to n) does time point 2 happen? 3
At what time of it does time point 2 happen? 0.75
In which InterpData (1 to n) does time point 3 happen? 4
At what time of it does time point 3 happen? 0

After this, the results will be:

STARTING POINT
InterpData 1, at time 3.75
----------------------------
Position: -2391.71 -51000.11 1431.70
Rotation: 0.00 19.17 -117.44

TIME POINT 1:
InterpData 1, at time 5.00
----------------------------
Position: -2393.46 -51003.49 1433.03
Rotation: 0.00 19.82 -117.05

TIME POINT 2:
InterpData 3, at time 0.75
----------------------------
Position: -2400.35 -51016.76 1438.27
Rotation: 0.00 22.37 -115.53

TIME POINT 3:
InterpData 4, at time 0.00
----------------------------
Position: -2402.24 -51020.41 1439.71
Rotation: 0.00 23.07 -115.11

ENDING POINT
InterpData 4, at time 4.40
----------------------------
Position: -2408.41 -51032.30 1444.40
Rotation: 0.00 25.35 -113.74

Press Enter to exit the program

Then it is just a matter of adding the resulting values in the indicated places.

Important note: As of version 1.0.2, I haven't built input validation into it. However, there should be no issues as long as you input numerical values when prompted.

Linear Camera Motion with Remote Camera

The other method is doing something similar to the technique used in the Dialogue Wheel with Matinee Camera section, so this section will assume you're familiar with it.

First, create empty camera groups in all the InterpDatas the motion will span, and then target them with their InterpTrackDirectors.

Figure 86
Figure 86

Then, open the sequence containing the InterpData, and add a new SeqAct_Interp and InterpData objects. Add the appropriate properties, minus bLooping. The InterpLength should that of the sum of the lengths of all the InterpDatas you want the movement to span.

Figure 87
Figure 87

Now open the newly created InterpData, add a new camera group with the same name as the one you're targeting inside your normal InterpDatas, and then add the appropriate tracks and the motion you want it to do.

Figure 88
Figure 88

The last thing to do is to connect the ConvNode of the first Interp of the motion to the Play input of the custom Interp, and the Completed and Reversed outputs of the last Interp of the motion to the Stop input of the custom Interp. This sets the remote camera to start playing at the first Interp, continue playing, and only stop once you reach the end of the last Interp that you want the motion to span.

Figure 89
Figure 89

This method is more flexible and elegant but a bit more complicated to set up, while the previous method is simpler but less flexible and elegant.

Miscellaneous

Here are some topics that are useful for the camera modding process, but are definitely tangential to the main ones.

Setting up the Coalesced for Camera Editing

By default, the game lacks certain QoL features for camera modding, like moving the up or down or move the view with the mouse with the flycamera. We'll add the needed functionality via editing the BioInput of the Coalesced file, and then I'll suggest some very useful keybindings to add.

If you've never edited the Coalesced files, you can do so with the Coalesced Editor tool from ME3Explorer. The basic process is as follows:

  1. Launch the tool.
  2. Next to Source, click "Browse", and navigate to and select your game's Coalesced.bin. It should be under [GAME INSTALL FOLDER]\BIOGame\CookedPCConsole\Coalesced.bin
  3. Click on "Convert".
  4. Go to the folder where the Coalesced was converted, if you didn't change anything it should be [GAME INSTALL FOLDER]\BIOGame\CookedPCConsole\Coalesced, and open the BioInput.xml file.
  5. HERE'S WHERE YOU ADD THE THINGS WE'LL SEE IN A BIT.
  6. Save the file.
  7. Go back to the Coalesced Editor, click "Browse" next to Source again and navigate to and select Coalesced.xml. It's inside the same folder as the BioInput.xml.
  8. For Destination, choose the path where the original Coalesced.bin was. [GAME INSTALL FOLDER]\BIOGame\CookedPCConsole\.
  9. Click "Convert".

You can leave the coalesced folder that was created at the beginning, or you can delete it if you want. DO NOT delete the Coalesced.bin file that you just created.

The basic QoL lines we're gonna add in step 5 are these:

  • In <Section name="sfxgame.sfxgamemodeconversation"> paste the following:
<Value type="2">( Name="A", Command="PC_StrafeLeft" )</Value>
<Value type="2">( Name="D", Command="PC_StrafeRight" )</Value>
<Value type="2">( Name="W", Command="PC_MoveForward" )</Value>
<Value type="2">( Name="S", Command="PC_MoveBackward" )</Value>
<Value type="2">( Name="MouseX", Command="PC_LookX" )</Value>
<Value type="2">( Name="MouseY", Command="PC_LookY" )</Value>
<Value type="2">( Name="E", Command="MoveDown" )</Value>
<Value type="2">( Name="Q", Command="MoveUp" )</Value>
  • In <Section name="sfxgame.sfxgamemodebase"> paste the following:
<Value type="2">( Name="MoveUp",Command="Axis aUp Speed=0.75" )</Value>
<Value type="2">( Name="MoveDown",Command="Axis aUp Speed=-0.75" )</Value>
  • In <Section name="sfxgame.sfxgamemodeflycam"> paste the following:
<Value type="2">( Name="Q", Command="MoveDown" )</Value>
<Value type="2">( Name="E", Command="MoveUp" )</Value>

In the end, it should look like this:

Figure 90
Figure 90

What we've set up allows you to move the camera freely with the flycam during a conversation, and move it up and down with the E and Q keys.

I also like to add the following key bindings for my most used commands in <Section name="sfxgame.sfxgamemodebase">:

<Value type="2">( Name="p", Command="playersonly", Control=True )</Value>
<Value type="2">( Name="o", Command="toggleflycam", Control=True )</Value>
<Value type="2">( Name="o", Command="toggledebugcamera", Alt=True )</Value>
<Value type="2">( Name="i", Command="profile conversation", Control=True )</Value>
<Value type="2">( Name="i", Command="profile camera", Alt=True )</Value>
<Value type="2">( Name="i", Command="profile none", Shift=True )</Value>
<Value type="2">( Name="l", Command="showlocation", Control=True )</Value>
<Value type="2">( Name="NumPadZero", Command="fov 0" )</Value>
<Value type="2">( Name="NumPadOne", Command="fov 23" )</Value>
<Value type="2">( Name="NumPadTwo", Command="fov 33" )</Value>
<Value type="2">( Name="NumPadThree", Command="fov 40" )</Value>
<Value type="2">( Name="NumPadFour", Command="fov 60" )</Value>
<Value type="2">( Name="NumPadFive", Command="fov 15" )</Value>
<Value type="2">( Name="NumPadSix", Command="fov 35" )</Value>
<Value type="2">( Name="NumPadSeven", Command="fov 45" )</Value>
<Value type="2">( Name="NumPadEight", Command="fov 80" )</Value>
<Value type="2">( Name="NumPadNine", Command="fov 100" )</Value>
<Value type="2">( Name="One",Command="slomo 0.1", Control=True )</Value>
<Value type="2">( Name="Two",Command="slomo 0.2", Control=True )</Value>
<Value type="2">( Name="Three",Command="slomo 0.3", Control=True )</Value>
<Value type="2">( Name="Four",Command="slomo 0.4", Control=True )</Value>
<Value type="2">( Name="Five",Command="slomo 0.5", Control=True )</Value>
<Value type="2">( Name="Six",Command="slomo 0.6", Control=True )</Value>
<Value type="2">( Name="Seven",Command="slomo 0.7", Control=True )</Value>
<Value type="2">( Name="Eight",Command="slomo 0.8", Control=True )</Value>
<Value type="2">( Name="Nine",Command="slomo 0.9", Control=True )</Value>
<Value type="2">( Name="Zero",Command="slomo 0", Control=True )</Value>
<Value type="2">( Name="One",Command="slomo 1", Alt=True )</Value>
<Value type="2">( Name="Two",Command="slomo 2", Alt=True )</Value>
<Value type="2">( Name="Three",Command="slomo 3", Alt=True )</Value>
<Value type="2">( Name="Four",Command="slomo 4", Alt=True )</Value>
<Value type="2">( Name="Five",Command="slomo 5", Alt=True )</Value>
<Value type="2">( Name="Six",Command="slomo 6", Alt=True )</Value>
<Value type="2">( Name="Seven",Command="slomo 7", Alt=True )</Value>
<Value type="2">( Name="Eight",Command="slomo 8", Alt=True )</Value>
<Value type="2">( Name="Nine",Command="slomo 9", Alt=True )</Value>
<Value type="2">( Name="Zero",Command="slomo 10", Alt=True )</Value>

Editing While the Game is Running

Camera modding is a process that requires a lot of trial and error. If you had to close and reopen the game every time you did an edit, that would be horrible, but thanks to the amazing developers of these tools, that's not the case!
All you need to do is install the AutoTOC ASI v2 ASI mod through the *ASI Manager. Then, as long as you are directly editing PCC files inside the game installation folder, you can save the files and you'll see the changes after you load a save.

Figure 91
Figure 91

Related Guides

These are some guides that you'll probably be interested in for conversation and camera modding:

Final Words

Before ending this guide, I wanted to give special thanks to Lunk/Lunkensko/Linkenski for teaching me pretty much all I know about camera modding. All this knowledge I've shared is just what I've been able to learn from him through what have probably been too many questions. I'm extremely thankful for his help and patience in getting me this far.

Camera editing is a process that can be frustrating and requires a lot of patience at times, but the results are worth it. My only hope is that this guide helps you accomplish whatever vision you've set for your mod.
Happy modding!

Clone this wiki locally