Alchemy
Alchemy copied to clipboard
Weird [Button] ordering
This attribute seems to cause weird ordering in the inspector.
- FoldoutGroup is always rendered after everything else
- Having multiple foldout groups causes weird ordering, as can be seen in the example below
Weird Ordering Code
using System;
using System.Threading.Tasks;
using Alchemy.Inspector;
using Assets.Scripts.Player.Camera;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Assets.Scripts.Core
{
public class SettingsManager : MonoBehaviour
{
[FoldoutGroup("Volume Profiles"), SerializeField, Required]
private VolumeProfile _dofProfile;
[FoldoutGroup("Volume Profiles"), SerializeField, Required]
private VolumeProfile _menuDOFProfile;
[FoldoutGroup("Volume Profiles"), SerializeField, Required]
private VolumeProfile _motionBlurProfile;
[FoldoutGroup("Audio"), SerializeField, Required] private AudioMixerGroup _master;
[FoldoutGroup("Audio"), SerializeField, Required] private AudioMixerGroup _sfx;
[FoldoutGroup("Audio"), SerializeField, Required] private AudioMixerGroup _music;
private void Awake() => LoadSettings();
private async void LoadSettings()
{
UseDOF = PlayerPrefs.GetInt("UseDOF", 1) == 1;
MotionBlur = PlayerPrefs.GetFloat("MotionBlur", 1);
Perspective = (Perspective)Enum.Parse(typeof(Perspective),
PlayerPrefs.GetString("Perspective", "First"));
// Takes care of updating the UI
MasterVolume = PlayerPrefs.GetFloat("MasterVolume", 0.5f);
SFXVolume = PlayerPrefs.GetFloat("SFXVolume", 1f);
MusicVolume = PlayerPrefs.GetFloat("MusicVolume", 1f);
// Wait a bit before updating the audio mixer cuz unity devs are competent
await Task.Delay(TimeSpan.FromSeconds(0.01f));
MasterVolume = PlayerPrefs.GetFloat("MasterVolume", 0.5f);
SFXVolume = PlayerPrefs.GetFloat("SFXVolume", 1f);
MusicVolume = PlayerPrefs.GetFloat("MusicVolume", 1f);
}
#region DOF
[FoldoutGroup("Settings"), Button]
public void ChangeDOF(bool useDOF) => UseDOF = useDOF;
private bool _useDOF;
public bool UseDOF
{
get => _useDOF;
private set
{
if (_useDOF == value) return;
_useDOF = value;
if (_menuDOFProfile && _dofProfile.TryGet(out DepthOfField dof))
dof.active = _useDOF;
if (_menuDOFProfile && _menuDOFProfile.TryGet(out DepthOfField menuDOF))
menuDOF.active = _useDOF;
PlayerPrefs.SetInt("UseDOF", UseDOF ? 1 : 0);
}
}
#endregion
#region MotionBlur
[FoldoutGroup("Settings"), Button]
public void ChangeMotionBlur(float mb) => MotionBlur = mb;
private float _motionBlur;
public float MotionBlur
{
get => _motionBlur;
private set
{
if (Mathf.Approximately(_motionBlur, value)) return;
_motionBlur = value;
if (_motionBlurProfile && _motionBlurProfile.TryGet(out MotionBlur mb))
mb.intensity.value = _motionBlur;
PlayerPrefs.SetFloat("MotionBlur", value);
}
}
#endregion
#region Perspective
[FoldoutGroup("Settings"), Button]
public void ChangePerspective(Perspective p) => Perspective = p;
public void ChangePerspective(int p) => Perspective = (Perspective)p;
private Perspective _perspective;
public Perspective Perspective
{
get => _perspective;
set
{
if (_perspective == value) return;
_perspective = value;
PlayerPrefs.SetString("Perspective", _perspective.ToString());
}
}
#endregion
#region Volume
private float GetVolume(float t) => Mathf.Lerp(-80, 0, t);
[FoldoutGroup("Settings/Audio"), Button]
public void ChangeMasterVolume(float vol) => MasterVolume = vol;
[FoldoutGroup("Settings/Audio"), Button]
public void ChangeSFXVolume(float vol) => SFXVolume = vol;
[FoldoutGroup("Settings/Audio"), Button]
public void ChangeMusicVolume(float vol) => MusicVolume = vol;
private float _masterVolume;
public float MasterVolume
{
get => _masterVolume;
private set
{
if (Mathf.Approximately(_masterVolume, value)) return;
_masterVolume = value;
_master.audioMixer.SetFloat("MasterVolume", GetVolume(value));
PlayerPrefs.SetFloat("MasterVolume", value);
}
}
private float _sfxVolume;
public float SFXVolume
{
get => _sfxVolume;
private set
{
if (Mathf.Approximately(_sfxVolume, value)) return;
_sfxVolume = value;
_sfx.audioMixer.SetFloat("SFXVolume", GetVolume(value));
PlayerPrefs.SetFloat("SFXVolume", value);
}
}
private float _musicVolume;
public float MusicVolume
{
get => _musicVolume;
private set
{
if (Mathf.Approximately(_musicVolume, value)) return;
_musicVolume = value;
_music.audioMixer.SetFloat("MusicVolume", GetVolume(value));
PlayerPrefs.SetFloat("MusicVolume", value);
}
}
#endregion
}
}
Reading the code, it would make sense for settings to be located below everything else, however, they end up being on top. Am I using this the wrong way or is this a bug?
Ok, this is not the only instance of it happening. I am starting to have a feeling it's something to do with buttons. Once again, I have this class:
namespace Assets.Scripts.Player.Camera
{
public class CameraHandlerScript : MonoBehaviour
{
private static Transform Player => PlaySceneManager.Player.transform;
public Perspective Perspective;
[SerializeField] private LayerMask _cameraCollisionMask;
[Tooltip("Offset from the player")]
[FoldoutGroup("Position"), SerializeField] private Vector3 _offset;
[Tooltip("Whether offset is applied locally or globally")]
[FoldoutGroup("Position"), SerializeField] private bool _localOffset;
[Tooltip("If enabled, offset will be applied according to the rotation")]
[FoldoutGroup("Position"), SerializeField] private bool _translateOffset;
[Tooltip("Whether the camera will follow player's rotation")]
[FoldoutGroup("Rotation"), SerializeField] private bool _rotateCamera;
[Tooltip("Delta between the player rotation and camera rotation")]
[FoldoutGroup("Rotation"), SerializeField] private Vector3 _rotationOffset;
[Button, Order(1)]
private void AddToSceneManager()
{
var handlers = PlaySceneManager.CameraManager.Handlers;
if (!handlers.Contains(this)) PlaySceneManager.CameraManager.Handlers.Add(this);
}
[Button, Order(1)]
private void RemoveFromSceneManager()
{
var handlers = PlaySceneManager.CameraManager.Handlers;
if (handlers.Contains(this)) PlaySceneManager.CameraManager.Handlers.Remove(this);
}
}
}
And even tho I explicitly tried setting the higher order, and also placing buttons under other elements, they still appear over some: