인프런 커뮤니티 질문&답변

고우진님의 프로필 이미지
고우진

작성한 질문수

[유니티 레벨 업!] 모듈식으로 개발하는 스킬 시스템

Skill (6) - Skill Custom Editor 및 Test

Retrieving array size but no array was provided 오류가 발생합니다.

작성

·

35

·

수정됨

0

property.arraySize이 문제인것 같은데

private void DrawSkillDatas()

{

// Skill의 Data가 아무것도 존재하지 않으면 1개를 자동적으로 만들어줌

if (skillDatasProperty.arraySize == 0)

{

// 배열 길이를 늘려서 새로운 Element를 생성

skillDatasProperty.arraySize++;

// 추가한 Data의 Level을 1로 설정

skillDatasProperty.GetArrayElementAtIndex(0).FindPropertyRelative("level").intValue = 1;

}

if (!DrawFoldoutTitle("Data"))

return;

EditorGUILayout.PropertyField(isAllowLevelExceedDatasProperty);

// Level 상한 제한이 없다면 MaxLevel을 그대로 그려주고,

// 상한 제한이 있다면 MaxLevel을 상한으로 고정 시키는 작업을 함

if (isAllowLevelExceedDatasProperty.boolValue)

EditorGUILayout.PropertyField(maxLevelProperty);

else

{

// Property를 수정하지 못하게 GUI Enable의 false로 바꿈

GUI.enabled = false;

var lastIndex = skillDatasProperty.arraySize - 1;

// 마지막 SkillData(= 가장 높은 Level의 Data)를 가져옴

var lastSkillData = skillDatasProperty.GetArrayElementAtIndex(lastIndex);

// maxLevel을 마지막 Data의 Level로 고정

maxLevelProperty.intValue = lastSkillData.FindPropertyRelative("level").intValue;

// maxLevel Property를 그려줌

EditorGUILayout.PropertyField(maxLevelProperty);

GUI.enabled = true;

}

EditorGUILayout.PropertyField(defaultLevelProperty);

 

for (int i = 0; i < skillDatasProperty.arraySize; i++)

{

var property = skillDatasProperty.GetArrayElementAtIndex(i);

var isUseCastProperty = property.FindPropertyRelative("isUseCast");

var isUseConcentrateProperty = property.FindPropertyRelative("isUseConcentration");

var chargeDurationProperty = property.FindPropertyRelative("chargeDuration");

var chargeTimeProperty = property.FindPropertyRelative("chargeTime");

var needChargeTimeToUseProperty = property.FindPropertyRelative("needLeastChargeTime");

var perfectDamageChargeTimeProperty = property.FindPropertyRelative("perfectDamageChargeTime");

var perfectDamageChargeTimeDetectionProperty = property.FindPropertyRelative("perfectDamageTimeDetection");

EditorGUILayout.BeginVertical("HelpBox");

{

// Data의 Level과 Data 삭제를 위한 X Button을 그려주는 Foldout Title을 그려줌

// 단, 첫번째 Data(= index 0) 지우면 안되기 때문에 X Button을 그려주지 않음

// X Button을 눌러서 Data가 지워지면 true를 return함

if (DrawRemovableLevelFoldout(skillDatasProperty, property, i, i != 0))

{

// Data가 삭제되었으며 더 이상 GUI를 그리지 않고 바로 빠져나감

// 다음 Frame에 처음부터 다시 그리기 위함

EditorGUILayout.EndVertical();

break;

}

EditorGUI.indentLevel += 1;

if (property.isExpanded)

{

// SkillData Property 내부로 들어감 -> Property == level field;

property.NextVisible(true);

DrawAutoSortLevelProperty(skillDatasProperty, property, i, i != 0);

// Level Up

for (int j = 0; j < 2; j++)

{

property.NextVisible(false);

EditorGUILayout.PropertyField(property);

}

// PrecedingAction

// Toggle Type일 때는 PrecedingAction을 사용하지 않을 것이므로,

// Instant Type일 때만 PrecedingAction 변수를 보여줌

property.NextVisible(false);

if (useTypeProperty.enumValueIndex == (int)SkillUseType.Instant)

EditorGUILayout.PropertyField(property);

// Action And Setting

for (int j = 0; j < 8; j++)

{

// 다음 변수의 Property로 이동하면서 그려줌

property.NextVisible(false);

EditorGUILayout.PropertyField(property);

}

// Cast

property.NextVisible(false);

if (IsDrawPropertyAll && !isUseConcentrateProperty.boolValue)

EditorGUILayout.PropertyField(property);

else

property.boolValue = false;

property.NextVisible(false);

if (isUseCastProperty.boolValue)

EditorGUILayout.PropertyField(property);

// Charge

property.NextVisible(false);

if (IsDrawPropertyAll && !isUseCastProperty.boolValue)

EditorGUILayout.PropertyField(property);

for (int j = 0; j < 5; j++)

{

property.NextVisible(false);

if (isUseConcentrateProperty.boolValue)

EditorGUILayout.PropertyField(property);

}

// 최대 chargeTime 값을 chargeDuration 값으로 제한

chargeTimeProperty.floatValue = Mathf.Min(chargeTimeProperty.floatValue, chargeDurationProperty.floatValue);

// 최대 needChargeTime 값을 chargeTime 값으로 제한

needChargeTimeToUseProperty.floatValue = Mathf.Min(chargeTimeProperty.floatValue, needChargeTimeToUseProperty.floatValue);

perfectDamageChargeTimeProperty.floatValue = Mathf.Clamp(perfectDamageChargeTimeProperty.floatValue,

needChargeTimeToUseProperty.floatValue,

chargeTimeProperty.floatValue);

// Effect

property.NextVisible(false);

EditorGUILayout.PropertyField(property);

 

//// EffectSelector의 level 변수를 effect의 최대 level 제한함

for (int j = 0; j < property.arraySize; j++)

{

var effectSelectorProperty = property.GetArrayElementAtIndex(j);

// Selector의 level Property를 가져옴

var levelProperty = effectSelectorProperty.FindPropertyRelative("level");

// Selector가 가진 effect를 가져옴

var effect = effectSelectorProperty.FindPropertyRelative("effect").objectReferenceValue as Effect;

var maxLevel = effect != null ? effect.MaxLevel : 0;

var minLevel = maxLevel == 0 ? 0 : 1;

levelProperty.intValue = Mathf.Clamp(levelProperty.intValue, minLevel, maxLevel);

}

}
파란색인 부분에서 계속 걸리는데 무슨 문제인지 모르겠습니다. 파란색 뒷부분은 너무 길어져서 잘랐습니다.
skillDatasProperty를 가져오는거라 Skill의 skillDatas가
[SerializeField]

private SkillData[] skillDatas;배열인것도 확인을 하였지만
if (property.isArray)

{

int size = property.arraySize;

Debug.Log("사이즈 :" + size);

}

else

{

Debug.LogError("이 속성은 배열 또는 리스트가 아닙니다.");

}이걸로 확인하니 배열이 아니라고 오는데 어떻게 배열이 아니게 된건지 모르겠습니다.

답변 2

1

고우진님의 프로필 이미지
고우진
질문자

다시 생각해보니 NextVisible으로 인해 꼬인것같습니다.

만약 아니라면 다시 질문드려도 괜찮을까요

Developer G님의 프로필 이미지
Developer G
지식공유자

말씀하신대로 property가 현재 Array Type이 아닌겁니다.
Code를 보시면서 NextVisible을 몇 번 호출했는지 보시고, 현재 property가 원하시는 알맞은 위치에 있는지 확인하시면 될 것 같습니다. 헷갈리신다면 EffectEditor에서 처럼 일일이 FindProperty 함수로 Property를 찾아 그리는 것도 방법입니다.

0

안녕하세요, 인프런 AI 인턴입니다. 고우진님.
질문해 주신 내용에 대해서 유사한 기존 답변을 제공하고 문제 해결에 도움이 될 만한 링크를 찾아보았습니다.

문제 요약

반환된 SerializedProperty가 배열 형태가 아니라는 점에서 발생하는 오류입니다. property.arraySize를 호출할 때 “Retrieving array size but no array was provided”라는 오류가 발생하며, 이는 SerializedProperty가 배열이나 리스트가 아니기 때문입니다.

해결 방안

오류의 원인은 SerializedProperty가 제대로 초기화되지 않거나, 배열이 아닌 다른 형태의 필드로 잘못 참조되고 있기 때문일 수 있습니다. 또한, Unity 버전에 따라 에디터 스크립트가 다르게 동작할 수도 있습니다.

기존 강의에서도 비슷한 문제를 해결한 답변이 있습니다. 해당 답변 링크를 참고하세요:
- IdentifiedObjectEditor 스크립트에서 에러가 납니다. - 여기서도 SerializedProperty 관련 오류를 다루고 있습니다. Unity 버전 문제일 수 있다는 답변도 포함되어 있습니다.

중요 포인트 요약 및 코멘트

  • SerializedProperty: SerializedProperty의 초기화와 사용 방법을 정확히 이해해야 합니다. 잘못된 경로를 통해 SerializedProperty를 가져오면 의도한 결과를 얻을 수 없습니다.
  • Unity 버전: Unity 버전에 따라 에디터 동작이 다를 수 있습니다. Unity의 최신 버전으로 업데이트하거나, 특정 버전에서의 문제가 있는지 확인해 보는 것도 좋습니다.
  • 코드 점검: 핵심 코드를 아래와 같이 간단히 점검해 보세요.
  serializedObject.Update();
  SerializedProperty skillDatasProperty = serializedObject.FindProperty("skillDatas");

  if (skillDatasProperty.isArray)
  {
      int size = skillDatasProperty.arraySize;
      Debug.Log("사이즈: " + size);
  }
  else
  {
      Debug.LogError("이 속성은 배열 또는 리스트가 아닙니다.");
  }

이 코드로 skillDatasProperty가 올바르게 초기화되었는지 확인합니다. 기존 DrawSkillDatas 함수의 첫 부분에서 이 부분을 확인해 보세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드렸습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

고우진님의 프로필 이미지
고우진

작성한 질문수

질문하기