【发布时间】:2020-10-23 22:26:07
【问题描述】:
我正在制作一个棋盘游戏原型,它有 20 个“方块”,当按下空格键时,敌方角色一次跳一个方块(从 1 到 20)。如果敌人成功阻挡了 20 - 它就是胜利者。
每个方块都有不同的障碍物,敌人可能会被冻结、燃烧、困住、融化、传送等。有些方块可能有多个这些障碍。
我要做的是为每个障碍物创建一个单独的类,并使用.AddComponent<> 将它们添加到不同的块中。当敌人降落在一个方块上时,该方块会穿过该方块上添加的障碍物并相应地惩罚敌人。
这是块预制类:
public class CompositeBlock : MonoBehaviour{
void Start(){
gameObject.AddComponent<ActionFreeze>();
gameObject.AddComponent<ActionTrap>();
}
// This is called when enemy steps on the block
public void ExecuteActions(Enemy enemy){
Debug.Log("Enemy has landed on this block");
IBlockAction[] actionArray = GetComponents<IBlockAction>();
foreach(IBlockAction action in actionArray){
action.Execute(enemy);
}
}
}
以下是可以对敌人执行“动作”的类。现在假设方块只能冻结或困住敌人:
public interface IBlockAction{
void Execute(Enemy enemy);
void OnActionComplete();
}
public class ActionFreeze : MonoBehaviour, IBlockAction{
public void Execute(Enemy enemy){
Debug.Log("Freezing Enemy");
enemy.Freeze(); // Change enemy's sprite to frozen
Invoke("OnActionComplete", 2f); // Wait for 2 seconds
}
public void OnActionComplete(){
Debug.Log("Freeze completed");
}
}
public class ActionTrap : MonoBehaviour, IBlockAction{
public void Execute(Enemy enemy){
Debug.Log("Trapping Enemy");
enemy.Trap(); // Change enemy's sprite to trapped
Invoke("OnActionComplete", 3f); // Wait for 3 seconds
}
public void OnActionComplete(){
Debug.Log("Trap completed");
}
}
这按预期工作,但由于 ExecuteActions 有一个 for 循环,所有操作都会立即执行。敌人的“冰冻”精灵将完全不可见,因为下一个动作会立即执行。日志如下所示:
Enemy has landed on this block
Freezing Enemy
Trapping Enemy
Freeze completed
Trap completed
如何在调用当前动作的OnActionComplete()之后才调用下一个动作的.Execute(),使敌人的“冰冻”精灵显示2秒,然后敌人的精灵变为“被困”,然后显示 3 秒。日志应如下所示:
Enemy has landed on this block
Freezing Enemy
Freeze completed
Trapping Enemy
Trap completed
显示精灵的持续时间(冻结或捕获)并不重要,因为可以播放动画来代替精灵变化。无论敌人(被冻结或被困)状态如何显示 - OnActionComplete() 都应在完成后调用。
【问题讨论】:
-
@Fattie
CompositeBlock最终将成为一个预制件——我当然不会在不先将它们做成预制件的情况下复制/粘贴这 20 个块中的每一个:D。我已经更新了问题,以便更清楚。 -
@Fattie 我认为这非常适合统一。通过这种方式,我可以创建
ActionMelt、ActionTeleport、ActionKill、ActionShrink等类,然后通过执行gameObject.AddComponent<ActionTeleport>()等将它们添加到不同的块预制件中。这些操作将在当敌人落在那个方块上时! -
@Fattie 我认为“freezeEnemy”内部发生的事情无关紧要,因为即使没有调用该方法,日志也会输出相同的日志序列。
-
啊!我想我终于明白 ypiur'e 在问@yeti 什么了!团结起来很容易..
-
请注意,在几乎所有 Unity 项目中,您的
enemy.Trap()几乎肯定是协程。任何需要时间的东西都是协程!顺便说一句,您可能会喜欢使用 Tweengb> 这是一个简单的扩展。它在很大程度上消除了几乎所有简单的动画(音频、位置等)stackoverflow.com/a/37228628/294884
标签: unity3d