我有一些脚本,这些脚本分为播放器和播放器下面的游戏对象。这些脚本包括准确性,玩家速度和弹丸伤害。
我创建了一个菜单,玩家(与NPC互动时)可以购买某些升级产品,以在整个游戏中增加这些价值。
现在我想知道,将所有这些脚本转换为1个脚本并对其进行访问是否更好?还是让它在脚本之间划分并单独调用它们更好?
由于这是我第一次升级玩家数据,因此欢迎您提供任何帮助!
让我们从最大运行速度的播放器脚本开始。
public class Player : Actor {
public int playerNumber = 1;
// Run Speed & Acceleration
public float MaxRun = 90f; // Maximun Horizontal Run Speed
public float RunAccel = 1000f; // Horizontal Acceleration Speed
public float RunReduce = 400f; // Horizontal Acceleration when you're already when your horizontal speed is higher or equal to the maximum
我拥有的第二个脚本是在武器本身中,我具有武器的准确性。
public class Weapon : MonoBehaviour {
protected float currentAngle = 0f;
public float randomAngle = 20;
最后一个脚本是我放置伤害的地方。由于损坏在弹丸之内,因此我将所有内容都放入了弹丸脚本中。
//[RequireComponent (typeof(Rigidbody2D))]
public class Projectile : MonoBehaviour {
[Header ("Speed")]
public float baseSpeed;
public float randomSpeed;
public Vector2 SpeedV2;
public Vector2 Direction;
[Header ("Damage")]
public int DamageOnHit;
为了将所有内容都放入我的“升级”菜单中,我制作了一个脚本,调用了不同的脚本。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UpgradeMenu : MonoBehaviour
{
[SerializeField]
private Text accuracyText;
[SerializeField]
private Text speedText;
[SerializeField]
private Text damageText;
[SerializeField]
private float accuracyMultiplier = 0.7f;
private Weapon weapon;
private Projectile projectile;
private Player player;
void OnEnable()
{
UpdateValues();
}
void UpdateValues ()
{
accuracyText.text = weapon.randomAngle.ToString();
damageText.text = projectile.DamageOnHit.ToString();
speedText.text = player.MaxRun.ToString();
}
public void UpgradeAccuracy ()
{
weapon.randomAngle = (int)weapon.randomAngle * accuracyMultiplier;
UpdateValues();
}
public void UpgradeDamage ()
{
projectile.DamageOnHit = (int)projectile.DamageOnHit + 1;
UpdateValues();
}
}
我很确定我试图在UpgradeMenu脚本中调用其他脚本的方式是错误的。因此,如果有人能够提供帮助,那就太好了!
您可以看到机枪是玩家的子弹。因为您能够拿起该物品。这已经引起了枪支问题。由于我可以在Unity内更改此值,但是当我拿起另一把机枪时,该值将恢复为通常的4值。
除此之外,我还有一个具有onclick值的按钮。这个想法是,当玩家单击此按钮(仍然需要更改UI)时,应该使用此UpgradeMenu脚本来更改值。
现在按钮可以正常工作,唯一的问题是升级功能“未设置为对象的实例”
答案 0 :(得分:1)
您应该区分配置数据和逻辑数据。
逻辑数据是唯一的,仅存在于某些对象实例中,而配置数据存在于数据库中并由id
标识。
以下仅是演示此想法的示例代码。
数据:
public class WeaponData
{
public string id;
public float spread;
public string projectileId;
}
public class ProjectileData
{
public string id;
public int damage;
public string prefabPath;
}
图书馆:
public static class Library
{
public static Dictionary<string, WeaponData> Weapons;
public static Dictionary<string, ProjectileData> Projectiles;
// add more ...
}
配置设置:
WeaponData weapon = new WeaponData
{
id = "shotgun",
spread = 20f,
projectileId = "shotgun_shell"
};
ProjectileData projectile = new ProjectileData
{
id = "shotgun_shell",
damage = 100,
prefabPath = "Projectiles/ShotgunShell"
};
Library.Weapons.Add(weapon.id, weapon);
Library.Weapons.Add(projectile.id, projectile);
逻辑:
public class Weapon
{
public WeaponData weapon = Library.Weapons["shotgun"];
public void Shoot()
{
GameObject.Instantiate(
Resources.Load<Projectile>(Library.Projectiles[weapon.projectileId].prefabPath)
);
}
}
要使升级系统正常工作,您可以设置多种武器:
"shotgun_v1"
-> "shotgun_v2"
-> "shotgun_v3"
注意:另一种方法是使用ScriptableObjects,即如果您想在Unity编辑器中序列化数据。在该主题上酷video。
答案 1 :(得分:0)
我相信您的问题出在您要在不是静态属性的类类型上设置randomAngle的地方:
public void UpgradeAccuracy ()
{
Weapon.randomAngle = (int)Weapon.randomAngle * accuracyMultiplier;
UpdateValues();
}
这里的Weapon
是什么?只是一个类名,您无法设置或获取这些东西,因为它没有实例化。我相信您想做的是:
public void UpgradeAccuracy ()
{
angle.randomAngle = (int)angle.randomAngle * accuracyMultiplier;
UpdateValues();
}
除此之外,您所做的可能并没有多大错误。可能不是我选择的体系结构,但我还没有看完您的整个游戏,因此可能有您选择的理由。未来的提示是,并非所有内容都必须是组件(源自MonoBehaviour),如果不需要组件行为,则在Unity中创建游戏时也可以使用“普通”类。我通常会尝试保持尽可能少的MonoBehaviour组件脚本。