您的位置:首页 > 移动开发 > Unity3D

Unity3D C# 状态机封装

2017-03-17 18:29 302 查看
简单明了,提供了一下几个功能。

enum类型状态id,c# 枚举Enum和int转换(不使用强转)
状态切换,获取当前状态,和前一个状态
状态进入,退出,执行
作为组件绑定在GameObject对象上,从此拥有了状态机
为什么要使用enum类型的状态id ?enum的特性符合,状态标识的要求
enum比string高效,也不损失可读性
enum比int有明确的类型要求,增加类型安全性
剔除了自定义enum类型和父类enum的强转的繁琐,增加了可读性
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

namespace OnePixelFramework
{
public class StateMachine : MonoBehaviour
{
private Dictionary<int, State> stateDict = new Dictionary<int, State>();

// 当前状态
public State curState
{
private set;
get;
}

// 前一个状态
public State preState
{
private set;
get;
}

// T 必须是Enum类型
public T GetCurStateId<T>() where T : struct, IConvertible
{
return GetStateId<T>(this.curState);
}

// T 必须是Enum类型
public T GetPreStateId<T>() where T : struct, IConvertible
{
return GetStateId<T>(this.preState);
}

// 获取State的状态id
private static T GetStateId<T>(State state)
{
Type enumType = typeof(T);

if (!enumType.IsEnum)
{
throw new ArgumentException("T must be an enumerated type");
}

int value;

if (state != null)
{
value = Convert.ToInt32(state.id);
}
else
{
value = -1;
}

return (T) Enum.ToObject(enumType, value);
}

// 根据自定义Enum创建State
public State CreateState(Enum stateId)
{
State state        = new State();
state.id           = stateId;
state.stateMachine = this;
this.stateDict.Add(Convert.ToInt32(stateId), state);

return state;
}

// 状态切换
public State SetState(Enum stateId)
{
if (this.curState != null)
{
if (this.curState.OnExit != null)
{
this.curState.OnExit();
}
}

this.preState = this.curState;
this.curState = this.stateDict[Convert.ToInt32(stateId)];

if (this.curState.OnEnter != null)
{
this.curState.OnEnter();
}

return this.curState;
}

// 状态执行
public virtual void Update()
{
if (this.curState != null)
{
if (this.curState.Update != null)
{
this.curState.Update();
}
}
}

// 状态对象
public class State
{
public Enum         id;
public object       userData;
public StateMachine stateMachine;
public Action       OnEnter;
public Action       OnExit ;
public Action       Update ;

public State SetId(Enum id)
{
this.id = id;
return this;
}

public State SetUserData(object userData)
{
this.userData = userData;
return this;
}

public State SetOnEnter(Action OnEnter)
{
this.OnExit = OnEnter;
return this;
}

public State SetOnExit(Action OnExit)
{
this.OnExit = OnExit;
return this;
}

public State SetUpdate(Action Update)
{
this.Update = Update;
return this;
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: