【问题标题】:Trying to Grab int Variable From Separate Script试图从单独的脚本中获取 int 变量
【发布时间】:2021-11-23 01:04:27
【问题描述】:

我知道我需要做什么才能让我的脚本工作我只是不知道要写什么代码。我想要做的是从我的敌人脚本中获取我的 currentHealth int(不是公共 int 只是一个 int)到我的 Enemy Combat 脚本,这样我就可以在我的 currentHealth 高于 50 时让我的第二次攻击做 0 dmg。如果我真的想要回到真正的问题,这是我的第二次攻击,虽然动画在 hp 为 50 或更高时不会播放,因为该攻击只应该在 50 hp 或更低时发生,但碰撞检查仍然起作用并损坏玩家,即使它直到 50 hp 或更低时才设置为激活。更详细地说,我将我的老板分为几个阶段,第一阶段是直到你将老板 dmg 到 50hp 然后他进入第二阶段并进行第二次攻击。该功能工作正常,但是,在第二阶段通过在 hp 低于 50 时将 bool 设置为 true 来激活的第二次攻击,即使动画没有播放,仍然会在攻击范围内造成伤害,但由于某种原因,我的伤害仍然会造成伤害即使在比赛开始时,即使没有播放动画。

这是保存健康逻辑的 Enemy 脚本。

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

public class Enemy : MonoBehaviour
{
public Component enemyCombat;

public Component aiScript;

public Animator animator;

public int maxHealth = 100;

int currentHealth;

// Start is called before the first frame update
void Start()
{
    currentHealth = maxHealth;
}

public void TakeDamage(int damage)
{
    currentHealth -= damage;
    animator.SetTrigger("Hurt");

    if (currentHealth <= 50)
    {
        animator.SetBool("IsAngry", true);
    }

    if(currentHealth <= 0)
    {
        Die();
    }
}

void Die()
{
    Debug.Log("Enemy Died");

    animator.SetBool("IsDead", true);

    Destroy(aiScript);

    Destroy(enemyCombat);

    GetComponent<Collider2D>().enabled = false;

   this.enabled = false;      
}

这是我的 EnemyCombat 脚本(以我的老板命名,它是 Orion 的升级版)

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

public class OrionUpgradedCombat : MonoBehaviour
{
public Animator animator;

public GameObject gameObject;

public Transform AttackPoint;

public Transform secondAttackPoint;

public float attackRange = 0.5f;

public float secondAttackRange = 0.5f;

public LayerMask enemyLayers;

public int attackDamage = 8;

public int secondAttackDamage = 15;

public float attackRate = 2f;
float nextAttackTime = 0f;

void Start()
{
    enemy enemyScript = gameObject.GetComponent<Enemy>();
}

// Update is called once per frame
void Update()
{
    if (Time.time >= nextAttackTime)
    {
        StartCoroutine(Attack());
        StartCoroutine(AttackTwo());
        nextAttackTime = Time.time + 8f / attackRate;
    }

    if (currentHealth >= 50)
    {
        secondAttackDamage -= 15;
    }
    else
    {
        secondAttackDamage = 15;
    }
}

public IEnumerator Attack()
{
    yield return new WaitForSeconds(2);
    animator.SetTrigger("Attack");
    Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, attackRange, enemyLayers);
    foreach (Collider2D enemy in hitEnemies)
    {
        enemy.GetComponent<PlayerHealth>().TakeDamage(attackDamage);
    }
}

public IEnumerator AttackTwo()
{
    yield return new WaitForSeconds(4);
    animator.SetTrigger("AttackTwo");
    Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(secondAttackPoint.position, secondAttackRange, enemyLayers);
    foreach (Collider2D enemy in hitEnemies)
    {
        enemy.GetComponent<PlayerHealth>().TakeDamage(secondAttackDamage);
    }
}

void OnDrawGizmosSelected()
{
    if (AttackPoint == null)
        return;

    Gizmos.DrawWireSphere(AttackPoint.position, attackRange);
}

【问题讨论】:

  • 欢迎来到 SO!一般来说,您希望避免使用 "...我>。我们都对某事、某处、某时陌生。所以不用担心。 :) 祝你好运!
  • 谢谢,我不一定是新手,我只是丢失了另一个帐户,但我只问了三个问题,所以还是有点新,哈哈。你是对的,我之前的经历很糟糕,有人暗示事情并告诉我参考其他地方而不是他们真正帮助我。我相对称职,在自己提出问题之前,我几乎总是参考所有其他地方。他们只是不明白每个项目都是不同的/:再次感谢您的智慧哈哈
  • 所以看起来你的currentHealth 应该是public 然后在第二个脚本OrionUpgradeCombat 你想使用if(GetComponent&lt;Enemy&gt;().currentHealth &gt;= 50 .... ?对我来说听起来不像你之前的评论是非常真实的......In Unity, how can I pass values from one script to another?

标签: c# unity3d


【解决方案1】:

它仍然造成伤害的原因是因为您在启动AttackOne coroutine 之后立即启动了AttackTwo coroutine。在将 secondAttackDamage 更改为 0 之前,您也要这样做。我建议您在敌人的生命值低于 50 时调用 AttackTwo coroutine。

【讨论】:

    【解决方案2】:

    如果你能在这种情况下使用动画事件就好了,但如果由于某种原因无法使用,我猜可能是在 Update() 方法中调用协程有问题,所以我建议使用一个标志来仅在前一个调用完成时启动协程。应该是这样的:

    bool isCoroutineStarted = false;
    
    void Update()
    {
        if (!isCoroutineStarted)
        {
            StartCoroutine("YourAttackCoroutine");
        }
    }
    
    IEnumerator YourAttackCoroutine()
    {
        isCoroutineStarted = true;
    
        //Your Code 
    
        yield return new WaitForSeconds(0);
    
        isCoroutineStarted = false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-18
      • 2013-06-15
      • 2019-02-16
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      相关资源
      最近更新 更多