枚举
简单枚举
• 枚举使用enum关键字来声明,与类同级。枚举本身可以有修饰符,但枚举的成员始终是公共的,不能有访问修饰符。枚举本身的修饰符仅能使用public和internal。
• 枚举是值类型,隐式继承自System.Enum,不能手动修改。System.Enum本身是引用类型,继承自System.ValueType。
• 枚举都是隐式密封的,不允许作为基类派生子类。
• 枚举类型的枚举成员均为静态,且默认为Int32类型。
• 每个枚举成员均具有相关联的常数值。此值的类型就是枚举的底层数据类型。每个枚举成员的常数值必须在该枚举的底层数据类型的范围之内。如果没有明确指定底层数据类型则默认的数据类型是int类型。
• 枚举成员不能相同,但枚举的值可以相同。
• 枚举最后一个成员的逗号和大括号后面的分号可以省略
枚举和int的互转
public enum Personstate //先定义一个枚举类型
{
//默认0,1,2,3 一般不会对其进行赋值
EatMeal,
Work,
Sleep,
Chat
}
public class MeiJuTest : MonoBehaviour {
public Personstate state;
void Start () {
state = Personstate.Sleep;
Debug.Log(state);
Debug.Log((int)state); //枚举类型转换成int类型
int a = 3;
Personstate stateConvert = (Personstate)a; //int类型转换成枚举类型
Debug.Log(stateConvert);
}
}
状态机使用
public enum Personstate //先定义一个枚举类型
{
//默认0,1,2,3 一般不会对其进行赋值
EatMeal,
Work,
Sleep,
Chat
}
public class MeiJuTest : MonoBehaviour {
public Personstate mstate = Personstate.EatMeal; //当前帧的状态
private Personstate lastState; //上一帧的状态
void Start() {
}
void Update() {
if (mstate != lastState)
{
Context context = new Context(); //new 一个状态机
IState state = new Sleep1(context); //一个状态 sleep状态
switch (mstate)
{
case Personstate.Work:
state = new Work1(context); break;
case Personstate.Chat:
state = new Chat1(context); break;
case Personstate.Sleep:
state = new Chat1(context); break;
case Personstate.EatMeal:
state = new Chat1(context); break;
default:
break;
}
//当前状态设置到状态机中
context.SetState(state);
context.Handle();
//更新上一帧状态为本帧状态
lastState = mstate;
}
}
}
public interface IState //定义状态的接口
{
void Handle(); //方法是当前状态应该处理的事情
}
public class Context //状态机
{
private IState mState; //当前状态
public void SetState(IState State) //设置当前状态
{
mState = State;
}
public void Handle()
{
mState.Handle(); //执行当前状态下的方法
}
}
public class EatMeal1 : IState
{
//成员变量 状态机属性
//当前状态 所属的管控领导
private Context mContext;
public EatMeal1(Context context)
{
mContext = context;//对当前状态的属性(状态机管理者属性) 进行赋值
}
public void Handle()
{
Debug.Log("当前正在吃饭");
}
}
public class Sleep1 : IState
{
//成员变量 状态机属性
//当前状态 所属的管控领导
private Context mContext;
public Sleep1(Context context)
{
mContext = context;//对当前状态的属性(状态机管理者属性) 进行赋值
}
public void Handle()
{
Debug.Log("当前正在睡觉");
}
}
public class Work1 : IState
{
//成员变量 状态机属性
//当前状态 所属的管控领导
private Context mContext;
public Work1(Context context)
{
mContext = context;//对当前状态的属性(状态机管理者属性) 进行赋值
}
public void Handle()
{
Debug.Log("当前正在工作");
}
}
public class Chat1 : IState
{
//成员变量 状态机属性
//当前状态 所属的管控领导
private Context mContext;
public Chat1(Context context)
{
mContext = context;//对当前状态的属性(状态机管理者属性) 进行赋值
}
public void Handle()
{
Debug.Log("当前正在聊天");
}
}
对象池的用法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class objectPool : MonoBehaviour {
public GameObject Monster; //定义一个怪物模板
private Stack<GameObject> _monsterPool; //定义一个对象池
private Stack<GameObject> _activeMonsterPool; //定义一个当前场景正在使用的 对象池
void Start () {
//实例化一下
_monsterPool = new Stack<GameObject>();
_activeMonsterPool = new Stack<GameObject>();
}
void Update () { //在Update测试一下
if (Input.GetMouseButtonDown(0))
{
GameObject monster = GetMonster(); //调用下面方法 用来得到怪物
monster.transform.position = Vector3.zero; //并且让他的位置处于世界中心
_activeMonsterPool.Push(monster); //得到的这个怪物就把他压栈到 另外一个新的对象池中
}
if (Input.GetMouseButtonDown(1))
{
if (_activeMonsterPool.Count > 0) //说明当前场景中的对象池有怪物
{
//这一步是 调用下面方法 把当前场景对象池中的怪物 出栈 然后压栈到第一个对象池中(回收)
PushGameObjectToPool(_activeMonsterPool.Pop());
}
}
}
private GameObject GetMonster() //封装一个方法 用来得到怪物
{
GameObject monster = null;
if (_monsterPool.Count > 0) //对象池长度大于0 说明池子里有怪物
{
monster = _monsterPool.Pop(); //有怪物 那就让它出栈
monster.SetActive(true); //并且让它显示出来
}else
{
monster = Instantiate(Monster); //否则就说明对象池没有怪物 那就实例化一个
}
return monster;
}
private void PushGameObjectToPool(GameObject monster)
{
monster.transform.SetParent(transform); //回收的对象池就放在 挂此脚本的物体 之下
monster.SetActive(false); //并且不让他显示出来
_monsterPool.Push(monster); //压栈 就是回收
}
}