작성
·
61
0
InActionState 플레이어의 입력을 받게 하려고 했는데
private PlayerInputEnum[] playerinput; 이렇게 변수를 만들고
playerinput = Entity.Owner.PlayerEntityInput.playerInputList; 이거를 통해서 가져오려고 했는데 이걸 Setup에 넣으면 스테이트 머신이 고장나면서 버그가 발생하고
KeyNotFoundException: The given key '0' was not present in the dictionary.
System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <834b2ded5dad441e8c7a4287897d63c7>:0)
StateMachine`1[EntityType].GetCurrentState (System.Int32 layer) (at Assets/Scripts/Core/StateMachine/StateMachine.cs:360)
StateMachine`1[EntityType].GetCurrentStateType (System.Int32 layer) (at Assets/Scripts/Core/StateMachine/StateMachine.cs:363)
Skill.GetCurrentStateType (System.Int32 layer) (at Assets/Scripts/Core/Skill/Skill.cs:600)
Test.SkillTest.OnGUI () (at Assets/Scripts/Test/Skill/SkillTest.cs:53)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
Enter에 넣어야 멀쩡히 작동을해서 질문을 드립니다.
다른 변수로 테스트를 해보아도 배열 형태의 변수만 버그가 발생하는것 같아 질문을 드립니다.
답변 1
0
수강해주셔서 감사합니다.
StateMachine Script 149번줄 AddState 함수를 보시면,
156번 줄에서 State를 Setup한 뒤 162번 줄에서 stateDatasByLayer에 Layer 0번 List를 만들기 때문에 Setup 함수에서 GetCurrentStateType 함수를 실행하면 아직 0번 Layer가 안만들어진 상태라 Error가 나게 됩니다.
올려주신 Error를 보면 Skill에서 GetCurrentStateType을 실행하는걸 볼 수 있구요, 156번 줄의 Setup 부분을 if 문 아래로 옮겨주시면 문제가 해결될겁니다.
감사합니다.
계속 버그가 발생해서 재부팅을 하니 해결이 되었습니다.
제가 ctrl+R로 새로 고침을 안했던건지 유니티 자체 버그 였던건지는 몰라도 유니티 재부팅 이후로 더이상 해당 오류가 발생하지 않고 setup을 기존의 위치로 옮겨도 해당 오류가 발생하질 않아서 더욱 모르게된거같습니다.
답변해주셔서 감사합니다.
해당 오류의 원인을 찾아내어서 발생 시키고 고쳐보겠습니다.
public void AddState<T>(int layer = 0) where T : State<EntityType>
{
// Layer 추가, Set이므로 이미 Layer가 존재한다면 추가되지 않음
layers.Add(layer);
// Type을 통해 State를 생성
var newState = Activator.CreateInstance<T>();
newState.Setup(this, Owner, layer);
// 아직 stateDatasByLayer에 추가되지 않은 Layer라면 Layer를 생성해줌
if (!stateDatasByLayer.ContainsKey(layer))
{
// Layer의 StateData 목록인 Dictionary<Type, StateData> 생성
stateDatasByLayer[layer] = new();
// Layer의 AnyTransitions 목록인 List<StateTransition<EntityType>> 생성
anyTransitionsByLayer[layer] = new();
}
Debug.Assert(!stateDatasByLayer[layer].ContainsKey(typeof(T)),
$"StateMachine::AddState<{typeof(T).Name}> - 이미 상태가 존재합니다.");
var stateDatasByType = stateDatasByLayer[layer];
// StateData를 만들어서 Layer에 추가
stateDatasByType[typeof(T)] = new StateData(layer, stateDatasByType.Count, newState);
}
이거를
public void AddState<T>(int layer = 0) where T : State<EntityType>
{
// Layer 추가, Set이므로 이미 Layer가 존재한다면 추가되지 않음
layers.Add(layer);
// Type을 통해 State를 생성
var newState = Activator.CreateInstance<T>();
// 아직 stateDatasByLayer에 추가되지 않은 Layer라면 Layer를 생성해줌
if (!stateDatasByLayer.ContainsKey(layer))
{
// Layer의 StateData 목록인 Dictionary<Type, StateData> 생성
stateDatasByLayer[layer] = new();
// Layer의 AnyTransitions 목록인 List<StateTransition<EntityType>> 생성
anyTransitionsByLayer[layer] = new();
}
newState.Setup(this, Owner, layer);
Debug.Assert(!stateDatasByLayer[layer].ContainsKey(typeof(T)),
$"StateMachine::AddState<{typeof(T).Name}> - 이미 상태가 존재합니다.");
var stateDatasByType = stateDatasByLayer[layer];
// StateData를 만들어서 Layer에 추가
stateDatasByType[typeof(T)] = new StateData(layer, stateDatasByType.Count, newState);
}
이런식으로 만드는게 맞을까요 여전히 버그가 발생하네요
그리고
private WeaponCollider weaponEnterd;
private PlayerInputEnum[] playerinput;
protected override void Setup()
{
isAutoExecuteType = Entity.ExecutionType == SkillExecutionType.Auto;
isWeaponTriggerExcuteType = Entity.ExecutionType == SkillExecutionType.WeaponTrigger;
}
public override void Enter()
{
playerinput = Entity.Owner.PlayerEntityInput.playerInputList;
weaponEnterd = Entity.Owner.Weapon;
weaponEnterd.OnObjectAdded += HandleObjectAdded;
if (!Entity.IsActivated)
Entity.Activate();
Entity.StartAction();
}
제가 개조한 InActionstate인데
weaponEnterd = Entity.Owner.Weapon;은 Setup으로 보내도 버그가 발생하지않고
playerinput = Entity.Owner.PlayerEntityInput.playerInputList;이 Enter에 있을때는 멀쩡한데 Setup으로 보낼때만 버그가 발생되어서 똑같이 Entity.Owner에서 가져오는데 어떤 차이점이 있을까에 대해서 질문을 드립니다.
Entity.Owner.PlayerEntityInput.playerInputList은 단순히 플레이어가 입력한 키를 Enum타입으로 재 정의한 후 받아서 저장하는 배열입니다.