0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】Screen.width / heightはOnEnable内で使わない方がよさそう

Last updated at Posted at 2024-08-06

概要

ある MonoBehaviour の OnEnable() / OnDisable()内でScreen.width / heightを使用した際に、予期しない値が返されていた.Unity2021.2.10f1 を使用.

公式ドキュメント:https://docs.unity3d.com/ScriptReference/Screen.html

結論

Screen.widthScreen.heightを OnEnable()内で使用すると、正しくない値が返されることがあるらしい.

(※自分はまだ上記バージョンでしか確認作業を行ってない.)

詳細

【確認のため使用したコード】

以下のコードで MonoBehaviour の Update、OnEnable、OnDisable 時の値を記録してインスペクタ上に表示した.また、Editor クラスの OnInspectorGUI での値も同時に確認した.

ScreenSizeDebugger.cs
using System.Collections.Generic;
using UnityEngine;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif

//[ExecuteAlways]  // ※ExecuteAlwaysでもほぼ同様の結果だった
public class ScreenSizeDebugger: MonoBehaviour{

    // サイズの記録
    public Vector2 size_Update;
    public Vector2 size_OnEnable;
    public Vector2 size_OnDisable;

    //
    public DateTime lastEnableTime = DateTime.MinValue;
    public DateTime lastDisableTime = DateTime.MinValue;

    private void Update() {
        size_Update =  new Vector2(Screen.width, Screen.height);
    }

    private void OnEnable() {
        size_OnEnable =  new Vector2(Screen.width, Screen.height);
        lastEnableTime = DateTime.Now;
    }

    private void OnDisable() {
        size_OnDisable =  new Vector2(Screen.width, Screen.height);
        lastDisableTime = DateTime.Now;
    }
}

#if UNITY_EDITOR
[CustomEditor(typeof(ScreenSizeDebugger))]
public class ScreenSizeDebuggerEditor : Editor {

    public override void OnInspectorGUI() {
        var instance = target as ScreenSizeDebugger;

        // MonoBehaviour
        var modeText = Application.isPlaying ? "Play mode" : "Edit mode";
        DrawScreenSizeInfo($"MonoBehaviour.<b>Update</b> ({modeText})", instance.size_Update.x, instance.size_Update.y);

        DrawScreenSizeInfo($"MonoBehaviour.<b>OnEnable</b> ({modeText})", instance.size_OnEnable.x, instance.size_OnEnable.y);
        EditorGUILayout.LabelField($"elaposed time {(DateTime.Now - instance.lastEnableTime).ToString("ss")} [s]");

        DrawScreenSizeInfo($"MonoBehaviour.<b>OnDisable</b> ({modeText})", instance.size_OnDisable.x, instance.size_OnDisable.y);
        EditorGUILayout.LabelField($"elaposed time {(DateTime.Now - instance.lastDisableTime).ToString("ss")} [s]");


        // Editor
        DrawScreenSizeInfo($"Editor.OnInspector", Screen.width, Screen.height);

        EditorUtil.GUI.HorizontalLine();
        // -------------------

        // インスペクタが表示されている画面の解像度
        EditorGUILayout.LabelField("Current Resolution", $"{Screen.currentResolution.width} x {Screen.currentResolution.height} @ {Screen.currentResolution.refreshRate}Hz");

        // 登録されている全ての解像度
        EditorGUILayout.LabelField("Supported Resolutions:");
        using (new EditorGUI.IndentLevelScope()) {
            foreach (var resolution in Screen.resolutions) {
                EditorGUILayout.LabelField($"{resolution.width} x {resolution.height} @ {resolution.refreshRate}Hz");
            }
        }
    }

    private void DrawScreenSizeInfo(string labelText, float width, float height) {
        EditorUtil.GUI.HorizontalLine();

        // SCREEN SIZE
        EditorGUILayout.LabelField(labelText, Styles.label);
        using (new EditorGUILayout.VerticalScope(GUI.skin.box))
        using (new EditorGUI.IndentLevelScope()) {
            EditorGUILayout.LabelField("Screen Width", width.ToString(), Styles.label);
            EditorGUILayout.LabelField("Screen Height", height.ToString(), Styles.label);
        }
    }

    private static class Styles {
        public static GUIStyle label;
        static Styles() {
            label = new GUIStyle(GUI.skin.label) {
                richText = true,
            };
        }
    }
}
#endif
Util.cs
util.cs
public static partial class EditorUtil {
    public static partial class GUI {

        /// <summary>
        /// 仕切り線を表示する
        /// </summary>
        public static void HorizontalLine(Color color, int thickness = 1, int padding = 10) {

            using (new EditorGUILayout.HorizontalScope()) {
                var splitterRect = EditorGUILayout.GetControlRect(false, GUILayout.Height(thickness + padding));
                splitterRect = EditorGUI.IndentedRect(splitterRect);
                splitterRect.height = thickness;
                splitterRect.y += padding / 2;

                EditorGUI.DrawRect(splitterRect, color);
            }
        }
    }
}

【結果】

image.png

Update では設定した Game 画面の解像度の値、Editor.OnInspectorGUI()ではインスペクタウインドウのサイズが返される.

一方、OnEnable/OnDisable は基本的に Editor.OnInspectorGUI()と同様の値が入っていた.
(※PlayMode に入るときの最初の呼び出し時のみ、Update と同じ値だった.)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?