Unity多线程修改主线程的问题解决方案 有限状态机相关理解

今天在项目中研究了下状态机 又问了同事 对状态机油有了更深的理解

突然想到之前Unity中主线程的UI界面的时候 比如说在线程 B 中修改了主线程 A 中的按钮上的文字 那么就会出错
既然不让访问 那么就可以转移到主线程某个cs文件中Update中做手脚
比如:主线程A
Update()
{
if(1 == state)//state默认值是0
{
if(1 == actor)
修改按钮文字
if(2 == actor)
修改按钮颜色
if(3 == actor)
修改按钮大小
...

}
if(2 == state)//state默认值是0
{
if(1 == actor)
修改图片文字
if(2 == actor)
修改图片颜色
if(3 == actor)
修改图片大小
...

}
}
线程B
...
xx.state = 1;
...

这样就能够修改主线程的东西了
但是这样会出现问题
执行一个操作就要在这里创个状态变量 然后在update用来判断是否执行了该操作 多了的话很不好管理
在了解状态机之后 可以大概这么改 将每个状态分成几个模块 然后再判断动作 这样能避免状态多的时候不好管理的问题
(动作依然是这样判断 个人认为 动作可变性比较大 所以没有进行判断更改)
主线程A:
FSM.cs
enum State
{
A_STATE,
B_STATE,
C_STATE
}
enum Actor
{
A_Actor,
B_Actor,
C_Actor
}
State currState  //当前状态
Map FSMMap//这里FSM是各模块状态机的父类 FSM中有Handle函数
List list //用来动作


public Update()
{
if(list > 0)
{


  FSMMap.GetValue(currState).Handle(list[0]);
  Handle.remove(0)
}


}
public ChangeState(state , actor)
{
currState = state
list.add(actor)


}


A_FSM.cs


Handle(actor)
{
  if(actor == A_Actor)
  执行A动作
   if(actor == B_Actor)
  执行B动作
  .. 
  ..

}
B_FSM.cs


Handle(actor)
{
  if(actor == A_Actor)
  执行A动作
   if(actor == B_Actor)
  执行B动作
  .. 
  ..

}
C_FSM.cs
...




线程B:


...


xx.currState = State.A_State
...


...
xx.list.add(Actor.B_Actor)
...
...


上述代码只是真正项目中的思想 代码方面只是演示下思想 什么封装性,,容错性,,都不要在意 重点是这个思想看懂了  实现起来就容易了
顺便说一下 之前是用在Lua中的  我只不过尽量的向cs方面写 不过目测实现起来很容易

之前用Photon服务器的时候我恨纳闷一个问题 为什么他这个收到服务器消息后改变主线程界面为什么好使
而我用底层Socket实现的时候直接修改主线程界面却不好使
然后我发现Photon中有一句代码在Update里(或者是Invoke 协程 总之是主线程中的)
有个 peer.Service() 不断地与服务器交互  这样就是相当于在主线程与服务器交互 就能够避免上述问题

你可能感兴趣的:(FSM)