Adding gimbal arms, hydraulic pistons, and actuators are a great way to add a lot of character to your engine. It’ll take a bit of fiddling, but the results are satisfying.

Basic gimbal arm setup

Each gimbal arm consists of an upper and lower section. The movements of each are defined using an FXModuleLookAtConstraint.

Courtesy of JadeOfMaar

Courtesy of JadeOfMaar

Courtesy of JadeOfMaar

Courtesy of JadeOfMaar

As a more comprehensive breakdown, for a given arm assembly:

Arm orientation

Each gimbal arm should be modelled such that the arm extends out in the Y+ direction. This is a little counter-intuitive as Blender defaults to orienting new meshes along the Z-axis, but a quick rotation should help.

To check for the right orientation, apply rotation to the object first (Ctrl+A ➡️ Rotation), and in the object properties tab of the properties pane, enable axes under viewport display. The arm’s pivot should be centred on the origin, and the arm should extend outwards towards the big “Y” like in the below image:

Untitled

Looking at an engine with its gimbal arms sticking out like that is a little jarring. You can use a track to object constraint on each arm: target each arm at the other, with track axis set to Y and up set to X. No, I don’t really know why, but it works.

Untitled

Nertea’s ModuleAdvancedLookAtConstraint

Provided in the Deployable Engines mod framework is a custom and alternative implementation of the stock look constraint module. ModuleAdvancedLookAtConstraint functions identically to the stock module, but prevents gimbal arms from rolling sideways and in unnatural ways.

Here’s an example module for an engine with two sets of gimbal arms. It’s exactly the same as the stock implementation, just with FXModuleLookAtConstraint swapped out for ModuleAdvancedLookAtConstraint on the second line.

MODULE {
	name = ModuleAdvancedLookAtConstraint

	CONSTRAINLOOKFX
	{
		targetName = GimbalArm_Upper1
		rotatorsName = GimbalArm_Lower1
	}
	CONSTRAINLOOKFX
	{
		targetName = GimbalArm_Lower1
		rotatorsName = GimbalArm_Upper1
	}

	CONSTRAINLOOKFX
	{
		targetName = GimbalArm_Upper2
		rotatorsName = GimbalArm_Lower2
	}
	CONSTRAINLOOKFX
	{
		targetName = GimbalArm_Lower2
		rotatorsName = GimbalArm_Upper2
	}

}