changed: fov and better offset. parallelized grapple change.

This commit is contained in:
Chris
2025-07-14 15:46:26 -04:00
parent b0bf831676
commit cb554175c3
5 changed files with 298 additions and 52 deletions

View File

@@ -38,6 +38,24 @@ public enum CameraSettingsToggle{
ResetValue,
}
public struct Vector3CameraValueGroup{
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{
public string label;
public Vector2 newValue;
@@ -54,6 +72,135 @@ public struct Vector2CameraValueGroup{
}
}
public struct FloatCameraValueGroup{
public string label;
public float value;
public CameraSettingsToggle changeValue;
public FloatCameraValueGroup(string newLabel){
label = newLabel;
value = 0f;
changeValue = CameraSettingsToggle.NoChange;
}
}
public class FloatCameraValueGroupDrawer : ObjectDrawer<FloatCameraValueGroup> {
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.ToString(), 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<Vector3CameraValueGroup> {
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.ToString(), 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<Vector2CameraValueGroup> {
public override Vector2CameraValueGroup OnGUI(GUIContent _content, Vector2CameraValueGroup _instance){
// Remove label for floats
@@ -175,16 +322,20 @@ 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")]
public OrbitalFollowValueGroup orbitFollowTop = new OrbitalFollowValueGroup(newLabel: "Top");
public OrbitalFollowValueGroup orbitFollowCenter = new OrbitalFollowValueGroup(newLabel: "Center");
public OrbitalFollowValueGroup orbitFollowBottom = new OrbitalFollowValueGroup(newLabel: "Bottom");
public OrbitalFollowValueGroup orbitFollowTop = new (newLabel: "Top");
public OrbitalFollowValueGroup orbitFollowCenter = new (newLabel: "Center");
public OrbitalFollowValueGroup orbitFollowBottom = new (newLabel: "Bottom");
[ParadoxNotion.Design.Header("Rotation Composer Settings")]
public Vector2CameraValueGroup screenPosition = new Vector2CameraValueGroup(newLabel: "Screen Position");
public Vector2CameraValueGroup screenPosition = new (newLabel: "Screen Position");
[ParadoxNotion.Design.Header("Camera Offset Settings")]
public Vector3CameraValueGroup cameraOffset = new (newLabel: "Screen Position");
private CinemachineOrbitalFollow orbitalFollow;
//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(){
@@ -196,6 +347,17 @@ namespace NodeCanvas.Tasks.Actions {
//EndAction can be called from anywhere.
protected override void OnExecute(){
// Switch case farm for checking if values should be changed and what to
// Field of view
switch (fieldOfView.changeValue) {
case CameraSettingsToggle.NewValue:
CameraSettingsProcessor.values.mainFieldOfView.targetValue = fieldOfView.value;
break;
case CameraSettingsToggle.ResetValue:
CameraSettingsProcessor.values.mainFieldOfView.Reset();
break;
}
// Orbit follow rings
switch (orbitFollowTop.changeHeight) {
case CameraSettingsToggle.NewValue:
CameraSettingsProcessor.values.orbitFollowTopHeight.targetValue = orbitFollowTop.height;
@@ -250,29 +412,50 @@ namespace NodeCanvas.Tasks.Actions {
break;
}
// Screen Position
switch (screenPosition.changeX) {
case CameraSettingsToggle.NewValue:
CameraSettingsProcessor.values.rotationComposerScreenPos.targetValue = new Vector2(
screenPosition.newValue.x,
CameraSettingsProcessor.values.rotationComposerScreenPos.originalValue.y);
break;
CameraSettingsProcessor.values.rotationComposerScreenPos.targetValue.x = screenPosition.newValue.x;
break;
case CameraSettingsToggle.ResetValue:
CameraSettingsProcessor.values.rotationComposerScreenPos.targetValue = new Vector2(
CameraSettingsProcessor.values.rotationComposerScreenPos.originalValue.x,
CameraSettingsProcessor.values.rotationComposerScreenPos.originalValue.y);
CameraSettingsProcessor.values.rotationComposerScreenPos.targetValue.x = CameraSettingsProcessor.values.rotationComposerScreenPos.originalValue.x;
break;
}
switch (screenPosition.changeY) {
case CameraSettingsToggle.NewValue:
CameraSettingsProcessor.values.rotationComposerScreenPos.targetValue = new Vector2(
CameraSettingsProcessor.values.rotationComposerScreenPos.originalValue.x,
screenPosition.newValue.y);
CameraSettingsProcessor.values.rotationComposerScreenPos.targetValue.y = screenPosition.newValue.y;
break;
case CameraSettingsToggle.ResetValue:
CameraSettingsProcessor.values.rotationComposerScreenPos.targetValue = new Vector2(
CameraSettingsProcessor.values.rotationComposerScreenPos.originalValue.x,
CameraSettingsProcessor.values.rotationComposerScreenPos.originalValue.y);
CameraSettingsProcessor.values.rotationComposerScreenPos.targetValue.y = CameraSettingsProcessor.values.rotationComposerScreenPos.originalValue.y;
break;
}
// Camera Offset
switch (cameraOffset.changeX) {
case CameraSettingsToggle.NewValue:
CameraSettingsProcessor.values.cameraOffsetOffset.targetValue.x = cameraOffset.newValue.x;
break;
case CameraSettingsToggle.ResetValue:
CameraSettingsProcessor.values.cameraOffsetOffset.targetValue.x = CameraSettingsProcessor.values.cameraOffsetOffset.originalValue.x;
break;
}
switch (cameraOffset.changeY) {
case CameraSettingsToggle.NewValue:
CameraSettingsProcessor.values.cameraOffsetOffset.targetValue.y = cameraOffset.newValue.y;
break;
case CameraSettingsToggle.ResetValue:
CameraSettingsProcessor.values.cameraOffsetOffset.targetValue.y = CameraSettingsProcessor.values.cameraOffsetOffset.originalValue.y;
break;
}
switch (cameraOffset.changeZ) {
case CameraSettingsToggle.NewValue:
CameraSettingsProcessor.values.cameraOffsetOffset.targetValue.z = cameraOffset.newValue.z;
break;
case CameraSettingsToggle.ResetValue:
CameraSettingsProcessor.values.cameraOffsetOffset.targetValue.z = CameraSettingsProcessor.values.cameraOffsetOffset.originalValue.z;
break;
}

View File

@@ -9,14 +9,16 @@ public struct CameraSettingSingleValue<T>{
public float velocityRef;
public Vector2 velocityRefV2;
public Vector3 velocityRefV3;
public CameraSettingSingleValue(float defaultSmoothing, T original = default(T)){
originalValue = original;
targetValue = default(T);
targetValue = original;
smoothing = defaultSmoothing;
velocityRef = 0;
velocityRefV2 = default;
velocityRefV3 = default;
}
public void Reset(){
@@ -25,6 +27,8 @@ public struct CameraSettingSingleValue<T>{
}
public struct CameraSettingValues{
public CameraSettingSingleValue<float> mainFieldOfView;
public CameraSettingSingleValue<float> orbitFollowTopHeight;
public CameraSettingSingleValue<float> orbitFollowTopRadius;
public CameraSettingSingleValue<float> orbitFollowCenterHeight;
@@ -33,8 +37,12 @@ public struct CameraSettingValues{
public CameraSettingSingleValue<float> orbitFollowBottomRadius;
public CameraSettingSingleValue<Vector2> rotationComposerScreenPos;
public CameraSettingSingleValue<Vector3> cameraOffsetOffset;
public CameraSettingValues(float defaultSmoothing){
mainFieldOfView = new CameraSettingSingleValue<float>(defaultSmoothing);
orbitFollowTopHeight = new CameraSettingSingleValue<float>(defaultSmoothing);
orbitFollowTopRadius = new CameraSettingSingleValue<float>(defaultSmoothing);
orbitFollowCenterHeight = new CameraSettingSingleValue<float>(defaultSmoothing);
@@ -43,6 +51,7 @@ public struct CameraSettingValues{
orbitFollowBottomRadius = new CameraSettingSingleValue<float>(defaultSmoothing);
rotationComposerScreenPos = new CameraSettingSingleValue<Vector2>(defaultSmoothing);
cameraOffsetOffset = new CameraSettingSingleValue<Vector3>(defaultSmoothing);
}
}
@@ -53,46 +62,45 @@ public class CameraSettingsProcessor : MonoBehaviour{
public static GameObject mainCamera;
private CinemachineCamera main;
private CinemachineOrbitalFollow orbit;
private CinemachineRotationComposer rotComp;
private CinemachineCameraOffset offset;
public void Awake(){
// Singleton management
if (Instance != null && Instance != this) {
Destroy(this);
} else {
Instance = this;
}
// Set references for camera object and cinemachine components
mainCamera = gameObject;
main = mainCamera.GetComponent<CinemachineCamera>();
orbit = mainCamera.GetComponent<CinemachineOrbitalFollow>();
rotComp = mainCamera.GetComponent<CinemachineRotationComposer>();
offset = mainCamera.GetComponent<CinemachineCameraOffset>();
StashCameraOriginalSettings(this);
SetTargetsToOriginalValues(this);
// Initialize camera settings values
values = new CameraSettingValues{
cameraOffsetOffset = new CameraSettingSingleValue<Vector3>(defaultSmoothing: .2f, offset.Offset),
mainFieldOfView = new CameraSettingSingleValue<float>(defaultSmoothing: .2f, main.Lens.FieldOfView),
orbitFollowTopHeight = new CameraSettingSingleValue<float>(defaultSmoothing: .2f, orbit.Orbits.Top.Height),
orbitFollowTopRadius = new CameraSettingSingleValue<float>(defaultSmoothing: .2f, orbit.Orbits.Top.Radius),
orbitFollowCenterHeight = new CameraSettingSingleValue<float>(defaultSmoothing: .2f, orbit.Orbits.Center.Height),
orbitFollowCenterRadius = new CameraSettingSingleValue<float>(defaultSmoothing: .2f, orbit.Orbits.Center.Radius),
orbitFollowBottomHeight = new CameraSettingSingleValue<float>(defaultSmoothing: .2f, orbit.Orbits.Bottom.Height),
orbitFollowBottomRadius = new CameraSettingSingleValue<float>(defaultSmoothing: .2f, orbit.Orbits.Bottom.Radius),
rotationComposerScreenPos = new CameraSettingSingleValue<Vector2>(defaultSmoothing: .2f, rotComp.Composition.ScreenPosition),
};
}
public static void StashCameraOriginalSettings(CameraSettingsProcessor settings){
values.orbitFollowTopHeight.originalValue = settings.orbit.Orbits.Top.Height;
values.orbitFollowTopRadius.originalValue = settings.orbit.Orbits.Top.Radius;
values.orbitFollowCenterHeight.originalValue = settings.orbit.Orbits.Center.Height;
values.orbitFollowCenterRadius.originalValue = settings.orbit.Orbits.Center.Radius;
values.orbitFollowBottomHeight.originalValue = settings.orbit.Orbits.Bottom.Height;
values.orbitFollowBottomRadius.originalValue = settings.orbit.Orbits.Bottom.Radius;
values.rotationComposerScreenPos.originalValue = settings.rotComp.Composition.ScreenPosition;
}
public static void SetTargetsToOriginalValues(CameraSettingsProcessor settings){
values.orbitFollowTopHeight.Reset();
values.orbitFollowTopRadius.Reset();
values.orbitFollowCenterHeight.Reset();
values.orbitFollowCenterRadius.Reset();
values.orbitFollowBottomHeight.Reset();
values.orbitFollowBottomRadius.Reset();
values.rotationComposerScreenPos.Reset();
}
void ProcessCameraValues(){
main.Lens.FieldOfView = Mathf.SmoothDamp(main.Lens.FieldOfView,
values.mainFieldOfView.targetValue, ref values.mainFieldOfView.velocityRef,
values.mainFieldOfView.smoothing);
orbit.Orbits.Top.Height = Mathf.SmoothDamp(orbit.Orbits.Top.Height,
values.orbitFollowTopHeight.targetValue, ref values.orbitFollowTopHeight.velocityRef,
values.orbitFollowTopHeight.smoothing);
@@ -120,6 +128,10 @@ public class CameraSettingsProcessor : MonoBehaviour{
rotComp.Composition.ScreenPosition = Vector2.SmoothDamp(rotComp.Composition.ScreenPosition,
values.rotationComposerScreenPos.targetValue, ref values.rotationComposerScreenPos.velocityRefV2,
values.rotationComposerScreenPos.smoothing);
offset.Offset = Vector3.SmoothDamp(offset.Offset,
values.cameraOffsetOffset.targetValue, ref values.cameraOffsetOffset.velocityRefV3,
values.cameraOffsetOffset.smoothing);
}
void Update(){