【问题标题】:Looking for ways to implement powerups寻找实现通电的方法
【发布时间】:2019-09-24 08:09:53
【问题描述】:

我正在尝试在我的游戏中实现一个通电系统,但不知道如何实现它。到目前为止,我有一个 powerup spawner,它在随机位置实例化一个 powerup 预制件。一旦被捡起,它就会自我毁灭并在另一个位置生成。所有权力都使用同一个预制件,并且一次在地图上只有一个。

spawnLocations = GameObject.FindGameObjectsWithTag("spawnLocation");
Instantiate(powerup, spawnLocations[spawnRandom].transform.position, transform.rotation);

至于通电,在拾取时应该移除当前的通电(如果玩家有)并用随机选择的新通电替换它。 (不需要计时器)。

我做了几个简单的通电:

public void SpeeedBoost(float speedMultiplied) {
    var playerController = gameObject.GetComponent<PlayerController>();
    playerController.speed = playerController.speed * speedMultiplied;
}

public void JumpBoost(float jumpPower) {
    var playerJump = gameObject.GetComponent<PlayerJump>();
    playerJump.jumpSpeed = playerJump.jumpSpeed * jumpPower;
}

+ 可能换个武器等等。

他们应该这样称呼:

private void OnTriggerEnter2D(Collider2D collision) {
    if (collision.gameObject.tag == "powerup") {
        // Remove current powerup and call a new random one
    }
}

所以我需要一些帮助。我应该如何构建我的通电?我如何随机调用它们?考虑可能以某种方式使用 unityEvent 。或者也许将每个通电保存为带有自己脚本的预制件并交换它们(虽然感觉有点乱)。

我在这里有点迷路,任何建议/示例都表示赞赏。 :)

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    你可以列举 powerUps

    public enum PowerUp
    {
        None, //default value
        SpeedBoost,
        JumpBoost,
        //etc
    }    
    

    然后创建对当前活动powerUp的引用

    private PowerUp currentPowerUp;
    

    这样之后,我们可以在分配新值之前撤消它的效果

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "powerup")
        {
            switch (currentPowerUp)
            {
                case PowerUp.JumpBoost:
                    RemoveJumpBoost();
                    break;
                case PowerUp.SpeedBoost:
                    RemoveSpeedBoost();
                    break;
            }
    
            do
            {
                //I set the minimum value to 1 to skip "None"
                var nextPowerUp = (PowerUp)UnityEngine.Random.Range(1, System.Enum.GetValues(typeof(PowerUp)).Length);
            }
            while (nextPowerUp == currentPowerUp);
    
            switch (nextPowerUp)
            {
                case PowerUp.JumpBoost:
                    AddJumpBoost();
                    break;
                case PowerUp.SpeedBoost:
                    AddSpeedBoost();
                    break;
            }
    
            currentPowerUp = nextPowerUp;
        }
    }
    

    或者您也可以在 powerUp 预制件中添加一个脚本,在其中指定上述 powerUp 枚举值,或者甚至在 OnDestroy 事件中声明要做什么。或者,您可以为每种 powerUp 类型创建一个预制件,并在决定实例化哪一个之前调用随机生成。由您来决定哪种解决方案看起来最干净、最容易理解,它们都是完全有效的

    【讨论】:

    • 谢谢!如果您希望每次上电都不同,就像 currentPowerUp != nextPowerUp 一样,您会添加某种 while 循环来检查吗?
    • @qua1ity 我添加了一个 while 循环以确保它检索到非重复值。考虑到如果您没有定义至少 2 个 powerUps,您可能会创建一个无限循环
    【解决方案2】:

    我认为您可以将 ScriptAbleObjects 用于您的 PowerUps。它将引用它生成的预制件。为了使其随机化,我会将它们存储在一个列表中并计算一个随机索引以检索随机加电。

    public class PowerUpObject : ScriptAbleObject
    {
        public GameObject Prefab;
    } 
    
    public class PowerUpManager : Monobehaviour
    {
        public List<PowerUpObject> PowerUps;
    
        public PowerUp GetRandomPowerUp()
        {
            if(PowerUps != null && PowerUps.Count > 0)
            {
                int randomIdx = Random.Range(0, PowerUps.Count);
                return PowerUps[randomIdx];
            }
    
            // error case
            Debug.Log("No PowerUps in List");
            return null;
        }
    }
    

    这并不完整,但应该会给您所需的灵感。 您将有一个经理 GameObject 持有游戏中所有已知的 powerUps。您可以从它请求随机加电,然后使用 PowerUpObject 的 Prefab 成员生成实际的 Prefab。

    我也推荐这个视频: https://www.youtube.com/watch?v=CLSiRf_OrBk

    【讨论】:

      猜你喜欢
      • 2021-10-17
      • 2011-04-01
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多