将Monster变量传递给Battle Controller

时间:2018-08-24 05:25:24

标签: c# unity3d

我正在Unity中制作RPG游戏,而我的战斗系统遇到了一些麻烦。我有一个世界场景,那里有各种各样的怪物,如果玩家与怪物发生碰撞,就会载入战斗场景。我想传递敌方控制器的名称和ID#,以便它可以加载正确的精灵和预制件(战斗场景是通用的)。问题是我的怪物对象(在本例中为GrassSlug)与战斗控制器(战斗场景)位于不同的场景(世界场景)中。如何将这些价值观传达给我的战斗指挥官?我是否需要添加一个不会在加载时被破坏的额外控制器? (我目前有一个像这样的GameManager和一个SkillManager)。

GrassSlug.cs(世界场景中的GameObject)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GrassSlug : Monster {
    private string enemyName = "Grass Slug";
    private int enemyID = 001;
}

Monster.cs(世界场景中的GameObject)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Monster : Character {  
    void OnCollisionEnter2D(Collision2D other)
    {
        if (other.collider.tag == "Player") {
            SceneManager.LoadScene("Battle");
        }
    }
}

BattleController.cs(战斗场景中的GameObject)

using Random = System.Random;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class BattleController : MonoBehaviour {
    private Stat playerHealth;
    private Stat enemyHealth;
    private static Random random = new Random();
    private int playerDamage;
    private int enemyDamage;
    public Button attackButton;
    public Button escapeButton;
    public Transform victoryText;
    public GameObject canvas;
    public GameObject button;
    public Canvas battleUI;

    void Start () {
        InitHealth();
        InitUI();
    }

    // <summary>
    // Init player and enemy health
    // </summary>
    private void InitHealth()
    {
        playerHealth.Initialize(100, 100);
        enemyHealth.Initialize(100, 100);
    }

    // <summary>
    // Set up main battle UI
    // </summary>
    private void InitUI()
    {
        Button AttackButton = attackButton.GetComponent<Button>();
        AttackButton.onClick.AddListener(PlayerAttack);

        Button EscapeButton = escapeButton.GetComponent<Button>();
        EscapeButton.onClick.AddListener(ReturnScene);
    }

    // <summary>
    // Function for the player attack
    // Calculates player's damage and adds XP to the skills
    // </summary>
    private void PlayerAttack () 
    {
        playerDamage = random.Next(20);
        enemyHealth.CurrentValue -= playerDamage;
        GameController.Instance.attackXP += playerDamage;
        GameController.Instance.hitpointsXP += playerDamage;

        if(enemyHealth.CurrentValue <= 0) {
            Victory();
        } else {
            EnemyAttack();
        }
    }

    // <summary>
    // Function for enemy attack
    // Calculates enemy's damage and adds XP to the  players' skills
    // </summary>
    private void EnemyAttack () {
        enemyDamage = random.Next(10);
        playerHealth.CurrentValue -= enemyDamage;
        GameController.Instance.defenceXP += enemyDamage;
        GameController.Instance.SkillDebug();

        if(playerHealth.CurrentValue <= 0) {
            Debug.Log("You are defeated!");
        }
    }

    // <summary>
    // Change UI when player wins the battle
    // </summary>
    private void Victory() {
        Instantiate(victoryText, new Vector3(0, 1.75f, 0), Quaternion.identity);

        GameObject newCanvas = Instantiate(canvas) as GameObject;
        GameObject newButton = Instantiate(button) as GameObject;
        newButton.transform.SetParent(newCanvas.transform, false);

        Button NewButton = newButton.GetComponent<Button>();
        NewButton.onClick.AddListener(ReturnScene);

        battleUI.gameObject.SetActive(false);
    }

    // <summary>
    // Return to the previous screen
    // Note: Currently only supports going back to the "Hometown" scene
    // </summary>
    private void ReturnScene () {
        SceneManager.LoadScene("Hometown");
    }
}

2 个答案:

答案 0 :(得分:1)

您可以创建一个新的Don't Destroy On Load对象来为您保存该信息,也可以仅将这些数据保留在静态字段中。更改场景时不会破坏静态字段。

我想您也可以创建一个ScriptableObject来保留这些数据,但是在我看来,这不是最佳的解决方案。

答案 1 :(得分:0)

一个简单的解决方案是在BattleController中创建一个静态方法和私有静态字段。

public class BattleController : MonoBehaviour {
    private static string enemyName;
    private static int enemyID;

    public static void SetEnemy(string name, int id)
    {
        enemyName = name;
        enemyID = id;
    }
    //other code
}

然后在加载场景之前调用该方法。

public class Monster : Character {  
    void OnCollisionEnter2D(Collision2D other)
    {
        if (other.collider.tag == "Player") {
            BattleController.SetEnemy(enemyName, enemyID)
            SceneManager.LoadScene("Battle");
        }
    }
}

在您的示例中,怪物的名称和ID在GrassSlug类中设置为私有字段,但是对于此解决方案,您需要将它们添加到Monster类中作为受保护的字段,然后在GrassSlug中进行设置。

如果您需要与Battle Controller共享更多信息,则可能希望将Monster实现传递给Battle Controller,而不仅仅是其名称和ID。