2017-06-12 42 views
2

我想隨着時間的推移造成法術傷害。因此,這裏是我的代碼:一段時間內的傷害統一

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; 
     } 
    } 
} 
+1

也許一個愚蠢的問題:爲什麼'appliedTimes ++'不是while循環? – Hellium

+0

@Hellium我認爲這是答案。它應該在循環 – Bijan

+0

@Hellium我正在嘗試的東西,當我把代碼回原來我忘了把它放回來,所以我編輯後發佈。 –

回答

3

OnTriggerStay每幀被調用2個對象發生衝突。這意味着CastDamage協同程序的異步實例被稱爲每一幀。所以會發生的是,你每秒會受到很多傷害,這不會模擬每秒造成的傷害,嘿嘿。

因此,將OnTriggerStay更改爲OnTriggerEnter。

根據其種類法術是的,我寧願創建一個DPS腳本並應用到遊戲的對象,因此...

  • 箭命中對象
  • AddComponent < MyDamageSpell>() ;

然後是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

+0

看起來很有趣。我會嘗試,但因爲你在這裏你能解釋我這個。我做了每個'N'秒,但IEnumerator裏面的if語句令我困惑。我編輯了我的問題,所以閱讀結束,如果你知道發生了什麼,請回答我 –

+0

我更新了我的答案以及更多的代碼,以及不同的場景。我會看你的更新! – Maakep

+0

我已經解決了它 –

1

爲什麼不創建,而是一個系統,將遊戲角色應用到遊戲中的角色?例如,如果像這樣的咒語隨着時間的推移增加了一個傷害debuff,它可以將debuff-aura腳本添加到遊戲對象中,然後在符合條件時自行移除。

+0

我不安靜得到它。你認爲將代碼插入gameobject本身(需要採取傷害),然後當條件滿足(與法術碰撞)我應用它? –