Skip to content

MinAttribute have weird behaviours in large inspectors #227

@Saradora

Description

@Saradora

Hello !

On an empty Unity 6000.3.4f1 projet with only Tri-Inspector installed, the following code makes the ScriptableObject's inspector bug out.

Trying to select a field in the bottom of the inspector selects instead something higher.

I've noticed that removing the "Min" attributes resolves the issue.

using UnityEngine;

namespace CTS.EnemiesFSMDetection.Data
{
    [CreateAssetMenu(menuName = "CTS/EnemiesFSMDetection/EnemySettings")]
    public class EnemySettingsSO : ScriptableObject
    {
        private const float MinDetectionTick = 0.05f;

        [field: Header("General")]
        [field: Tooltip("Tag used to identify the player GameObject.")]
        [field: SerializeField] public string PlayerTag { get; private set; } = "Player";

        [field: Tooltip("Interval in seconds between detection checks. Lower values = more responsive but costly.")]
        [field: Min(0.05f)]
        [field: SerializeField] public float DetectionTickSeconds { get; private set; } = 1f;

        [field: Header("Vision")]
        [field: Tooltip("Maximum distance in meters at which the enemy can see the player.")]
        [field: Min(0f)]
        [field: SerializeField] public float VisionDistance { get; private set; } = 10f;

        [field: Tooltip("Total vision cone angle in degrees (e.g., 90 means 45 degrees on each side).")]
        [field: Range(1f, 179f)]
        [field: SerializeField] public float VisionAngleDegrees { get; private set; } = 90f;

        [field: Tooltip("Layer mask for detecting the player.")]
        [field: SerializeField] public LayerMask PlayerLayerMask { get; private set; }

        [field: Tooltip("Layer mask for obstacles that block line of sight.")]
        [field: SerializeField] public LayerMask ObstacleLayerMask { get; private set; }

        [field: Tooltip("Vertical offset for line-of-sight raycast origin (eye height).")]
        [field: SerializeField] public float LosRaycastHeightOffset { get; private set; } = 1.5f;

        [field: Tooltip("If true, performs a raycast to verify line of sight to the player.")]
        [field: SerializeField] public bool UseLineOfSightRaycast { get; private set; } = true;

        [field: Header("Hearing")]
        [field: Tooltip("Maximum distance in meters at which the enemy can hear noises.")]
        [field: Min(0f)]
        [field: SerializeField] public float HearingRadius { get; private set; } = 15f;

        [field: Tooltip("Cooldown in seconds before the enemy can react to another noise.")]
        [field: Min(0f)]
        [field: SerializeField] public float HearingCooldownSeconds { get; private set; } = 0.5f;

        [field: Header("Chase")]
        [field: Tooltip("Time in seconds the enemy continues chasing after losing sight of the player.")]
        [field: Min(0f)]
        [field: SerializeField] public float ChaseLoseSightSeconds { get; private set; } = 3f;

        [field: Header("Attack")]
        [field: Tooltip("Distance in meters at which the enemy can attack the player.")]
        [field: Min(0f)]
        [field: SerializeField] public float AttackDistance { get; private set; } = 2f;

        [field: Tooltip("Distance at which the enemy stops moving toward the player during attack.")]
        [field: Min(0f)]
        [field: SerializeField] public float StoppingDistance { get; private set; } = 1.5f;

        [field: Header("Movement")]
        [field: Tooltip("Base movement speed in units per second.")]
        [field: Min(0f)]
        [field: SerializeField] public float MoveSpeed { get; private set; } = 3.5f;

        [field: Tooltip("Rotation speed in degrees per second.")]
        [field: Min(0f)]
        [field: SerializeField] public float RotationSpeed { get; private set; } = 120f;

        [field: Tooltip("Distance threshold to consider a waypoint as reached.")]
        [field: Min(0f)]
        [field: SerializeField] public float WaypointReachDistance { get; private set; } = 0.5f;

        [field: Header("Movement - Advanced")]
        [field: Tooltip("Minimum direction vector magnitude to trigger rotation. Prevents jitter.")]
        [field: Min(0f)]
        [field: SerializeField] public float DirectionMagnitudeThreshold { get; private set; } = 0.001f;

        [field: Tooltip("Minimum velocity magnitude to consider the enemy as moving.")]
        [field: Min(0f)]
        [field: SerializeField] public float VelocityMagnitudeThreshold { get; private set; } = 0.01f;

        [field: Tooltip("Radius of the patrol area when using Area patrol mode.")]
        [field: Min(0f)]
        [field: SerializeField] public float PatrolAreaRadius { get; private set; } = 10f;

        [field: Tooltip("Time in seconds before picking a new random point in Area patrol mode.")]
        [field: Min(0f)]
        [field: SerializeField] public float PatrolAreaPointRefreshSeconds { get; private set; } = 5f;

        [field: Header("Investigation")]
        [field: Tooltip("Movement speed when investigating a noise or disturbance.")]
        [field: Min(0f)]
        [field: SerializeField] public float InvestigationSpeed { get; private set; } = 2f;

        [field: Tooltip("Maximum time in seconds to investigate before giving up.")]
        [field: Min(0f)]
        [field: SerializeField] public float InvestigationTimeout { get; private set; } = 5f;

        [field: Tooltip("Time in seconds to linger at the investigation point before returning.")]
        [field: Min(0f)]
        [field: SerializeField] public float InvestigationLingerTime { get; private set; } = 2f;

        [field: Header("Debug - Gizmos")]
        [field: Tooltip("Display the vision cone gizmo in the Scene view.")]
        [field: SerializeField] public bool ShowVisionConeGizmos { get; private set; } = true;

        [field: Tooltip("Display the hearing radius gizmo in the Scene view.")]
        [field: SerializeField] public bool ShowHearingRadiusGizmos { get; private set; } = true;

        [field: Tooltip("Display patrol path/waypoints gizmo in the Scene view.")]
        [field: SerializeField] public bool ShowPatrolPathGizmos { get; private set; } = true;

        [field: Tooltip("Display line-of-sight raycast debug lines in the Scene view.")]
        [field: SerializeField] public bool ShowLosRaycastGizmos { get; private set; } = true;

        [field: Header("Debug - Logging")]
        [field: Tooltip("Log state machine transitions to the console.")]
        [field: SerializeField] public bool LOGStateTransitions { get; private set; } = true;

        [field: Header("Debug - Runtime")]
        [field: Tooltip("Display a runtime mesh representing the vision cone during play mode.")]
        [field: SerializeField] public bool ShowVisionRuntimeMesh { get; private set; }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions