c# - 访问另一个脚本变量,但不能更改游戏内
问题描述
我是 Unity 的新手。我遵循了一个教程并遵循了他所做的一切。玩家默认有 3 条生命(您可以在页面底部的健康脚本中看到。)我想要显示玩家剩余多少条生命的游戏内文本。
首先,我创建了一个 Text 并在其中创建了新的LivesDisplay脚本。然后我访问 Health Script(这是 Player 对象组件)并在 LivesDisplay 脚本中获取 currentLives 变量。
LivesDisplay 脚本
public class LivesDisplay : MonoBehaviour
{
[SerializeField] Text livesText;
int remainingLives;
private void Start()
{
remainingLives = GameObject.FindWithTag("Player").GetComponent<Health>().currentLives;
Debug.Log("Entered Start Method");
}
void Update()
{
livesText.text = "Lives : " + (remainingLives).ToString();
Debug.Log("Entered Update Method");
}
}
当我开始游戏时,默认变量正确显示,如您所见。
当玩家在游戏中击中时,这个生命变量应该减少,但不会发生。我已经检查过游戏可能没有进入 LivesDisplay 脚本,但是当你看到控制台时,一切似乎都很正常。
奇怪的是,这段代码昨天运行良好,但今天却不行。我也把 Health 脚本留在这里,也许问题源在这里,但我没有写这个脚本。我只是将这个脚本拖放到教程中,没有改变任何东西(除了让一些变量对公共私有。)
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
/// <summary>
/// This class handles the health state of a game object.
///
/// Implementation Notes: 2D Rigidbodies must be set to never sleep for this to interact with trigger stay damage
/// </summary>
public class Health : MonoBehaviour
{
[Header("Team Settings")]
[Tooltip("The team associated with this damage")]
public int teamId = 0;
[Header("Health Settings")]
[Tooltip("The default health value")]
public int defaultHealth = 1;
[Tooltip("The maximum health value")]
public int maximumHealth = 1;
[Tooltip("The current in game health value")]
public int currentHealth = 1;
[Tooltip("Invulnerability duration, in seconds, after taking damage")]
public float invincibilityTime = 3f;
[Tooltip("Whether or not this health is always invincible")]
public bool isAlwaysInvincible = false;
[Header("Lives settings")]
[Tooltip("Whether or not to use lives")]
public bool useLives = false;
[Tooltip("Current number of lives this health has")]
public int currentLives = 3;
[Tooltip("The maximum number of lives this health can have")]
public int maximumLives = 5;
/// <summary>
/// Description:
/// Standard unity funciton called before the first frame update
/// Inputs:
/// none
/// Returns:
/// void (no return)
/// </summary>
void Start()
{
SetRespawnPoint(transform.position);
}
/// <summary>
/// Description:
/// Standard Unity function called once per frame
/// Inputs:
/// none
/// Returns:
/// void (no return)
/// </summary>
void Update()
{
InvincibilityCheck();
}
// The specific game time when the health can be damged again
private float timeToBecomeDamagableAgain = 0;
// Whether or not the health is invincible
private bool isInvincableFromDamage = false;
/// <summary>
/// Description:
/// Checks against the current time and the time when the health can be damaged again.
/// Removes invicibility if the time frame has passed
/// Inputs:
/// None
/// Returns:
/// void (no return)
/// </summary>
private void InvincibilityCheck()
{
if (timeToBecomeDamagableAgain <= Time.time)
{
isInvincableFromDamage = false;
}
}
// The position that the health's gameobject will respawn at if lives are being used
private Vector3 respawnPosition;
/// <summary>
/// Description:
/// Changes the respawn position to a new position
/// Inputs:
/// Vector3 newRespawnPosition
/// Returns:
/// void (no return)
/// </summary>
/// <param name="newRespawnPosition">The new position to respawn at</param>
public void SetRespawnPoint(Vector3 newRespawnPosition)
{
respawnPosition = newRespawnPosition;
}
/// <summary>
/// Description:
/// Repositions the health's game object to the respawn position and resets the health to the default value
/// Inputs:
/// None
/// Returns:
/// void (no return)
/// </summary>
void Respawn()
{
transform.position = respawnPosition;
currentHealth = defaultHealth;
}
/// <summary>
/// Description:
/// Applies damage to the health unless the health is invincible.
/// Inputs:
/// int damageAmount
/// Returns:
/// void (no return)
/// </summary>
/// <param name="damageAmount">The amount of damage to take</param>
public void TakeDamage(int damageAmount)
{
if (isInvincableFromDamage || isAlwaysInvincible)
{
return;
}
else
{
if (hitEffect != null)
{
Instantiate(hitEffect, transform.position, transform.rotation, null);
}
timeToBecomeDamagableAgain = Time.time + invincibilityTime;
isInvincableFromDamage = true;
currentHealth -= damageAmount;
CheckDeath();
}
}
/// <summary>
/// Description:
/// Applies healing to the health, capped out at the maximum health.
/// Inputs:
/// int healingAmount
/// Returns:
/// void (no return)
/// </summary>
/// <param name="healingAmount">How much healing to apply</param>
public void ReceiveHealing(int healingAmount)
{
currentHealth += healingAmount;
if (currentHealth > maximumHealth)
{
currentHealth = maximumHealth;
}
CheckDeath();
}
[Header("Effects & Polish")]
[Tooltip("The effect to create when this health dies")]
public GameObject deathEffect;
[Tooltip("The effect to create when this health is damaged")]
public GameObject hitEffect;
/// <summary>
/// Description:
/// Checks if the health is dead or not. If it is, true is returned, false otherwise.
/// Calls Die() if the health is dead.
/// Inputs:
/// none
/// Returns:
/// bool
/// </summary>
/// <returns>Bool: true or false value representing if the health has died or not (true for dead)</returns>
bool CheckDeath()
{
if (currentHealth <= 0)
{
Die();
return true;
}
return false;
}
/// <summary>
/// Description:
/// Handles the death of the health. If a death effect is set, it is created. If lives are being used, the health is respawned.
/// If lives are not being used or the lives are 0 then the health's game object is destroyed.
/// Inputs:
/// none
/// Returns:
/// void (no return)
/// </summary>
public void Die()
{
if (deathEffect != null)
{
Instantiate(deathEffect, transform.position, transform.rotation, null);
}
if (useLives)
{
HandleDeathWithLives();
}
else
{
HandleDeathWithoutLives();
}
}
/// <summary>
/// Description:
/// Handles the death of the health when lives are being used
/// Inputs:
/// none
/// Returns:
/// void (no return)
/// </summary>
void HandleDeathWithLives()
{
currentLives -= 1;
if (currentLives > 0)
{
Respawn();
}
else
{
if (gameObject.tag == "Player" && GameManager.instance != null)
{
GameManager.instance.GameOver();
}
if (gameObject.GetComponent<Enemy>() != null)
{
gameObject.GetComponent<Enemy>().DoBeforeDestroy();
}
Destroy(this.gameObject);
}
}
/// <summary>
/// Description:
/// Handles death when lives are not being used
/// Inputs:
/// none
/// Returns:
/// void (no return)
/// </summary>
void HandleDeathWithoutLives()
{
if (gameObject.tag == "Player" && GameManager.instance != null)
{
GameManager.instance.GameOver();
}
if (gameObject.GetComponent<Enemy>() != null)
{
gameObject.GetComponent<Enemy>().DoBeforeDestroy();
}
Destroy(this.gameObject);
}
}
我正在使用 Unity 版本 2020.2.7f1。
谢谢阅读。
解决方案
您仅在 start 方法中检查 currentLives,该方法仅在脚本启动时调用一次。因此该值不会更新,您必须在更新方法中检查该值。
推荐阅读
- javascript - PWA 中的 getUserMedia 与 iOS 11 上的清单
- c++ - 使用模板运算符 () 将函数提升到任何函子
- stackdriver - 缺少 Gmail 脚本/添加 Stackdriver 日志
- sql - SQL:填充缺失值多列
- c++ - 在 C++ 中不使用静态函数的情况下不修改数组
- sql - 带有外键的sql错误
- javascript - 如何通过javascript访问chrome中的签名板ActiveX对象?
- sql - 执行存储在表列中的不同查询
- php - 将整数变量舍入为 x 位数
- python-3.x - fastparquet 不提供解压“SNAPPY”