点击按钮更改数据

时间:2019-08-05 15:28:03

标签: c# unity3d

我在某些GameObjects中具有一些功能。 在游戏中购买升级时,需要更改这些功能。问题在于每个函数都设置在自己的对象上。

第一个问题是,当我单击按钮时,变量不会更改。如您所见,我已经向按钮添加了onclick值,说明单击按钮时。该值应更改。

Button UI

这里的问题是 “对象引用未设置为实例”

我要面对的第二个问题是每个弹丸都是独立发射的。因此,如果我将静态伤害更改为1,它将不会转移到其他弹丸上。

UpgradeMenu

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();
    }
}

弹丸(DamageScript)

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

//[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;

    [Header ("Layers")]
    public LayerMask solid_layer;
    public LayerMask entities_layer;

    [Header ("OnHit FX")]
    public GameObject HitFxPrefab;
    public GameObject DustFxPrefab;

    [Header ("Bounce")]
    public bool BounceOnCollide = false;
    public int bouncesLeft = 0;

    [HideInInspector]
    public Health owner; // owner of the projectile
    private Vector2 Position; // Current position
    private Vector2 movementCounter = Vector2.zero;  // Counter for subpixel movement
    public BoxCollider2D myCollider; 
    List<Health> healthsDamaged = new List<Health>(); // List to store healths damaged

    void OnCollideWith (Collider2D col, bool horizontalCol = true) {
        var component = col.GetComponent<Health> ();
        // If the target the hitbox collided with has a health component and it is not our owner and it is not on the already on the list of healths damaged by the current hitbox
        if (component != null && component != owner && !healthsDamaged.Contains(component)) {
            // Add the health component to the list of damaged healths
            healthsDamaged.Add (component);

            // Apply the damage
            var didDamage = component.TakeDamage (DamageOnHit);
            // Destroy the projectile after applying damage
            if (didDamage) {
                DestroyMe ();
                return;
            }
        }

        // if the projectile hit's a solid object, destroy it
        if (col.gameObject.layer ==  (int)Mathf.Log(solid_layer.value, 2)) {
            DestroyMeWall ();
            return;
        }
    }

    void OnCollideWithEntity(Collider2D col) {
        var component = col.GetComponent<Health> ();
        // If the target the hitbox collided with has a health component and it is not our owner and it is not on the already on the list of healths damaged by the current hitbox
        if (component != null && component != owner && !healthsDamaged.Contains(component)) {
            // Add the health component to the list of damaged healths
            healthsDamaged.Add (component);

            // Apply the damage
            var didDamage = component.TakeDamage (DamageOnHit);
            // Destroy the projectile after applying damage
            if (didDamage) {
                DestroyMe ();
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

首先,更改

[Header ("Damage")]
public int DamageOnHit;

静态

public static int DamageOnHit = /*your starting value*/;

这可以确保所有弹丸在遭受打击时都受到相同的伤害。
例如,如果您当前在一个场景中有10个弹丸,而DamageOnHit为2,则它们都会造成2点伤害。

没有static,每个射弹将拥有自己的DamageOnHit。这也将我们带入下一个情况:

如果每个弹丸都有自己的DamageOnHit,而我们想修改DamageOnHit,则需要指定要修改的弹丸的伤害。
但是,如果它是静态的,它将变得更加简单,因为所有弹丸都共享相同的DamageOnHit

现在,如果您想更改所有射弹的DamageOnHit,只需

Projectile.DamageOnHit = /*Your new damage value*/

此外,由于您从未在null reference exception中分配projectile,因此您的UpgradeMenu出现了。
(请注意您从未在projectile = /*your projectile*/中做过UpgradeMenu.cs吗?)

默认情况下,该变量将为null。而尝试做null.DamageOnHit += 1毫无道理。

小型编辑:将变量设为静态还意味着您无法将其公开给检查器。但是您可以分配一个初始值,如最初显示的代码。