using NodeCanvas.Framework; using ParadoxNotion.Design; using Unity.Cinemachine; using UnityEditor; using UnityEngine; // Individual bool setting for each ring. Three of these will be used. public struct OrbitalFollowValueGroup : ICameraValueGroup{ public string label; public CameraSettingsToggle changeHeight; public float height; public CameraSettingsToggle changeRadius; public float radius; public OrbitalFollowValueGroup(string newLabel){ label = newLabel; changeHeight = CameraSettingsToggle.NoChange; height = 0f; changeRadius = CameraSettingsToggle.NoChange; radius = 0f; } } // Setting for any X and Y based values public struct CinemachineVectorValueGroup{ public CameraSettingsToggle changeX; public float xValue; public CameraSettingsToggle changeY; public float yValue; } // Enum options for individual camera settings public enum CameraSettingsToggle{ NoChange, NewValue, ResetValue, RelativeValue, // Placeholder for using as altering existing value } public interface ICameraValueGroup{ } public struct Vector3CameraValueGroup : ICameraValueGroup{ public string label; public Vector3 newValue; public CameraSettingsToggle changeX; public CameraSettingsToggle changeY; public CameraSettingsToggle changeZ; public Vector3CameraValueGroup(string newLabel){ changeX = CameraSettingsToggle.NoChange; changeY = CameraSettingsToggle.NoChange; changeZ = CameraSettingsToggle.NoChange; newValue = Vector3.zero; label = newLabel; } } public struct Vector2CameraValueGroup : ICameraValueGroup{ public string label; public Vector2 newValue; public CameraSettingsToggle changeX; public CameraSettingsToggle changeY; public Vector2CameraValueGroup(string newLabel){ changeX = CameraSettingsToggle.NoChange; changeY = CameraSettingsToggle.NoChange; newValue = Vector2.zero; label = newLabel; } } public struct FloatCameraValueGroup : ICameraValueGroup{ public string label; public float value; public CameraSettingsToggle changeValue; public FloatCameraValueGroup(string newLabel){ label = newLabel; value = 0f; changeValue = CameraSettingsToggle.NoChange; } } public struct BoolCameraValueGroup : ICameraValueGroup{ public string label; public bool value; public CameraSettingsToggle changeValue; public BoolCameraValueGroup(string newLabel){ label = newLabel; value = true; changeValue = CameraSettingsToggle.NoChange; } } #if UNITY_EDITOR public class BoolCameraValueGroupDrawer : ObjectDrawer { public override BoolCameraValueGroup OnGUI(GUIContent content, BoolCameraValueGroup _instance){ // Remove label for floats EditorGUIUtility.labelWidth = 50; // Set layout options for the label and the float fields GUILayoutOption[] floatOptions = new GUILayoutOption[] { GUILayout.Width(80.0f), GUILayout.MinWidth(20.0f), GUILayout.ExpandWidth(true), }; GUILayoutOption[] labelOptions = new GUILayoutOption[]{ GUILayout.Width(200.0f), }; // Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options GUILayout.BeginVertical(); GUILayout.Label(_instance.label, labelOptions); GUILayout.BeginHorizontal(); // Create the x settings enum _instance.changeValue = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", instance.changeValue); // Create the value/disabled information field if (_instance.changeValue == CameraSettingsToggle.NewValue){ _instance.value = EditorGUILayout.Toggle(_instance.value, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeValue == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // Close this line up GUILayout.EndHorizontal(); GUILayout.EndVertical(); // Reset to default so the rest of things don't get messed up EditorGUIUtility.labelWidth = 0; return _instance; } } public class FloatCameraValueGroupDrawer : ObjectDrawer { public override FloatCameraValueGroup OnGUI(GUIContent _content, FloatCameraValueGroup _instance){ // Remove label for floats EditorGUIUtility.labelWidth = 50; // Set layout options for the label and the float fields GUILayoutOption[] floatOptions = new GUILayoutOption[] { GUILayout.Width(80.0f), GUILayout.MinWidth(20.0f), GUILayout.ExpandWidth(true), }; GUILayoutOption[] labelOptions = new GUILayoutOption[]{ GUILayout.Width(200.0f), }; // Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options GUILayout.BeginVertical(); GUILayout.Label(_instance.label, labelOptions); GUILayout.BeginHorizontal(); // Create the x settings enum _instance.changeValue = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", instance.changeValue); // Create the value/disabled information field if (_instance.changeValue == CameraSettingsToggle.NewValue){ _instance.value = EditorGUILayout.FloatField(_instance.value, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeValue == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // Close this line up GUILayout.EndHorizontal(); GUILayout.EndVertical(); // Reset to default so the rest of things don't get messed up EditorGUIUtility.labelWidth = 0; return _instance; } } public class Vector3CameraValueGroupDrawer : ObjectDrawer { public override Vector3CameraValueGroup OnGUI(GUIContent _content, Vector3CameraValueGroup _instance){ // Remove label for floats EditorGUIUtility.labelWidth = 20; // Set layout options for the label and the float fields GUILayoutOption[] floatOptions = new GUILayoutOption[] { GUILayout.Width(300.0f), GUILayout.MinWidth(20.0f), GUILayout.ExpandWidth(true), }; GUILayoutOption[] labelOptions = new GUILayoutOption[]{ GUILayout.Width(200.0f), }; // Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options GUILayout.BeginVertical(); GUILayout.Label(_instance.label, labelOptions); GUILayout.BeginHorizontal(); // Create the x settings enum _instance.changeX = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", instance.changeX); // Create the value/disabled information field if (_instance.changeX == CameraSettingsToggle.NewValue){ _instance.newValue.x = EditorGUILayout.FloatField(_instance.newValue.x, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeX == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // It do what it do. GUILayout.Space(5); // Create the y settings enum _instance.changeY = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", _instance.changeY); // Create the value/disabled information field if (_instance.changeY == CameraSettingsToggle.NewValue){ _instance.newValue.y = EditorGUILayout.FloatField(_instance.newValue.y, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeY == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // It do what it do. GUILayout.Space(5); // Create the y settings enum _instance.changeZ = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", _instance.changeZ); // Create the value/disabled information field if (_instance.changeZ == CameraSettingsToggle.NewValue){ _instance.newValue.z = EditorGUILayout.FloatField(_instance.newValue.z, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeZ == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // Close this line up GUILayout.EndHorizontal(); GUILayout.EndVertical(); // Reset to default so the rest of things don't get messed up EditorGUIUtility.labelWidth = 0; return _instance; } } public class Vector2CameraValueGroupDrawer : ObjectDrawer { public override Vector2CameraValueGroup OnGUI(GUIContent _content, Vector2CameraValueGroup _instance){ // Remove label for floats EditorGUIUtility.labelWidth = 50; // Set layout options for the label and the float fields GUILayoutOption[] floatOptions = new GUILayoutOption[] { GUILayout.Width(300.0f), GUILayout.MinWidth(20.0f), GUILayout.ExpandWidth(true), }; GUILayoutOption[] labelOptions = new GUILayoutOption[]{ GUILayout.Width(200.0f), }; // Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options GUILayout.BeginVertical(); GUILayout.Label(_instance.label, labelOptions); GUILayout.BeginHorizontal(); // Create the x settings enum _instance.changeX = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", instance.changeX); // Create the value/disabled information field if (_instance.changeX == CameraSettingsToggle.NewValue){ _instance.newValue.x = EditorGUILayout.FloatField(_instance.newValue.x, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeX == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // It do what it do. GUILayout.Space(5); // Create the y settings enum _instance.changeY = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", _instance.changeY); // Create the value/disabled information field if (_instance.changeY == CameraSettingsToggle.NewValue){ _instance.newValue.y = EditorGUILayout.FloatField(_instance.newValue.y, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeY == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // Close this line up GUILayout.EndHorizontal(); GUILayout.EndVertical(); // Reset to default so the rest of things don't get messed up EditorGUIUtility.labelWidth = 0; return _instance; } } // Custom editor for each orbital follow ring setting public class OrbitalFollowValueGroupDrawer : ObjectDrawer{ public override OrbitalFollowValueGroup OnGUI(GUIContent _content, OrbitalFollowValueGroup _instance){ // Remove label for floats EditorGUIUtility.labelWidth = 1; // Set layout options for the label and the float fields GUILayoutOption[] floatOptions = new GUILayoutOption[] { GUILayout.Width(300.0f), GUILayout.MinWidth(20.0f), GUILayout.ExpandWidth(true), }; GUILayoutOption[] labelOptions = new GUILayoutOption[]{ GUILayout.Width(60.0f), }; // Start a Horiztonal Section GUILayout.BeginHorizontal(); // Add the left side label GUILayout.Label(_instance.label, labelOptions); // Create the height settings enum _instance.changeHeight = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", _instance.changeHeight); // Create the value/disabled information field if (_instance.changeHeight == CameraSettingsToggle.NewValue){ _instance.height = EditorGUILayout.FloatField(_instance.height, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeHeight == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // It do what it do. GUILayout.Space(5); // Create the radius settings enum _instance.changeRadius = (CameraSettingsToggle)EditorGUILayout.EnumPopup("", _instance.changeRadius); // Create the value/disabled information field if (_instance.changeRadius == CameraSettingsToggle.NewValue){ _instance.radius = EditorGUILayout.FloatField(_instance.radius, floatOptions); } else { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField(_instance.changeRadius == CameraSettingsToggle.NoChange ? "Unchanged" : "Reset", floatOptions); EditorGUI.EndDisabledGroup(); } // Close this line up GUILayout.EndHorizontal(); // Reset to default so the rest of things don't get messed up EditorGUIUtility.labelWidth = 0; return _instance; } } #endif namespace NodeCanvas.Tasks.Actions { [Category("Reset")] [Description("Change Cinemachine camera settings for the player")] public class ChangeCameraSettings : ActionTask{ [ParadoxNotion.Design.Header("Main Settings")] public FloatCameraValueGroup fieldOfView = new (newLabel: "FOV"); [ParadoxNotion.Design.Header("Orbit Follow Ring Settings"), Space (5)] public Vector3CameraValueGroup orbitTargetOffset = new(newLabel: "Target Offset"); [Space(5)]public Vector3CameraValueGroup orbitPositionDamping = new(newLabel: "Position Damping"); public OrbitalFollowValueGroup orbitFollowTop = new (newLabel: "Top"); public OrbitalFollowValueGroup orbitFollowCenter = new (newLabel: "Center"); public OrbitalFollowValueGroup orbitFollowBottom = new (newLabel: "Bottom"); public BoolCameraValueGroup enableXAxis = new (newLabel: "Input Axis X Enabled"); public BoolCameraValueGroup enableYAxis = new (newLabel: "Input Axis Y Enabled"); public FloatCameraValueGroup axisLookXGain = new (newLabel: "Look Orbit X Gain"); public FloatCameraValueGroup axisLookYGain = new (newLabel: "Look Orbit Y Gain"); [ParadoxNotion.Design.Header("Rotation Composer Settings")] public Vector2CameraValueGroup screenPosition = new (newLabel: "Screen Position"); [ParadoxNotion.Design.Header("Camera Offset Settings")] public Vector3CameraValueGroup cameraOffset = new (newLabel: "Offset"); //Use for initialization. This is called only once in the lifetime of the task. //Return null if init was successfull. Return an error string otherwise protected override string OnInit(){ return null; } //This is called once each time the task is enabled. //Call EndAction() to mark the action as finished, either in success or failure. //EndAction can be called from anywhere. protected override void OnExecute(){ UpdateOrbitFollowValue(orbitFollowTop, ref CameraSettingsProcessor.values.orbitFollowTopHeight, ref CameraSettingsProcessor.values.orbitFollowTopRadius); UpdateOrbitFollowValue(orbitFollowCenter, ref CameraSettingsProcessor.values.orbitFollowCenterHeight, ref CameraSettingsProcessor.values.orbitFollowCenterRadius); UpdateOrbitFollowValue(orbitFollowBottom, ref CameraSettingsProcessor.values.orbitFollowBottomHeight, ref CameraSettingsProcessor.values.orbitFollowBottomRadius); UpdateVector3Value(cameraOffset, ref CameraSettingsProcessor.values.cameraOffsetOffset); UpdateVector3Value(orbitPositionDamping, ref CameraSettingsProcessor.values.orbitPositionDamping); UpdateVector3Value(orbitTargetOffset, ref CameraSettingsProcessor.values.orbitTargetOffset); UpdateVector2Value(screenPosition, ref CameraSettingsProcessor.values.rotationComposerScreenPos); UpdateFloatValue(fieldOfView, ref CameraSettingsProcessor.values.mainFieldOfView); UpdateFloatValue(axisLookXGain, ref CameraSettingsProcessor.values.axisLookGainX); UpdateFloatValue(axisLookYGain, ref CameraSettingsProcessor.values.axisLookGainY); UpdateBoolValue(enableXAxis, ref CameraSettingsProcessor.values.axisLookEnabledX); UpdateBoolValue(enableYAxis, ref CameraSettingsProcessor.values.axisLookEnabledY); EndAction(true); } public void UpdateVector3Value(Vector3CameraValueGroup valueGroup, ref CameraSettingSingleValue targetProperty){ switch (valueGroup.changeX) { case CameraSettingsToggle.NewValue: targetProperty.targetValue.x = valueGroup.newValue.x; break; case CameraSettingsToggle.ResetValue: targetProperty.targetValue.x = targetProperty.originalValue.x; break; } switch (valueGroup.changeY) { case CameraSettingsToggle.NewValue: targetProperty.targetValue.y = valueGroup.newValue.y; break; case CameraSettingsToggle.ResetValue: targetProperty.targetValue.y = targetProperty.originalValue.y; break; } switch (valueGroup.changeZ) { case CameraSettingsToggle.NewValue: targetProperty.targetValue.z = valueGroup.newValue.z; break; case CameraSettingsToggle.ResetValue: targetProperty.targetValue.z = targetProperty.originalValue.z; break; } } public void UpdateVector2Value(Vector2CameraValueGroup valueGroup, ref CameraSettingSingleValue targetProperty){ switch (valueGroup.changeX) { case CameraSettingsToggle.NewValue: targetProperty.targetValue.x = valueGroup.newValue.x; break; case CameraSettingsToggle.ResetValue: targetProperty.targetValue.x = targetProperty.originalValue.x; break; } switch (valueGroup.changeY) { case CameraSettingsToggle.NewValue: targetProperty.targetValue.y = valueGroup.newValue.y; break; case CameraSettingsToggle.ResetValue: targetProperty.targetValue.y = targetProperty.originalValue.y; break; } } public void UpdateOrbitFollowValue(OrbitalFollowValueGroup valueGroup, ref CameraSettingSingleValue targetHeight, ref CameraSettingSingleValue targetRadius){ switch (valueGroup.changeHeight) { case CameraSettingsToggle.NewValue: targetHeight.targetValue = valueGroup.height; break; case CameraSettingsToggle.ResetValue: targetHeight.targetValue = targetHeight.originalValue; break; } switch (valueGroup.changeRadius) { case CameraSettingsToggle.NewValue: targetRadius.targetValue = valueGroup.radius; break; case CameraSettingsToggle.ResetValue: targetRadius.targetValue = targetRadius.originalValue; break; } } public void UpdateBoolValue(BoolCameraValueGroup valueGroup, ref CameraSettingSingleValue targetProperty){ switch (valueGroup.changeValue) { case CameraSettingsToggle.NewValue: targetProperty.targetValue = valueGroup.value; break; case CameraSettingsToggle.ResetValue: targetProperty.targetValue = targetProperty.originalValue; break; } } public void UpdateFloatValue(FloatCameraValueGroup valueGroup, ref CameraSettingSingleValue targetProperty){ switch (valueGroup.changeValue) { case CameraSettingsToggle.NewValue: targetProperty.targetValue = valueGroup.value; break; case CameraSettingsToggle.ResetValue: targetProperty.targetValue = targetProperty.originalValue; break; } } //Called once per frame while the action is active. protected override void OnUpdate() { } //Called when the task is disabled. protected override void OnStop() { } //Called when the task is paused. protected override void OnPause() { } } }