Я пытаюсь создать свою собственную машину состояний, но столкнулся с некоторыми проблемами в отношении списков классов с общим типом. Мой код выглядит следующим образом.Как создать список классов с параметром generic type в C#?
State.cs:
using UnityEngine;
using System.Collections;
public abstract class State<T> where T:StateMachine
{
public T sm;
public State()
{
}
public virtual void OnEnter()
{
sm.currentState = sm.futureState;
}
public abstract void OnExit();
public abstract void OnLoop();
}
StateMachine.cs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public abstract class StateMachine : MonoBehaviour
{
public List<State<T>> stateList = new List<T>>();
public int currentState = -1;
public int futureState;
protected virtual void Start()
{
foreach (State<T> s in stateList)
{
s.sm = this;
}
}
protected virtual void Update()
{
if (currentState != futureState)
{
stateList[futureState].OnEnter();
}
stateList[currentState].OnLoop();
if (currentState != futureState)
{
stateList[currentState].OnExit();
}
}
}
TestStateMachine.cs:
using UnityEngine;
using System.Collections;
public class TestStateMachine : StateMachine
{
public enum StateNames:int
{
State1,
State2,
};
public KeyCode kc;
// Use this for initialization
protected override void Start()
{
stateList.Add(new TestStateMachineFirstState());
stateList.Add(new TestStateMachineSecondState());
base.Start();
}
}
public class TestStateMachineFirstState : State<StateMachine>
{
public override void OnEnter()
{
Debug.Log("SM1 OnEnter");
base.OnEnter();
}
public override void OnLoop()
{
Debug.Log("SM1 OnLoop");
if (Input.GetKeyDown(sm.kc))
{
sm.futureState = (int)TestStateMachine.StateNames.State2;
}
}
public override void OnExit()
{
Debug.Log("SM1 OnExit");
}
}
public class TestStateMachineSecondState : State<StateMachine>
{
public override void OnEnter()
{
Debug.Log("SM2 OnEnter");
base.OnEnter();
}
public override void OnLoop()
{
Debug.Log("SM2 OnLoop");
if (Input.GetKeyDown(sm.kc))
{
sm.futureState = (int)TestStateMachine.StateNames.State1;
}
}
public override void OnExit()
{
Debug.Log("SM2 OnExit");
}
}
Я получаю ошибку CS0246: Type or namespace name T cannot be found
(или что-то, что звучит подобное).
Мое состояние машины «функции», если я заменю все State<T>
и State<TestStateMachine>
с State<StateMachine>
и если (Input.GetKeyDown(sm.kc))
с (Input.GetKeyDown(KeyCode.A))
.
Но это не идеальный вариант, поскольку я не смог бы получить переменные с компьютеров состояния детей. Есть ли способ сохранить эту структуру (как бы плохо она ни была), или я должен попробовать другой подход к использованию государственных машин?
* Где * вы получаете сообщение об ошибке? Можете ли вы воспроизвести его с меньшим количеством кода? И можете ли вы правильно отложить свой код? Это сделало бы его намного легче читать ... –
Мое лучшее предположение, что у вас есть некоторые проблемы при добавлении экземпляров в список>, но дайте некоторые пояснения. –
Ну, для начала, есть следующее: 'public List> stateList = new List >();' –