2015-08-14 5 views
5

Ich arbeite an der Erstellung eines Ofscreen-Enemy-Indikators mit Hilfe des unten genannten Tutorials. Allerdings kann ich den Indikator drehen, um auf den Feind zu zeigen, aber der Indikator bewegt sich nicht vom Ende zum Ende des Bildschirms.Wie man den Ofscreen-Feindindikator in Unity 3D erstellt?

http://gamedevelopment.tutsplus.com/tutorials/positioning-on-screen-indicators-to-point-to-off-screen-targets--gamedev-6644

Dies ist das gewünschte Ergebnis:

desired-outcome

Bis jetzt habe ich die unten, um herauszufinden, haben es geschafft, Bitte helfen.

var screenCenter:Vector3 = new Vector3(0.5, 0.5, 0f); 
    //Note coordinates are translated 
    //Make 00 the centre of the screen instead of bottom left 
    screenpos -= screenCenter; 

    //find angle from center of screen instead of bototom left 
    var angle:float = Mathf.Atan2(screenpos.y, screenpos.x); 
    angle -= 90 * Mathf.Deg2Rad; 

    var cos:float = Mathf.Cos(angle); 
    var sin:float = -Mathf.Cos(angle); 

    screenpos = screenCenter + new Vector3(sin*150, cos*150, 0); 

    //y=mx + b format 
    var m:float = cos/sin; 
    var ScreenBounds:Vector3 = screenCenter;// * 0.9f; 

    //Check up and down first 
    if(cos > 0){ 
     screenpos = new Vector3(ScreenBounds.y/m, ScreenBounds.y, 0); 
    }else{//down 
     screenpos = new Vector3(-ScreenBounds.y/m, -ScreenBounds.y, 0); 
    } 
    //If out of bound then get point on appropriate side 
    if(screenpos.x > ScreenBounds.x){//Out of bound must be on right 
     screenpos = new Vector3(ScreenBounds.x, ScreenBounds.y*m, 0); 
    }else if(screenpos.x < ScreenBounds.x){//Out of bound must be on left 
     screenpos = new Vector3(-ScreenBounds.x, -ScreenBounds.y*m, 0); 
    } 
    //Remove the co ordinate translation 
    screenpos += screenCenter; 
    var DistanceIndicatorRectT = DistanceIndicator.GetComponent(RectTransform); 
    DistanceIndicatorRectT.localPosition = new Vector3(screenpos.x * scrWidth/2, screenpos.y * scrHeight/2, DistanceIndicatorRectT.localPosition.z * screenpos.z); 
    DistanceIndicator.transform.rotation = Quaternion.Euler(0, 0, angle*Mathf.Rad2Deg); 
+1

Können Sie Ihr Problem ein wenig besser erklären? Alles, was Sie jetzt haben, ist "Ich möchte dieses Verhalten mit diesem Code". Was genau versagt? Was ist der Unterschied zwischen Ihrer gewünschten und erhaltenen Ausgabe? –

+0

@DJ IV DJIV: Wo haben Sie den obigen Code hinzugefügt? Update()? – user1509674

Antwort

2

ein Rechteck Feld collider Erstellen der Grenzen des Siebes abgrenzt und Physics2D.Raycast in Richtung des Gegners verwenden.

Der Kollisionspunkt wird Ihnen sagen, wo der grüne Pfeil gezeichnet werden muss.

3

Ich habe ein etwas anderer Ansatz als Sie, was Carlos vorgeschlagen, aber ohne Physik.

Wenn „t“ Ihr Ziel ist es, auf diese Weise Sie seine Position in Pixel auf dem Bildschirm bekommen kann (wenn es außerhalb des Bildschirms ist es nur geht auf negative Werte oder Werte höher die Breite)

Vector3 targetPosOnScreen = Camera.main.WorldToScreenPoint (t.position); 

Und diese Funktion dass die Rückkehr ein Bool, ob der Vector3 (in Pixel) ist auf dem Bildschirm

bool onScreen(Vector2 input){ 
    return !(input.x > Screen.width || input.x < 0 || input.y > Screen.height || input.y < 0); 
} 

das erste, was wir tun sollten, ist zu überprüfen, ob das Ziel auf dem Bildschirm angezeigt wird, wenn es nicht dann ist mit Code gehen.

if (onScreen (targetPosOnScreen)) { 
     //Some code to destroy indicator or make it invisible 
     return; 
    } 

Dann eine einfache Berechnung des Winkels zwischen der Mitte des Bildschirms und Ziel.

Der nächste Teil des Codes bestimmt, wo das Objekt mit der Kamera verglichen wird, basierend auf dem Winkel, den wir gerade berechnet haben.

float coef; 
if (Screen.width > Screen.height) 
    coef = Screen.width/Screen.height; 
else 
    coef = Screen.height/Screen.width; 

float degreeRange = 360f/(coef + 1); 

if(angle < 0) angle = angle + 360; 
int edgeLine; 
if(angle < degreeRange/4f) edgeLine = 0; 
else if (angle < 180 - degreeRange/4f) edgeLine = 1; 
else if (angle < 180 + degreeRange/4f) edgeLine = 2; 
else if (angle < 360 - degreeRange/4f) edgeLine = 3; 
else edgeLine = 0; 

http://s23.postimg.org/ytpm82ad7/Untitled_1.png

Bild stellt dar, was Wert „Edgeline“ auf Zielposition hat basieren und schwarze Linien Raumaufteilung (roter Blick der Kamera steht).

Und dann haben wir diesen Code, der Transform "t2" (Indikator) auf korrekte Position und Winkel setzt.

t2.position = Camera.main.ScreenToWorldPoint(intersect(edgeLine, center, targetPosOnScreen)+new Vector3(0,0,10)); 
t2.eulerAngles = new Vector3 (0, 0, angle); 

Im Folgenden Funktion haben „schneiden“, die Nummer lautet:

Vector3 intersect(int edgeLine, Vector3 line2point1, Vector3 line2point2){ 
    float[] A1 = {-Screen.height, 0, Screen.height, 0}; 
    float[] B1 = {0, -Screen.width, 0, Screen.width}; 
    float[] C1 = {-Screen.width * Screen.height,-Screen.width * Screen.height,0, 0}; 

    float A2 = line2point2.y - line2point1.y; 
    float B2 = line2point1.x - line2point2.x; 
    float C2 = A2 * line2point1.x + B2 * line2point1.y; 

    float det = A1[edgeLine] * B2 - A2 * B1[edgeLine]; 

    return new Vector3 ((B2 * C1[edgeLine] - B1[edgeLine] * C2)/det, (A1[edgeLine] * C2 - A2 * C1[edgeLine])/det, 0); 
} 

Wir diese Funktion Index senden, von denen Linie Kameraansicht (Rechteck), mit dem wir überprüft Kreuzung benötigen, und baut eine Linie zwischen Bildschirmmitte und Zielposition.

Zur besseren Erläuterung dieser Funktion sehen hier: https://www.topcoder.com/community/data-science/data-science-tutorials/geometry-concepts-line-intersection-and-its-applications/

ich nur Werte von A1 modifiziert, B1 und C1, jeder von ihnen ist jetzt Array von 4 und jeweils Werte repräsentiert Wert benötigt für eine Zeile der Blick der Kamera (Rechteck).

Wenn Sie Margen implementieren möchten, ändern Sie einfach den Drehpunkt des Indikators (fügen Sie den tatsächlichen Sprite-Renderer als untergeordnetes Element ein und verschieben Sie ihn wie gewünscht im lokalen Bereich).

Als nächstes würde dies für Array von Zielen und setzen alle diese Ziele in bestimmten Array arbeiten. Hoffe, dass dies hilft und nicht zu hart für mich ist, es ist mein erstes Mal hier posten :)

+0

Danke, es ist Arbeit für mich. Aber es gibt einen kleinen Fehler. Wenn targetPosOnScreen.z <0 ist, wird alles umgedreht. Also fügen Sie Folgendes hinzu: – phuongnd