Unity 中 C# 脚本的问题
Problems with C# script in Unity
如何缩短它?我想我可能是一个数组,但我不知道如何设置它。这是代码,这是当你获得一定数量的金币时需要做的事情:它增加 10 的健康并保存健康,然后它改变显示下一次升级需要多少金币的文本。
void HpUpgradelvl()
{
if (PlayerControl.coins >= 30)
{
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 60)
{
txt.SetActive(false);
txt1.SetActive(true);
txt2_0.SetActive(false);
txt2_1.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 100)
{
txt1.SetActive(false);
txt2.SetActive(true);
txt2_1.SetActive(false);
txt2_2.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 150)
{
txt2.SetActive(false);
txt3.SetActive(true);
txt2_2.SetActive(false);
txt2_3.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 210)
{
txt3.SetActive(false);
txt4.SetActive(true);
txt2_3.SetActive(false);
txt2_4.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 280)
{
txt4.SetActive(false);
txt5.SetActive(true);
txt2_4.SetActive(false);
txt2_5.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 360)
{
txt5.SetActive(false);
txt6.SetActive(true);
txt2_5.SetActive(false);
txt2_6.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 450)
{
txt6.SetActive(false);
txt7.SetActive(true);
txt2_6.SetActive(false);
txt2_7.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 500)
{
txt7.SetActive(false);
txt8.SetActive(true);
txt2_7.SetActive(false);
txt2_8.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 610)
{
txt8.SetActive(false);
txt9.SetActive(true);
txt2_8.SetActive(false);
txt2_9.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 730)
{
txt9.SetActive(false);
txt10.SetActive(true);
txt2_9.SetActive(false);
txt2_10.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 860)
{
txt10.SetActive(false);
txt11.SetActive(true);
txt2_10.SetActive(false);
txt2_11.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 1000)
{
txt11.SetActive(false);
txtmax.SetActive(true);
imgmax.SetActive(false);
txt2_11.SetActive(false);
txtmax2.SetActive(true);
imgmax2.SetActive(false);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
}
}
}
}
}
}
}
}
}
}
}
}
}
else healthPoints = 100;
}
有几种不同的方法来处理这个问题,但也许最简单的方法是从一个带有阈值的数组开始(确保它按从小到大的顺序排列):
var thresholds = new int[] { 30,60,100,150,210,...};
然后您可以循环遍历您的数组,而不是那组可怕的 if
嵌套:
int i = 0;
while (PlayerControl.coins < thresholds[i++])
{
healthpoints += 10;
}
我发现您设置的等级要求(至少达到 450)遵循一定的模式。每个级别的要求总是增加 10。我认为这是管理 XP 要求的简单但有效的方法。
这种模式的优点之一是,它可以用二次函数表示。所以我写了一个生成和求解这样一个二次函数的方法。
您向它提供基本功能参数(基础、增长)和当前点数(在本例中为黄金),它 returns 玩家达到的等级。
举个例子,我在下面的常量中设置的值几乎符合您首先列出的要求。他们是:
- 30
- 70
- 130
- 200
- 280...
我还使用了 属性 来使 HP 与 PlayerPrefs 保持同步。您可以在此处添加一个支持变量,以防止一直读取 PlayerPrefs。
public class HpManager : MonoBehaviour
{
public int HealthPoints
{
get
{
PlayerPrefs.GetFloat("HealthUP")
}
set
{
PlayerPrefs.SetFloat("HealthUP", value);
}
}
private const uint BASE_HEALTH_POINTS = 100; // Your HP for level 0
private const uint HEALTH_POINTS_PER_LEVEL = 10; // The amount the HP increase with each level
private const uint BASE_LEVEL_REQUIREMENT = 30; // The gold required to reach level 1
private const uint PER_LEVEL_INCREASE = 10; // The amount the level up requirement increases with every level
private const uint MAX_LEVEL = 99;
private void Start()
{
HealthPoints = BASE_HEALTH_POINTS; // Set a base value for your HP
}
void HpUpgradelvl()
{
int level = GetLevel((uint)PlayerControl.coins, BASE_LEVEL_REQUIREMENT, PER_LEVEL_INCREASE);
level = Mathf.Clamp(0, MAX_LEVEL);
HealthPoints = BASE_HEALTH_POINTS + level * HEALTH_POINTS_PER_LEVEL;
}
private int GetLevel(uint points, uint baseRequirement, uint increaseRequirement)
{
float a = 0.5f * increaseRequirement;
float b = baseRequirement - a;
// Convert quadratic equation "l = ax² + bx" into normalized form "0 = x² + px + q"
float p = b / a;
float q = -points / a; // Bring across and normalize
float level = -p / 2f + Mathf.Sqrt((p * p) / 4f - q); // Solve for positive value
return Mathf.FloorToInt(level); // Return reached level
}
}
我需要更多信息来帮助您处理文本。
照原样,它似乎过于复杂。我无法想象您实际上需要所有这些单独的文本对象。
你到底想在这里做什么?
如何缩短它?我想我可能是一个数组,但我不知道如何设置它。这是代码,这是当你获得一定数量的金币时需要做的事情:它增加 10 的健康并保存健康,然后它改变显示下一次升级需要多少金币的文本。
void HpUpgradelvl()
{
if (PlayerControl.coins >= 30)
{
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 60)
{
txt.SetActive(false);
txt1.SetActive(true);
txt2_0.SetActive(false);
txt2_1.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 100)
{
txt1.SetActive(false);
txt2.SetActive(true);
txt2_1.SetActive(false);
txt2_2.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 150)
{
txt2.SetActive(false);
txt3.SetActive(true);
txt2_2.SetActive(false);
txt2_3.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 210)
{
txt3.SetActive(false);
txt4.SetActive(true);
txt2_3.SetActive(false);
txt2_4.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 280)
{
txt4.SetActive(false);
txt5.SetActive(true);
txt2_4.SetActive(false);
txt2_5.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 360)
{
txt5.SetActive(false);
txt6.SetActive(true);
txt2_5.SetActive(false);
txt2_6.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 450)
{
txt6.SetActive(false);
txt7.SetActive(true);
txt2_6.SetActive(false);
txt2_7.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 500)
{
txt7.SetActive(false);
txt8.SetActive(true);
txt2_7.SetActive(false);
txt2_8.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 610)
{
txt8.SetActive(false);
txt9.SetActive(true);
txt2_8.SetActive(false);
txt2_9.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 730)
{
txt9.SetActive(false);
txt10.SetActive(true);
txt2_9.SetActive(false);
txt2_10.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 860)
{
txt10.SetActive(false);
txt11.SetActive(true);
txt2_10.SetActive(false);
txt2_11.SetActive(true);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
if (PlayerControl.coins >= 1000)
{
txt11.SetActive(false);
txtmax.SetActive(true);
imgmax.SetActive(false);
txt2_11.SetActive(false);
txtmax2.SetActive(true);
imgmax2.SetActive(false);
healthPoints = healthPoints + 10;
PlayerPrefs.SetFloat("HealthUP", healthPoints);
}
}
}
}
}
}
}
}
}
}
}
}
}
else healthPoints = 100;
}
有几种不同的方法来处理这个问题,但也许最简单的方法是从一个带有阈值的数组开始(确保它按从小到大的顺序排列):
var thresholds = new int[] { 30,60,100,150,210,...};
然后您可以循环遍历您的数组,而不是那组可怕的 if
嵌套:
int i = 0;
while (PlayerControl.coins < thresholds[i++])
{
healthpoints += 10;
}
我发现您设置的等级要求(至少达到 450)遵循一定的模式。每个级别的要求总是增加 10。我认为这是管理 XP 要求的简单但有效的方法。
这种模式的优点之一是,它可以用二次函数表示。所以我写了一个生成和求解这样一个二次函数的方法。
您向它提供基本功能参数(基础、增长)和当前点数(在本例中为黄金),它 returns 玩家达到的等级。
举个例子,我在下面的常量中设置的值几乎符合您首先列出的要求。他们是:
- 30
- 70
- 130
- 200
- 280...
我还使用了 属性 来使 HP 与 PlayerPrefs 保持同步。您可以在此处添加一个支持变量,以防止一直读取 PlayerPrefs。
public class HpManager : MonoBehaviour
{
public int HealthPoints
{
get
{
PlayerPrefs.GetFloat("HealthUP")
}
set
{
PlayerPrefs.SetFloat("HealthUP", value);
}
}
private const uint BASE_HEALTH_POINTS = 100; // Your HP for level 0
private const uint HEALTH_POINTS_PER_LEVEL = 10; // The amount the HP increase with each level
private const uint BASE_LEVEL_REQUIREMENT = 30; // The gold required to reach level 1
private const uint PER_LEVEL_INCREASE = 10; // The amount the level up requirement increases with every level
private const uint MAX_LEVEL = 99;
private void Start()
{
HealthPoints = BASE_HEALTH_POINTS; // Set a base value for your HP
}
void HpUpgradelvl()
{
int level = GetLevel((uint)PlayerControl.coins, BASE_LEVEL_REQUIREMENT, PER_LEVEL_INCREASE);
level = Mathf.Clamp(0, MAX_LEVEL);
HealthPoints = BASE_HEALTH_POINTS + level * HEALTH_POINTS_PER_LEVEL;
}
private int GetLevel(uint points, uint baseRequirement, uint increaseRequirement)
{
float a = 0.5f * increaseRequirement;
float b = baseRequirement - a;
// Convert quadratic equation "l = ax² + bx" into normalized form "0 = x² + px + q"
float p = b / a;
float q = -points / a; // Bring across and normalize
float level = -p / 2f + Mathf.Sqrt((p * p) / 4f - q); // Solve for positive value
return Mathf.FloorToInt(level); // Return reached level
}
}
我需要更多信息来帮助您处理文本。
照原样,它似乎过于复杂。我无法想象您实际上需要所有这些单独的文本对象。
你到底想在这里做什么?