public void Start()
        {
            if (HighLogic.LoadedSceneIsEditor)
            {
                return;
            }

            if (string.IsNullOrEmpty(cameraTransform))
            {
                // Nothing to do if there're no camera transforms.
                return;
            }

            string[] cameraTransformList = cameraTransform.Split('|');

            // I'm sure this and the loop can be done a little differently to
            // make it clearer, but this works.
            string[] fovLimitsList   = (string.IsNullOrEmpty(fovLimits)) ? null : fovLimits.Split('|');
            string[] yawLimitsList   = (string.IsNullOrEmpty(yawLimits)) ? null : yawLimits.Split('|');
            string[] pitchLimitsList = (string.IsNullOrEmpty(pitchLimits)) ? null : pitchLimits.Split('|');
            string[] zoomRateList    = (string.IsNullOrEmpty(zoomRate)) ? null : zoomRate.Split('|');
            string[] yawRateList     = (string.IsNullOrEmpty(yawRate)) ? null : yawRate.Split('|');
            string[] pitchRateList   = (string.IsNullOrEmpty(pitchRate)) ? null : pitchRate.Split('|');

            // cameraTransformList controls the number of cameras instantiated.
            // Every other value has a default, so if it's not specified, we
            // will use that default.
            for (int i = 0; i < cameraTransformList.Length; ++i)
            {
                Vector2 thisFovLimit   = (fovLimitsList != null && i < fovLimitsList.Length) ? (Vector2)ConfigNode.ParseVector2(fovLimitsList[i]) : defaultFovLimits;
                Vector2 thisYawLimit   = (yawLimitsList != null && i < yawLimitsList.Length) ? (Vector2)ConfigNode.ParseVector2(yawLimitsList[i]) : defaultYawLimits;
                Vector2 thisPitchLimit = (pitchLimitsList != null && i < pitchLimitsList.Length) ? (Vector2)ConfigNode.ParseVector2(pitchLimitsList[i]) : defaultPitchLimits;
                float   thisZoomRate   = (zoomRateList != null && i < zoomRateList.Length) ? JUtil.GetFloat(zoomRateList[i]) ?? 0.0f : 0.0f;
                float   thisYawRate    = (yawRateList != null && i < yawRateList.Length) ? JUtil.GetFloat(yawRateList[i]) ?? 0.0f : 0.0f;
                float   thisPitchRate  = (pitchRateList != null && i < pitchRateList.Length) ? JUtil.GetFloat(pitchRateList[i]) ?? 0.0f : 0.0f;

                var thatCamera = new SteerableCameraParameters(cameraTransformList[i],
                                                               thisFovLimit, thisYawLimit, thisPitchLimit,
                                                               thisZoomRate, thisYawRate, thisPitchRate, i + 1);
                cameras.Add(thatCamera);
            }

            gizmoTexture = JUtil.GetGizmoTexture();

            iconMaterial = new Material(Shader.Find("KSP/Alpha/Unlit Transparent"));

            // MOARdV: The maneuver gizmo texture is white. Unity's DrawTexture
            // expects a (0.5, 0.5, 0.5, 0.5) texture to be neutral for coloring
            // purposes.  Multiplying the desired alpha by 1/2 gets around the
            // gizmo texture's color, and gets correct alpha effects.
            Color32 iconColor = ConfigNode.ParseColor32(targetIconColor);

            iconColor.a       /= 2;
            iconMaterial.color = iconColor;

            homeCrosshairMaterial       = new Material(Shader.Find("KSP/Alpha/Unlit Transparent"));
            homeCrosshairMaterial.color = ConfigNode.ParseColor32(homeCrosshairColor);

            if (!string.IsNullOrEmpty(cameraInfoVarName))
            {
                persistence = new PersistenceAccessor(internalProp);
                if (persistence.HasPropVar(cameraInfoVarName + "_ID"))
                {
                    currentCamera = persistence.GetPropVar(cameraInfoVarName + "_ID") - 1;
                }
                else
                {
                    persistence.SetPropVar(cameraInfoVarName + "_ID", currentCamera + 1);
                }
            }
        }
        public void Start()
        {
            if (HighLogic.LoadedSceneIsEditor)
                return;

            if (string.IsNullOrEmpty(cameraTransform))
            {
                // Nothing to do if there're no camera transforms.
                return;
            }

            string[] cameraTransformList = cameraTransform.Split('|');

            // I'm sure this and the loop can be done a little differently to
            // make it clearer, but this works.
            string[] fovLimitsList = (string.IsNullOrEmpty(fovLimits)) ? null : fovLimits.Split('|');
            string[] yawLimitsList = (string.IsNullOrEmpty(yawLimits)) ? null : yawLimits.Split('|');
            string[] pitchLimitsList = (string.IsNullOrEmpty(pitchLimits)) ? null : pitchLimits.Split('|');
            string[] zoomRateList = (string.IsNullOrEmpty(zoomRate)) ? null : zoomRate.Split('|');
            string[] yawRateList = (string.IsNullOrEmpty(yawRate)) ? null : yawRate.Split('|');
            string[] pitchRateList = (string.IsNullOrEmpty(pitchRate)) ? null : pitchRate.Split('|');

            // cameraTransformList controls the number of cameras instantiated.
            // Every other value has a default, so if it's not specified, we
            // will use that default.
            for (int i = 0; i < cameraTransformList.Length; ++i)
            {
                Vector2 thisFovLimit = (fovLimitsList != null && i < fovLimitsList.Length) ? (Vector2)ConfigNode.ParseVector2(fovLimitsList[i]) : defaultFovLimits;
                Vector2 thisYawLimit = (yawLimitsList != null && i < yawLimitsList.Length) ? (Vector2)ConfigNode.ParseVector2(yawLimitsList[i]) : defaultYawLimits;
                Vector2 thisPitchLimit = (pitchLimitsList != null && i < pitchLimitsList.Length) ? (Vector2)ConfigNode.ParseVector2(pitchLimitsList[i]) : defaultPitchLimits;
                float thisZoomRate = (zoomRateList != null && i < zoomRateList.Length) ? JUtil.GetFloat(zoomRateList[i]) ?? 0.0f : 0.0f;
                float thisYawRate = (yawRateList != null && i < yawRateList.Length) ? JUtil.GetFloat(yawRateList[i]) ?? 0.0f : 0.0f;
                float thisPitchRate = (pitchRateList != null && i < pitchRateList.Length) ? JUtil.GetFloat(pitchRateList[i]) ?? 0.0f : 0.0f;

                var thatCamera = new SteerableCameraParameters(cameraTransformList[i],
                    thisFovLimit, thisYawLimit, thisPitchLimit,
                    thisZoomRate, thisYawRate, thisPitchRate, i + 1);
                cameras.Add(thatCamera);
            }

            gizmoTexture = JUtil.GetGizmoTexture();

            iconMaterial = new Material(Shader.Find("KSP/Alpha/Unlit Transparent"));

            // MOARdV: The maneuver gizmo texture is white. Unity's DrawTexture
            // expects a (0.5, 0.5, 0.5, 0.5) texture to be neutral for coloring
            // purposes.  Multiplying the desired alpha by 1/2 gets around the
            // gizmo texture's color, and gets correct alpha effects.
            Color32 iconColor = ConfigNode.ParseColor32(targetIconColor);
            iconColor.a /= 2;
            iconMaterial.color = iconColor;

            homeCrosshairMaterial = new Material(Shader.Find("KSP/Alpha/Unlit Transparent"));
            homeCrosshairMaterial.color = ConfigNode.ParseColor32(homeCrosshairColor);

            if (!string.IsNullOrEmpty(cameraInfoVarName))
            {
                persistence = new PersistenceAccessor(internalProp);
                if (persistence.HasPropVar(cameraInfoVarName + "_ID"))
                {
                    currentCamera = persistence.GetPropVar(cameraInfoVarName + "_ID") - 1;
                }
                else
                {
                    persistence.SetPropVar(cameraInfoVarName + "_ID", currentCamera + 1);
                }
            }
        }