随着时间的推移损坏统

时间:2017-06-12 10:48:54

标签: c# unity3d coroutine

我希望随着时间的推移造成法术伤害。所以这是我的代码:

/some/really/long/url

问题是public class Spell : MonoBehaviour { public float damage = 1.0f; public bool ignoreCaster = true; public float delayBeforeCasting = 0.4f; public float applyEveryNSeconds = 1.0f; public int applyDamageNTimes = 5; private bool delied = false; private int appliedTimes = 0; void OnTriggerStay(Collider other) { IDamageable takeDamage = other.gameObject.GetComponent<IDamageable>(); if(takeDamage != null) { StartCoroutine(CastDamage(takeDamage)); } } IEnumerator CastDamage(IDamageable damageable) { if(!delied) { yield return new WaitForSeconds(delayBeforeCasting); delied = true; } while(appliedTimes < applyDamageNTimes) { damageable.TakeDamage(damage); yield return new WaitForSeconds(applyEveryNSeconds); appliedTimes++; } } } 开始的地方。我想检查是否while,然后是否真的做了损坏,等待延迟(applyEveryNSeconds),然后再次检查但是我没有方便的协程,并且由于某种原因它没有这样做。

这是工作代码。如果有人需要,还要寻找其他答案!

appliedTimes < applyDamageNTimes

2 个答案:

答案 0 :(得分:3)

OnTriggerStay在每个帧2对象发生碰撞时被调用。这意味着每帧都会调用CastDamage协同程序的异步实例。所以会发生的事情是你每秒钟会受到很多伤害,模拟的每秒伤害并不是很大,呵呵。

因此将OnTriggerStay更改为OnTriggerEnter。

根据它的类型,我宁愿创建一个DPS脚本并将其应用于游戏对象,所以...

  • 拼写点击对象
  • AddComponent&LT; MyDamageSpell&GT;();

然后MyDpsSpell会每N秒对它所在的对象造成伤害,并在完成后自行移除:

// Spell.cs

void OnTriggerEnter(Collider col) {
    // if you don't want more than 1 dps instance on an object, otherwise remove if
    if (col.GetComponent<MyDpsAbility>() == null) {
        var dps = col.AddComponent<MyDpsAbility>();
        dps.Damage = 10f;
        dps.ApplyEveryNSeconds(1);
        // and set the rest of the public variables
    }
}

// MyDpsAbility.cs

public float Damage { get; set; }
public float Seconds { get; set; }
public float Delay { get; set; }
public float ApplyDamageNTimes { get; set; }
public float ApplyEveryNSeconds { get; set; }

private int appliedTimes = 0;

void Start() {
    StartCoroutine(Dps());
}

IEnumerator Dps() {
    yield return new WaitForSeconds(Delay);

    while(appliedTimes < ApplyDamageNTimes)
    {
        damageable.TakeDamage(damage);
        yield return new WaitForSeconds(ApplyEveryNSeconds);
        appliedTimes++;
    }

    Destroy(this);
}

如果这是一个光环法术,单位每秒受到伤害,他们就会在范围内做出类似的事情:

float radius = 10f;
float damage = 10f;
void Start() {
    InvokeRepeating("Dps", 1);
}


void Dps() {
    // QueryTriggerInteraction.Collide might be needed
    Collider[] hitColliders = Physics.OverlapSphere(gameObject.position, radius);

    foreach(Collider col in hitColliders) {
        col.getComponent<IDamagable>().TakeDamage(10);
    }
}

https://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html

答案 1 :(得分:1)

为什么不创建一个将auras应用于游戏中角色的系统呢?例如,如果像这样的咒语随着时间的推移增加了一个伤害debuff,它可以将debuff-aura脚本添加到游戏对象中,然后在满足条件后自行删除。