我正在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");
}
}
答案 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。