2013-04-19 5 views
7

Ich versuche, meinen Player zu blinken, wenn er getroffen wird. Ich habe Erkennungsfunktion getroffen. Er wechselt momentan zu rot. Ich frage mich, wie man das tatsächliche Blinken auftreten lässt. Hier ist ein Ausschnitt, der getroffen Griffe werden:Spieler-Flash machen, wenn er getroffen wird

if(otherObject.CompareTag("Minion")) //hit by minion 
    { 
     if(hitFromTop(otherObject.gameObject)) //if player jumped on enemy 
     { 
      otherObject.GetComponent<Minion>().setMoving(false); //stop moving 
      playSound(KillEnemySound); //play killing enemy sound 
      jump(); 
      Destroy(otherObject.gameObject); //kill minion 

     } 
     else //otherwise, enemy hit player 
     { 
      if(canTakeDamage) 
      { 
       changeColor(Color.red); 
       loseHealth(1); //lose health 
       canTakeDamage=false; 
       yield return new WaitForSeconds(1.5f); //delay taking damage repeatedly 
       changeColor(Color.white); 
       canTakeDamage=true; 
      } 
      //indicate lost health somehow 
     } 

Derzeit ist die Umstellung auf rot konstant ist (nicht blinkend) und zeitlich begrenzt, über die yield return new WaitForSeconds(1.5f);. Ich könnte ein paar dieser Anrufe stellen, mit Farbänderungen dazwischen, aber ich frage mich, ob es einen besseren Weg gibt. Ich kann nicht der Erste sein, der in einem Spiel etwas Flash macht.

EDIT: Ich habe Heisenbug Flash() Code wie folgt hinzugefügt:

IEnumerator FlashPlayer(float time, float intervalTime) 
{ 
    canTakeDamage=false; 
    float elapsedTime = 0f; 
    int index = 0; 

    while(elapsedTime < time) 
    { 
     Debug.Log("Elapsed time = " + elapsedTime + " < time = " + time + " deltaTime " + Time.deltaTime); 
     mat.color = colors[index % 2]; 
     elapsedTime += Time.deltaTime; 
     index++; 
     yield return new WaitForSeconds(intervalTime); 
    } 
    canTakeDamage=true; 
} 

und es wird hier genannt:

void loseHealth(int damage) 
{ 
    //irrelevant details omitted for brevity 
      //the "if" checks if the player has run out of health, should not affect the else because this method is called from OnTriggerEnter...see below... 
    else 
    { 
     StartCoroutine(FlashPlayer (1.5f, 0.5f)); 
    } 
} 

und hier ist, wo das (in OnTriggerEnter) aufgerufen wird:

Das Problem ist jetzt, dass der Flash nie aufhört. Es sollte aufhören, wenn elapsedTime 1,5 f erreicht, wie ich angegeben habe, aber weil es nur um kleine Beträge (in Time.deltaTime) erhöht wird, dann erreicht es nicht 1.5f für eine sehr lange Zeit. Gibt es etwas, das ich weggelassen habe, das es 1,5 f schneller erreichen sollte, oder gibt es eine andere Nummer, die ich auswählen kann, die ich genau verwenden kann, um als Haltepunkt zu dienen? Die Zahlen für elapsedTime sind in der Regel: 0, 0.02, 0.03693, 0.054132, usw. sehr klein, also kann ich nichts wirklich von hier wählen.

+0

erwägen, einen SSCCE zu veröffentlichen: http://sscce.org/. – Heisenbug

+0

Entschuldigung, ich hatte noch keine Chance das zu tun. Ich werde es versuchen, sobald ich die Gelegenheit dazu habe. – muttley91

Antwort

2

Der folgende Code ist möglicherweise der, nach dem Sie suchen. Das Objekt sollte für die Gesamtmenge an time ändert seine Farbe blinken nach intervalTime

using UnityEngine; 
using System.Collections; 

public class FlashingObject : MonoBehaviour { 

    private Material mat; 
    private Color[] colors = {Color.yellow, Color.red}; 

    public void Awake() 
    { 

     mat = GetComponent<MeshRenderer>().material; 

    } 
    // Use this for initialization 
    void Start() { 
     StartCoroutine(Flash(5f, 0.05f)); 
    } 

    IEnumerator Flash(float time, float intervalTime) 
    { 
     float elapsedTime = 0f; 
     int index = 0; 
     while(elapsedTime < time) 
     { 
      mat.color = colors[index % 2]; 

      elapsedTime += Time.deltaTime; 
      index++; 
      yield return new WaitForSeconds(intervalTime); 
     } 
    } 

} 
+0

Das funktioniert so weit. Das einzige ist, dass es nicht wirklich aufhört, nachdem die Zeit verstrichen ist. Ich werde einige Debug-Anweisungen einwerfen, aber jede Idee, warum das sein könnte? Beachten Sie, dass ich die Coroutine nicht von Start aus anrufe, wie Sie es getan haben. Ich rufe sie von meiner 'loseHealth (1)' Funktion an, die Sie oben in meinem Codeschnipsel sehen (ich habe alles andere aus dieser Bedingung außer dem Anruf entfernt) zu 'verlierenGesundheit (1)'). – muttley91

+0

wird looseHealth innerhalb Update oder ähnlichen Methoden aufgerufen? – Heisenbug

+0

Nein, es heißt nur onTriggerEnter (es sei denn, dies gilt als eine ähnliche Methode ...). – muttley91

0

Die Antwort oben ist groß, aber es hört nicht auf zu blinken, weil es viel zu lange dauert, bis der Schwimmer 5f zu erreichen.

Der Trick besteht darin, den ersten Parameter in der Flash Funktion auf etwas kleiner, wie 1f, anstelle von 5f. Nimm dieses Skript und befestige es an jedem Spielobjekt. Es blinkt für etwa 2,5 Sekunden zwischen gelb und rot und stoppt dann.

using UnityEngine; 
using System.Collections; 

public class FlashingObject : MonoBehaviour 
{ 

    private Material _mat; 
    private Color[] _colors = { Color.yellow, Color.red }; 
    private float _flashSpeed = 0.1f; 
    private float _lengthOfTimeToFlash = 1f; 

    public void Awake() 
    { 

     this._mat = GetComponent<MeshRenderer>().material; 

    } 
    // Use this for initialization 
    void Start() 
    { 
     StartCoroutine(Flash(this._lengthOfTimeToFlash, this._flashSpeed)); 
    } 

    IEnumerator Flash(float time, float intervalTime) 
    { 
     float elapsedTime = 0f; 
     int index   = 0; 
     while (elapsedTime < time) 
     { 
      _mat.color = _colors[index % 2]; 

      elapsedTime += Time.deltaTime; 
      index++; 
      yield return new WaitForSeconds(intervalTime); 
     } 
    } 
}