Skip to content

MinAttribute have weird behaviours in large inspectors #227

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; }
    }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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