gpt4 book ai didi

c# - 随着时间的推移造成的伤害统一

转载 作者:行者123 更新时间:2023-11-30 20:30:38 24 4
gpt4 key购买 nike

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

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开始。我想检查是否 appliedTimes < applyDamageNTimes ,那么如果确实造成损坏,请等待延迟(applyEveryNSeconds),然后再次检查,但我对协程不方便,并且由于某种原因它没有这样做。

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

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

public class Spell : MonoBehaviour
{
public float damage = 1.0f;
public bool ignoreCaster = true;
public float delayBeforeCasting = 0.0f;
public float applyEveryNSeconds = 1.0f;
public int applyDamageNTimes = 1;

private bool delied = false;

private int appliedTimes = 0;

private bool test = false;
void OnTriggerStay(Collider other)
{
IDamageable takeDamage = other.gameObject.GetComponent<IDamageable>();
if(takeDamage != null)
{
StartCoroutine(CastDamage(takeDamage));
}
}

IEnumerator CastDamage(IDamageable damageable)
{
if(!test && appliedTimes <= applyDamageNTimes || !test && applyEveryNSeconds == 0)
{
test = true;
if(!delied)
{
yield return new WaitForSeconds(delayBeforeCasting);
delied = true;
}
else
{
yield return new WaitForSeconds(applyEveryNSeconds);
}
damageable.TakeDamage(damage);
appliedTimes++;
test = false;
}
}
}

最佳答案

每帧有 2 个对象发生碰撞时,都会调用 OnTriggerStay。这意味着每帧都会调用 CastDamage 协程的异步实例。所以发生的情况是你每秒受到大量伤害,这模拟每秒没有任何伤害,呵呵。

因此将 OnTriggerStay 更改为 OnTriggerEnter。

根据咒语的类型,我宁愿创建一个 DPS 脚本并将其应用到游戏对象,这样...

  • 法术击中物体
  • AddComponent ();

然后 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

关于c# - 随着时间的推移造成的伤害统一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44497565/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com