C# 团结一致的承诺
我想要一个角色类,从MonoBehavior继承并公开大量的方法:Walk、Attack 但是,假设两个组件同时使用这些方法,我希望对操作进行排队,并通过某种方式通知组件它们的操作已经执行 在Javascript标准中,我会这样做:C# 团结一致的承诺,c#,unity3d,unityscript,C#,Unity3d,Unityscript,我想要一个角色类,从MonoBehavior继承并公开大量的方法:Walk、Attack 但是,假设两个组件同时使用这些方法,我希望对操作进行排队,并通过某种方式通知组件它们的操作已经执行 在Javascript标准中,我会这样做: var Character = function ( ) { this._deferred = new Deferred( ); }; Character.prototype.walk = function ( ) { return this._d
var Character = function ( ) {
this._deferred = new Deferred( );
};
Character.prototype.walk = function ( ) {
return this._deferred = this._deferred.then( function ( ) {
// Do the actual walk
} );
};
Character.prototype.attack = function ( ) {
return this._deferred = this._deferred.then( function ( ) {
// Do the actual attack
} );
};
var character = new Character( );
// Component A
character.walk( ).then( function ( ) {
// Executes when the walk is done
} );
// Component B
character.attack( ).then( function ( ) {
// Executes when the walk AND attack is done
} );
使用Unity/C#的正确方法是什么?序言
Queue
。唯一的问题是使用什么作为TCommand。这里我给你举两个例子。但是,像往常一样,还有更多的选择
某类
大概是这样的:
public enum CommandUpdateResult
{
Ongoing,
Finished
}
public interface ICommand
{
CommandUpdateResult Update();
}
public class RunCommand: ICommand
{
// Bla-bla-bla
}
public class AttackCommand: ICommand
{
// Bla-bla-bla
}
public class Character: MonoBehaviour
{
private Queue<ICommand> commandQueue;
public void Awake()
{
commandQueue = new Queue<ICommand>();
}
public void Update()
{
if (commandQueue.Count > 0 && commandQueue.Peek().Update() == CommandUpdateResult.Finished)
commandQueue.Dequeue();
}
public void EnqueueCommand(ICommand command)
{
commandQueue.Enqueue(command);
}
}
public class SomeClassThatUsesCharacter
{
private Character character;
public void SomeMethodThatUsesCharacter()
{
character.EnqueueCommand(new RunCommand(bla-bla-bla));
character.EnqueueCommand(new AttackCommand(bla-bla-bla));
}
}
public enum CommandUpdateResult
{
不间断的
完成了
}
公共接口ICommand
{
CommandUpdateResult Update();
}
公共类RunCommand:ICommand
{
//呜呜呜呜
}
公共类攻击命令:ICommand
{
//呜呜呜呜
}
公共阶级特征:单一行为
{
专用队列命令队列;
公共图书馆
{
commandQueue=新队列();
}
公共无效更新()
{
if(commandQueue.Count>0&&commandQueue.Peek().Update()==CommandUpdateResult.Finished)
commandQueue.Dequeue();
}
public void排队命令(ICommand命令)
{
命令队列。排队(命令);
}
}
public类使用schracter的类
{
个性;
使用schracter()的公共void方法
{
character.EnqueueCommand(newrunCommand(blablabla));
character.EnqueueCommand(新攻击命令(blablabla));
}
}
迭代器
使用IEnumerator最简单(但不是很优雅)的方法是将它与一些无限元素一起使用
公共类字符:单行为
{
专用队列命令队列;
私有IEnumerator命令QueueCoroutine()
{
while(true)
{
如果(commandQueue.Count>0)
产生返回start例程(commandQueue.Peek());
其他的
返回新的WaitForFixedUpdate();
}
}
公共图书馆
{
commandQueue=新队列();
start例程(CommandQueueCoroutine());
}
公共无效更新()
{
if(commandQueue.Count>0&&commandQueue.Peek().Update()==CommandUpdateResult.Finished)
commandQueue.Dequeue();
}
公共void排队(IEnumerator命令)
{
命令队列。排队(命令);
}
IEnumerator运行命令()
{
而(Jenny.Tells(“Run”))
{
transform.position.x+=1;
返回新的WaitForFixedUpdate();
}
}
IEnumerator攻击命令(恶棍恶棍)
{
坏人。死();
屈服断裂;
}
}
public类使用schracter的类
{
个性;
使用schracter()的公共void方法
{
character.Enqueue(character.RunCommand());
character.Enqueue(character.AttackCommand(someBadGuy));
}
}
一个非常好的Unity Promise库:请参阅相关博客
或者,我认为您也可以使用观察者对
Walk
和Attack
事件做出反应的接收方法。见不清楚。您是否希望在C#中实现承诺?或者您想要一种将角色的命令排队的方法吗?回答“两者”意味着你试图用错误的仪器来解决问题。看看行动,功能,也许delegate@SergeyKrusch我的问题是关于连锁指挥的“统一方式”。在Javascript中,我可能会使用承诺之类的东西,但在统一世界中,这可能是错误的。
public class Character: MonoBehaviour
{
private Queue<IEnumerator> commandQueue;
private IEnumerator CommandQueueCoroutine()
{
while (true)
{
if (commandQueue.Count > 0)
yield return StartCoroutine(commandQueue.Peek());
else
yield return new WaitForFixedUpdate();
}
}
public void Awake()
{
commandQueue = new Queue<ICommand>();
StartCoroutine(CommandQueueCoroutine());
}
public void Update()
{
if (commandQueue.Count > 0 && commandQueue.Peek().Update() == CommandUpdateResult.Finished)
commandQueue.Dequeue();
}
public void Enqueue(IEnumerator command)
{
commandQueue.Enqueue(command);
}
IEnumerator RunCommand()
{
while (Jenny.Tells("Run"))
{
transform.position.x += 1;
yield return new WaitForFixedUpdate();
}
}
IEnumerator AttackCommand(BadGuy badGuy)
{
badGuy.Die();
yield break;
}
}
public class SomeClassThatUsesCharacter
{
private Character character;
public void SomeMethodThatUsesCharacter()
{
character.Enqueue(character.RunCommand());
character.Enqueue(character.AttackCommand(someBadGuy));
}
}