Alchemy icon indicating copy to clipboard operation
Alchemy copied to clipboard

Weird [Button] ordering

Open nnra6864 opened this issue 9 months ago • 1 comments

This attribute seems to cause weird ordering in the inspector.

  1. FoldoutGroup is always rendered after everything else
  2. Having multiple foldout groups causes weird ordering, as can be seen in the example below

Image

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?

nnra6864 avatar Apr 26 '25 09:04 nnra6864

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:

Image

nnra6864 avatar Apr 26 '25 11:04 nnra6864