Jump to content
Unity Insider Forum

Sehr simple RTS-Kamera


Hendrik

Recommended Posts

Ich habe hier für mein Projekt eine simple RTS-Kamera erstellt. Das Script Skaliert den Scrollbereich dynamisch, ist also besonders interessant wenn man die Auflösung im Spiel ändert und/oder den Scollbereich veränderbar haben will. Bitte achtet darauf,dass die Kamera eine maximale x-Rotation hat von 45° :)

 

public var scrollSpeed : float = 50; //Die Geschwindigkeit, mit der gescrollt wird
private var transformation : Vector3; //Eine Variable, die definiert wird um die Camera zu verschieben
var curCamera : Transform; //Zieht die Camera, an die das Script gehängt worden ist, hier hin 

function Update () 
{
var screenh : float = Screen.height; //Wird benötigt um richtig zu skalieren
var screenw : float = Screen.width; //s.o.
var screenRightScrollArea : float = screenw * 0.9; //Wenn die Maus in die jeweils 10 % des unteren oder oberen/rechten oder linken Bildschirmbereich kommt, wird gescrollt
var screenLeftScrollArea : float = screenw * 0.1; //s.o.
var screenTopScrollArea : float = screenh * 0.1; //s.o.
var screenBottomScrollArea : float = screenh * 0.9; //s.o

if(Input.mousePosition.x < screenLeftScrollArea) //ist die Maus im linken Scrollbereich? 
{
	transformation.x = scrollSpeed * Time.deltaTime; //Scrolling wird berechnet und für ein sauberes Scrollen mit der Frameanzahhl multipliziert
	transformation.x= transformation.x * (-1); // Für die richtige Richtung wird die Transformation ins negative gekehrt 
	curCamera.Translate(transformation); //Das eigentliche Verschieben der Camera
	transformation.x = 0; //Rücksetzung der Variable um fehlerhaftes Verhalten zu vermeiden
}

if(Input.mousePosition.x > screenRightScrollArea)
{
	transformation.x = scrollSpeed * Time.deltaTime; // Die Schritte sind eigentlich die gleichen wie oben
	curCamera.Translate(transformation);
	transformation.x = 0;
}

if(Input.mousePosition.y < screenTopScrollArea)
{
	transformation.y = scrollSpeed * Time.deltaTime;
	transformation.y = transformation.y * (-1);
	transformation.z = transformation.y;// Da die Camera um die Lokale, nicht um die Globalen Achsen verschoben wird, muss ein Ausgleich der z-Achse geschehen
	curCamera.Translate(transformation);
	transformation.y = 0;
	transformation.z = 0;
}

if(Input.mousePosition.y > screenBottomScrollArea)
{
	transformation.y = scrollSpeed * Time.deltaTime;
	transformation.z = transformation.y;// Da die Camera um die Lokale, nicht um die Globalen Achsen verschoben wird, muss ein Ausgleich der z-Achse geschehen
	curCamera.Translate(transformation);
	transformation.y = 0;
	transformation.z = 0;
}
}

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nette Sache, aber hier und da kann man noch etwas verbessern.

 

Zu Anfang einmal ist es überflüssig, dass man die Kamera dem Skript geben muss, obwohl jede Komponente sein eigenes GameObject und damit auch sein Transform kennt.

 

Als nächstes gibt es keinen Grund, transformation als Feld der Klasse zu deklarieren, sodass man auch in mehreren Funktionen darauf zugreifen kann, da nur Update() damit arbeitet.

Die ScrollArea-Variablen sind dafür in Update() deklariert, was schade ist, denn so etwas möchte man ja vielleicht variabel haben.

 

scrollSpeed darf auch gerne vor einer Zuweisung negiert werden (Zweite Anweisung im ersten if entfällt).

 

Screen.height und .width zwischenzuspeichern ist nicht nötig, der Zugriff darauf ist "leicht und belastet nicht".

 

Warum du überhaupt auf der z-Achse transformierst, weiss ich nicht, alles vertikale kann man stark vereinfachen.

 

Außerdem: Man alle Translate()-Aufrufe aus den if-Abfragen raus nehmen und einen ans Ende tun.

Damit spart man sich auch das Zurücksetzen.

 

Zu guter letzt: Da du immer schön typisiert hast, verdient dein Script das Prädikat #pragma strict

 

Am Ende hat man nur noch:

#pragma strict

private var me : Transform; //Als Feld immernoch sinnvoll, da GetComponent() nicht jeden Frame ausgeführt werden sollte
var scrollSpeed : float = 50; //Die Geschwindigkeit, mit der gescrollt wird
var border : float = 0.1;

function Awake()
{
       me = transform; //transform ist wie GetComponent(Transform) und frist daher auch, aber hier halt nur ein Mal
}

function Update() 
{
       var translation : Vector3 = Vector3.zero;
       var screenRightScrollArea : float = Screen.width * (1-border); //Wenn die Maus in die jeweils x% des unteren oder oberen/rechten oder linken Bildschirmbereich kommt, wird gescrollt
       var screenLeftScrollArea : float = Screen.width * border; //s.o.
       var screenTopScrollArea : float = Screen.height * border; //s.o.
       var screenBottomScrollArea : float = Screen.height * (1-border); //s.o

       if(Input.mousePosition.x < screenLeftScrollArea) //ist die Maus im linken Scrollbereich? 
       {
               transformation.x = -scrollSpeed; //Scrolling wird berechnet und für ein sauberes Scrollen mit der Frameanzahhl multipliziert
       }

       if(Input.mousePosition.x > screenRightScrollArea)
       {
               transformation.x = scrollSpeed;
       }

       if(Input.mousePosition.y < screenTopScrollArea)
       {
               transformation.z = -scrollSpeed;
       }

       if(Input.mousePosition.y > screenBottomScrollArea)
       {
               transformation.z = scrollSpeed;
       }

       me.Translate(transformation * Time.deltaTime); //Das eigentliche Verschieben der Camera
}

Link zu diesem Kommentar
Auf anderen Seiten teilen

Vielen Dank für die Verbesserungen!

Ich fange grade mit dem Scripten an, da sind solche "Wege wie man es besser macht" mir sehr hilfreich :) Ich habe dein Script übernommen, und werde es um einige Komponenten erweitern. Mein Ziel ist es nämlich, eine komplette Maussteuerung meines 3d RTS zu erreichen, das aber natürlich selber gescriptet.

Sobald ich weitergemacht habe werde ich es hier Posten und es mal Überprüfen lassen ;)

Edit:

So, hier ist das schlussendlich funktionierende Script. Sascha hat einige Sachen vergessen, man kann es ihm aber auch nicht übel nehmen, er konnte es ja nicht testen ;)

 

#pragma strict

private var me : Transform; //Als Feld immernoch sinnvoll, da GetComponent() nicht jeden Frame ausgeführt werden sollte
var scrollSpeed : float = 50; //Die Geschwindigkeit, mit der gescrollt wird
var border : float = 0.1;
function Awake()
{
       me = transform; //transform ist wie GetComponent(Transform) und frist daher auch, aber hier halt nur ein Mal
}

function Update() 
{
       var transformation : Vector3 = Vector3.zero;
       var screenRightScrollArea : float = Screen.width * (1-border); //Wenn die Maus in die jeweils x% des unteren oder oberen/rechten oder linken Bildschirmbereich kommt, wird gescrollt
       var screenLeftScrollArea : float = Screen.width * border; //s.o.
       var screenTopScrollArea : float = Screen.height * border; //s.o.
       var screenBottomScrollArea : float = Screen.height * (1-border); //s.o

       if(Input.mousePosition.x < screenLeftScrollArea) //ist die Maus im linken Scrollbereich? 
       {
               transformation.x = -scrollSpeed; //Scrolling wird berechnet und für ein sauberes Scrollen mit der Frameanzahhl multipliziert
       }

       if(Input.mousePosition.x > screenRightScrollArea)
       {
               transformation.x = scrollSpeed;
       }

       if(Input.mousePosition.y < screenTopScrollArea)
       {
               transformation.z = -scrollSpeed;
			transformation.y = -scrollSpeed;
       }

       if(Input.mousePosition.y > screenBottomScrollArea)
       {
               transformation.z = scrollSpeed;
			transformation.y = scrollSpeed;
	}

       me.Translate(transformation * Time.deltaTime); //Das eigentliche Verschieben der Camera
}

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 months later...

Ah, deswegen transformation.y, verstehe.

Wie wäre es, wenn die Kamera einem Objekt untergeordnet wird, dessen "Oben" wirklich "oben" ist, und das bekommt dann das Skript? Dann entfällt diese Unsauberkeit und man kann die Kamera fortan frei nach oben und unten schwenken.

 

Das ist wieder Typisch programmierer xD Mit deiner Methode bekommst du zwar die Unsauberkeit aus dem Code raus aber wenn sich dann ein Mapdesigner oder was weiß ich was die Kamera mit dem Objekt anschaut wird der auch sagen was soll denn der Blödsinn die Unsauberkeit wäre doch damit dann nur verschoben oder nicht? ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Lädt...
×
×
  • Neu erstellen...