Jump to content
Unity Insider Forum

Wir bauen uns ein Space Shoot em Up [Teil 6 - Optik]


Mark

Recommended Posts

Heute wenden wir uns ein wenig der Optik zu, aktuell haben wir einfache Primitiven (Würfel und Kugeln). Diese machen optisch absolut nichts her und mittlerweile haben wir uns besseres verdient. Ausserdem brauchten wir unsere Kugel bisher als Wegbarke, aber da diese nun zerstört werden kann und wir später auch Gegner und mehr haben brauchen wir noch etwas anderes, etwas für den Hintergrund.

 

Wir starten damit dass wir unseren blauen Hintergrund etwas weltraumiger gestalten indem wir zuerst die Farbe abdunkeln und ein paar Sterne hinzufügen.

 

Wir selektieren also als erstes unsere "Main Camera" im Inspektor sehen wir eine Camera Komponente und dort das Feld mit dem Text "Background Color" klickt auf die daneben angezeigte Farbe und ändert diese auf eine sehr dunkle blaue Farbe oder was auch immer am besten gefällt.

 

Damit haben wir die Grundhintergrundfarbe festgelegt, was schon etwas ausmacht im vergleich zu zuvor. Nun fügen wir ein simples Licht hinzu um die flache Optik unserer Objekte loszuwerden. Geht auf "GameObject"->"Create Other"->"Directional Light". Ändert nun die Rotation dieses GameObjektes auf: X = 30, Y = 100 und Z = 60

 

Damit haben wir das Direktionale Licht so gedreht das wir eine ansprechende Beleuchtung haben. Wer Lust hat kann nun ein wenig an der Light Komponente herumspielen, interessant dürften die Lichtfarbe und Intensität sein.

 

Damit haben wir schon 2 wichtige Punkte abgehakt die maßgeblich zur Optik beitragen. Nun fügen wir noch einen Sternenhintergrund hinzu der sich je nach Position der Kamera verändert. Es gibt viele Wege dies zu bewerkstelligen. Wir nehmen dafür einfach ein Partikelsystem welches uns die Sterne zeichnet und eine neue Komponente die die Position des Partikelsystems auf eine Ebene unter dem Raumschiff projeziert.

 

Wir erstellen uns als erstes ein geeignetes Partikelsystem. Erstellt dazu ein neues GameObjekt mit "GameObject"->"Create Other"->"Particle System", nennt das neu erstellte GameObject in "Sterne" um. Ihr solltet nun einige Partikel sehen die empor steigen. Wir wollen aber keine sich selbst bewegenden Sterne und daher ändern wir im Inspektor unter "Particle System" die Start Speed auf 0, damit fliegen unsere Partikel nicht mehr durch die Gegend, statt dessen sehen wir eine Punktwolke.

 

Diese Wolke sollte sich aber etwas weiter ausbreiten, also klicken wir auf "Shape" welches sich dadurch ausklappen sollte (nicht die Checkbox entfernen) und ändern die "Shape" von Cone auf eine Box um. Um die Box besser zu definieren ändern wir noch die Werte der Box auf X = 100, Y = 100 und Z = 10. Nun sehen wir nur noch sehr wenige Sterne da der Raum so riesig geworden ist (wir könnten hier auch kleinere Werte verwenden, aber es schadet auch nicht wenn die Werte so groß sind).

 

Um mehr Sterne zu bekommen setzen wir noch die "Start Lifetime" auf 10 damit wir nicht so viele Sterne aufflackern und verschwinden sehen. Nun müssen wir noch den "Emission" Bereich wie zuvor den "Shape" Bereich ausklappen und dort den "Rate" Wert auf 300 setzen. Dies beeinflusst wieviele Partikel pro Sekunde erzeugt werden sollen. Ausserdem brauchen wir spielraum für die maximale Anzahl der Partikel. ändert daher den Wert von "Max Particles" auf 10000.

 

Da die Partikel noch sehr groß sind müssen wir auch diese anpassen und setzen die Start Size auf einen Wert zwischen 0.2 und 0.3.

Damit die Sterne wenn wir das Spiel starten schon vorhanden sind müssen wir noch die Checkbox bei "Prewarm" setzen, dies sorgt dafür dass das Partikel System schon alle Partikel erstellt bevor sie angezeigt werden. Ein kleines aber wichtiges Detail.

 

Nun tauchen die Partikel aber einfach so auf und verschwinden auch einfach so wieder, ohne sanft ein und auszublenden. Auch dies können wir anpassen indem wir die "Color over Lifetime" Kategorie ausklappen und dort die Checkbox aktivieren. Der daraufhin aktivierte Colorwert kann nun dazu benutzt werden einen Farbverlauf zu definieren. Wir klicken also auf die Farbe und erstellen uns einen Farbverlauf.

 

Im oberen Bereich des Farbverlaufeditors können wir die Transparenz (Alpha) festlegen pro Stufe des Verlaufes, wir klicken nun also bei 10% und bei 90% des großen Balkens und stellen dort den Alpha Wert auf 255, die Werte ganz links (0%) und ganz rechts (100%) des Farbverlaufes setzen wir auf 0 Alpha.

 

Damit blenden unsere Partikel sanft ein, bleiben eine weile bestehen und blenden dann wieder sanft aus.

 

Wenn wir jetzt die Szene starten sollten wir schon ein viel bessers Flugerlebniss haben, aber wenn wir zu weit fliegen verschwinden die Sterne auf einmal, da dort der Bereich des Partikel Systems zu Ende ist.

 

Um dies zu ändern erstellen wir uns ein neues C# Script mit dem Namen "ProjectToPlane". Wir fügen nun eine Variable hinzu:

 

public GameObject ObjectToProject;

 

Dies dient dazu um festzulegen welches Objekt auf die Ebene projeziert werden soll.

 

In der Update Methode schreiben wir nun folgendes:

 

var plane = new Plane(Vector3.up, 0);

float distance;
if (plane.Raycast(new Ray(transform.position, transform.forward), out distance))
{
ObjectToProject.transform.position = transform.position + transform.forward * distance;
}

 

Die erste Zeile definiert unsere Ebene, wir benutzen einfach die Ebene die nach oben zeigt und durch den 0 Punkte geht.

Die nächste Zeile definiert eine lokale float Variable die wir hier noch nicht zuweisen. Dies erledigt die nächste Zeile in der if Abfrage. Hier prüfen wir ob der Strahl (Ray) der durch unsere Position (transform.position) und Richtung (transform.forward) definiert wird, die Ebene schneidet. Wenn die Ebene geschnitten wird wird so hat unsere float Variable die Distanz die der Strahl gewandert ist um die Ebene zu treffen. Das out Keyword gibt dabei an dass unsere float Variable als Referenzweret behandelt wird und damit von der Methode die wir aufrufen verändert werden kann. Dadurch kann uns die Methode die Distanz direkt in diese Variable legen und gleichzeitig einen bool Rückgabewert haben. Diesen bool Rückgabewert verwenden wir um die if Abfrage zu steuern.

 

Wenn diese if Abfrage erfolgreich ist so setzen wir unser ObjectToProject auf den Schnittpunkt den wir berechnen indem wir unseren Ursprungspunkt mit der Richtung multipliziert mit der Distanz addieren.

 

Wir legen dieses Script auf unsere Main Camera und wählen als ObjectToProject Wert unser Sternen Partikelsystem aus. Anschließend selektieren wir nochmal unser Partikel System und ändert dort den "Simulation Space" von "Local" auf "World". Dies sorgt dafür dass sich die Sterne nicht automatisch mitbewegen wenn unser neu erstelltes Script die Position des Partikelsystems ändert.

 

Das war auch schon der schwierigste Teil dieses Tutorials. Aber fertig mit dem aufhübschen sind wir noch nicht. Es wäre toll wenn unsere Projektile einen Schweif hinter sich herziehen könnte wenn sie fliegen.

 

Wählt das Projektil Prefab aus und fügt folgende Komponente hinzu: "Effects"->"Trail Renderer". Ändert bei dieser Komponente "Time" auf 0.3, dies gibt an wie lange der Schweif sichtbar sein darf, 0.3 Sekunden reicht aus um es bei höheren Geschwindigkeiten zu sehen ohne das es zu penetrant wirkt.

 

Ändert ausserdem "End Width" auf 0, dies gibt an dass der Schweif zum Ende hin kleiner wird. Passt noch den "Start Width" Wert auf 0.5 oder kleiner an damit der Schweif auch zu der Größe des Projektils passt.

 

Wenn wir die Szene nun starten sehen wir einen pinken langweiligen Schweif bei jedem gefeuerten Schuss. Dies können wir ändern indem wir dem Trail Renderer ein Material zuweisen. Materialien werden benutzt um das Aussehen von Objekte zu beeinflussen. hier können wir uns eine Textur aussuchen und auch angeben wie etwas gezeichnet werden solle (Shader). Wir sollten uns daher ein neues Material erstellen.

 

Klickt mit der rechten Maustaste in den Asset Bereich und wählt Material. Nennt das neu erzeugte Material "Schweif" und weist es auch gleich dem Trail Renderer zu. Wählt nun wieder das Material aus und ändert die Textur des Materials indem ihr im inspektor auf Select im großen grauen Rechteck klickt. Wählt dort die bereits vorhandene Default-Particle Textur aus. Zusätzlich solltet ihr den verwendeten Shader ändern und zwar auf: "Particles"->"Additive". Dieser Shader sorgt dafür dass der Schweif schön hell erscheint.

 

Ändert wenn ihr wollt die "Tint Color" des Materials um den Schweif eine andere Farbe zu verpassen. Zum Beispiel ein helles Blau.

 

Damit wäre der Teil des Tutorials erledigt. Wer möchte kann versuchen bei einem Treffer des Projektils ein anderes PartikelSystem anzuzeigen, wie das geht ist recht einfach, erstellt einfach an der Stelle des Projektils wenn es etwas getroffen hat ein weiteres PartikelSystem. Ihr könnt das leicht mithilfe eines weiteren Prefabs lösen. Dazu könnt ihr die Partikel Klasse erweitern um dieses Prefab als Aufschlagseffekt anzugeben um es im Code per Instantiate zu spawnen.

 

Im angehangenen Unitypackage habe ich dies gemacht, inklusive eines kleinen Scriptes welches automatisch die Effekte zerstört wenn sie zu ende abgespielt wurden. Particle Systeme übernehmen dies leider nicht automatisch.

 

Unitypackage:

https://dl.dropboxus...t6.unitypackage

 

Webplayer:

https://dl.dropboxus...art6/Part6.html

 

Teil 7:

http://forum.unity-c...m-up-teil-7-ki/

Link zu diesem Kommentar
Auf anderen Seiten teilen

ObjectToProject konnte ich nur dann machen, nachdem ich den Partikel-Effekt runter zu den Assets gezogen habe um ein Prefab zu erzeugen. Wahrscheinlich habe das mal wieder überlesen. ^^

Beim Farbverlaufeditor hat bei mir Alpha keine %-Angaben, sondern nur Werte von 0-255, aber Location hat %-Werte.

Der obere linke Schieber steht bei mir den Wert Alpha 0 und Location 10%

Der obere rechte Schieber hat bei mir den Wert Alpha 100 und Location 90%

Ist das Korrekt ?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mhh komisch, ObjectToProject sollte auch mit Objekten in der Szene funktionieren, zumindest geht das so bei mir. Ein Prefab macht da auch kein Sinn, da das Script kein Klon daraus erzeugt.

 

Mit den Farbverlaufseditor hast du aber recht. Wenn ich da schrieb 100% für Alpha meine ich den Wert 255 also das maximum. ich werde das im Tutorial mal korrigieren.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 3 weeks later...

Moin moin, ich hätte mal ne Frage zu dem Partikelsystem das erzeugt wird wenn ein Objekt getroffen wird.

ich hab das jetzt selber mal implementiert und hab einfach in der Klasse Projectile die Methode OnCollisionEnter() um folgendes erweitert:

 

 

var hitparticle = (GameObject)Instantiate(hitParticle, transform.position, transform.rotation);

Destroy(hitparticle, 0.5f);

 

Also das Konstrukt funktioniert super und genau wie ich will, darum geht's mir grad auch gar nicht ^^

Mich würde mich nur interessieren wieso du das so löst. Hast du da nen Hintergedanken der spätere Implementierungen vereinfachen soll?

 

Hätte angedacht den verschiedenen Waffen(systemen) zusätzliche Variablen zu geben, die das Partikelsystem beeinflussen z.B. Farbe, Größe, Lebensdauer der Partikel, etc..

Wäre das sinnvoll oder müsste man da umständlich viel Code schreiben um auf die Particlesettings zu greifen und diese zu verändern?

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 5 months later...
Prefabs haben einfach den Vorteil dass sie wenig extra Arbeit benötigen, so wie du es machst geht es auch, was immer dich zum Ziel bringt ist legitim :)

 

^ Hier hab ich ein Engine-Partikel-System gefunden, welches ich auch benutze.

Wenn man bei Particle Animator die Farben so einstellt, sieht es fast echt aus!

 

Blau, Blau, Rot-Orange, Gelb, Rot

 

Und dann hab ich das Drive-Script erweitert, um die Engine und Bremsen anzuzeigen. (Es ist ein primitives Schubtriebwerk-Raumschiff ;) )

 

Hier ist der Code:

 

using UnityEngine;
using System.Collections;
public abstract class DriveEffects : MonoBehaviour {
public abstract void Accelerate();
public abstract void DeAccelerate();
public abstract void StopDrives();
public abstract void RotateLeft();
public abstract void RotateRight();
}

 

..erst mal eine abstrakte Klasse, um bei verschiedenen Raumschiffen verschiedene Antriebs-Effekte zu generieren.

 

Nun habe ich hinten zwei Partikelsysteme: Engine (Local Space) und Tail (World Space)

Vorn habe ich Brake_Left und Brake_Right, beide im Local Space.

 

Hier ist nun der Code, um meine Schiffseffekte anzuzeigen:

using UnityEngine;
using System.Collections;
public class DriveEffects_SpaceShip : DriveEffects
{
public GameObject particlesThrust;
public GameObject particlesTail;
public GameObject particlesBrakeLeft;
public GameObject particlesBrakeRight;

public override void Accelerate ()
{
 if (particlesTail)
  particlesTail.particleEmitter.emit = true;
 if (particlesThrust)
  particlesThrust.particleEmitter.emit = true;
 if (particlesBrakeLeft)
  particlesBrakeLeft.particleEmitter.emit = false;
 if (particlesBrakeRight)
  particlesBrakeRight.particleEmitter.emit = false;
}
public override void DeAccelerate ()
{
 if (particlesTail)
  particlesTail.particleEmitter.emit = false;
 if (particlesThrust)
  particlesThrust.particleEmitter.emit = false;
 if (particlesBrakeLeft)
  particlesBrakeLeft.particleEmitter.emit = true;
 if (particlesBrakeRight)
  particlesBrakeRight.particleEmitter.emit = true;
}
public override void StopDrives ()
{
 if (particlesTail)
  particlesTail.particleEmitter.emit = false;
 if (particlesThrust)
  particlesThrust.particleEmitter.emit = false;
 if (particlesBrakeLeft)
  particlesBrakeLeft.particleEmitter.emit = false;
 if (particlesBrakeRight)
  particlesBrakeRight.particleEmitter.emit = false;
}
public override void RotateLeft ()
{
 if (particlesBrakeRight)
  particlesBrakeRight.particleEmitter.emit = true;
}
public override void RotateRight ()
{
 if (particlesBrakeLeft)
   particlesBrakeLeft.particleEmitter.emit = true;
}
}

 

Hier werden einfach die jeweiligen Partikelsysteme ein- oder ausgeschaltet.

 

Zieht diese Klasse auf das Raumschiff.

Zieht nun die jeweiligen Partikelsysteme auf die Variablen des Scripts im Inspector.

 

Nun müssen im Drive-Script noch einige Sachen angepasst werden:

Erstmal braucht es eine Start-Methode.

 

// Use this for initialization
void Start () {
 driveEffects = GetComponentInChildren<driveeffects> ();
}

 

Mein Drive-Script ist in einem übergeordneten GameObject als das DriveEffects-Script. (GetComponentInChildren)

 

Dann müssen noch die jeweiligen Steuerungsbefehle angepasst werden.

(Ich hab es mit CurrentForce versucht, doch da schalten die Triebwerke zu spät an. Es muss direkt beim Input anschalten.)

 

public void Accelerate(float factor)
{
 currentForce += Time.deltaTime * acceleration*factor;
 currentForce = Mathf.Clamp(currentForce, minForce, maxForce);
 hasChangedCurrentForce = true;
 if (driveEffects)
  driveEffects.Accelerate();
}
public void DeAccelerate(float factor)
{
 currentForce -= Time.deltaTime * deAcceleration * factor;
 currentForce = Mathf.Clamp(currentForce, minForce, maxForce);
 hasChangedCurrentForce = true;
 if (driveEffects)
  driveEffects.DeAccelerate();
}
public void RotateRight(float factor)
{
 rigidbody.AddTorque(0, Time.deltaTime * rotationAcceleration * factor, 0);
 if (driveEffects)
   driveEffects.RotateRight();
}

public void RotateLeft(float factor)
{
 rigidbody.AddTorque(0, -Time.deltaTime * rotationAcceleration * factor, 0);
 if (driveEffects)
   driveEffects.RotateLeft ();
}

 

Hier wird einfach bei jedem Befehl der jeweilige Befehl im DriveEffects-Script aufgerufen.

 

In der Update-Methode braucht es noch die folgenden Zeilen, um die Engines zu stoppen:

 

 // maybe stop the drives
 if (currentForce == 0 && driveEffects)
  driveEffects.StopDrives ();

 

Hoffe das hilft.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Super Erweiterung, danke. Hast du eventuell ein WebPlayer oder Video dazu parat? Würde mich interessieren wie es wirkt, auch wenn ich es mir so schon prima vorstellen kann.

 

Ich mach dann was, wenn ich alle Tutorials durch habe.

 

 

[FIXED, siehe unten]

Ich habe noch ein Problem: um den Weltraum realistischer zu machen, habe ich noch mal dasselbe Feld kopiert und den Local Space eingeschaltet. Somit hat es Fixsterne. Wenn ich nicht zoomen könnte, würde ich das Teil ja direkt an die Kamera ranhängen, aber Y muss gleich bleiben.

 

Das Problem ist hierbei, dass das fixe Sternenfeld ein bisschen ruckelt beim bewegen. Sogar wenn ich das da mache, ruckelt es:

vector3 pos=transform.position;
pos.y=ObjectToProject.transform.position.y
ObjectToProject.transform.position=pos;

 

Hab schon alles mögliche ausprobiert....hat mir jemand einen Tipp?

 

[EDIT: FIXED]: Statt Update die Funktion "OnPreRender" benutzen, welche das Zeug VOR dem Rendern(Zeichnen) ausführt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

 

danke für das Video, schöne Verwendung des LocalSpaces der PartikelSysteme. Sieht wirklich gut aus.

 

Wegen der Sterne, wenn du feste Sterne willst, dann wäre evtl eine CubeMap/Skybox an der Kamera geeigneter.

 

Ansonsten wenn du es animiert haben willst, dann würde sich auch eine extra Kamera eignen die vor der MainCam gerendert wird und dort nur die statischen Objekte rendert (Sterne, rotierende Planeten, pulsierende Nebel). Dies kann man gut erreichen indem man diese Background Cam mithilfe der Layer so einstellt dass nur eben diese Objekte gerendert werden.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ansonsten wenn du es animiert haben willst, dann würde sich auch eine extra Kamera eignen die vor der MainCam gerendert wird und dort nur die statischen Objekte rendert (Sterne, rotierende Planeten, pulsierende Nebel). Dies kann man gut erreichen indem man diese Background Cam mithilfe der Layer so einstellt dass nur eben diese Objekte gerendert werden.

 

Für mich gibt es nur eine aktive Kamera, keine Ahnung wie man zwei Kameras gleichzeitig rendert.

 

Dann würde die zweite Kamera auf statisches Zeug gucken, welches sich ausserhalb der SIchtweite der Schiffs-Kamera befindet? (Also das statische Zeug oberhalb der main cam hinpflanzen und mit der secondary cam nach oben gucken, damit man keine Planeten (doppelt) sieht, verstehe ich das richtig?)

 

Und die beiden Bilder werden dann zusammengesetzt? ... Sehr interessant...

 

Könntest du da ein Beispiel geben? Danke.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du hast 2 GOs einmal die für die MainCamera und einmal die für die BackgroundCamera. Die MainCamera rendert alles was nicht zum Hintergrund gehört und die BackgroundCamera alles für den Hintergrund, sollte klar sein ;)

 

Folgendes muss nun an den Kameras eingestellt werden..

 

MainCamera

ClearFlags: Depth only, nichts löschen/clearen bis auf den Tiefenbuffer.

CullingMask: Auf alles ausser den BackgroundLayer setzen (Der Layer muss vermutlich neu erzeugt werden, oder man nimmt einen bestehenenden der nur für die Hintergrundobjekte gedacht ist).

 

 

BackgroundCamera

Depth: Eins weniger als die MainCamera, damit die BackgroundCamera VOR der MainCamera gerendert wird.

CullingMask: Nur der BackgroundLayer.

 

Die BackgroundCamera rendert nun nur noch die GOs welche im BackgroundLayer layer liegen und die MainCamera danach alles andere.

 

Die BackgroundKamera kann nun irgendwo hingelegt werden wo sie nicht stört oder sogar noch besser, in eine separate Background Szene die einfach geladen wird wenn die eigentlich Spielszene auch geladen wurde (Application.LoadLevelAdditive), so kann man sich seinen Background ganz gemütlich aufbauen ohne dabei im Editor alles in einem Bereich mixen zu müssen.

 

In der BackgroundSzene/Bereich kann nun alles mögliche platziert werden mit folgendem Effekt: Da die BackgroundCam vor der MainCam gerendert wird hat man nun eine höchst dynamische Skybox.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Application.LoadLevelAdditive), so kann man sich seinen Background ganz gemütlich aufbauen ohne dabei im Editor alles in einem Bereich mixen zu müssen.

 

...das ist einer der geilsten Befehle, die ich in meiner 15jährigen Programmierer-Laufbahn gesehen habe. THUMPS UP! ;)

 

Ich hab euch noch einen Effekt gebastelt.

 

Pseudo-Dynamisches Licht

 

Dreht die y-Achse eines Directional-Lights relativ zu der Player-Position und der Sonnen-Position.

Somit sieht es immer so aus, als würde das Schiff von der Sonne angeleuchtet werden.

 

Also erst mal, bitte eine Sonne erstellen.

Ein Directional-Light solltet ihr schon in der Szene haben. Es ist egal, wo dieses positioniert ist.

 

Setzt bei der Rotation des Lichtes nur die X und Z Achse so wie es euch beliebt. Am besten so 30 und 60 Grad. (Meine Werte)

 

Fügt nun an die Sonne folgendes Script an:

using UnityEngine;
using System.Collections;

public class SunLightDirectionEffect : MonoBehaviour
{
  public Light directionalLight;
  private Transform target;
  // Use this for initialization
  void Start ()
  {
   // get the main cams target, that's the player ship.
   Camera mainCam = Camera.main;
   if (mainCam)
   {
	  CameraController c=mainCam.GetComponent<CameraController>();
	  if(c)
		  target = c.target;
   }
}

  // Update is called once per frame
  void Update ()
  {
   if (target && directionalLight)
   {
	   Vector3 targetDir=target.transform.position-transform.position;
	   float angle=Vector3.Angle(targetDir, Vector3.forward);

	   // wrong angle on left side fix
	   if(target.transform.position.x< transform.position.x)
		  angle=360-angle;
	   // get rotation and euler angles
	   Quaternion rot=directionalLight.transform.rotation;
	   Vector3 euler=rot.eulerAngles;
		// set y
		euler.y=angle;
	   // revert rot to new euler angles.
	   rot.eulerAngles=euler;
	   // revert light.rotation to rot
	   directionalLight.transform.rotation=rot;
   }
  }
}

 

Zieht jetzt noch euer DirectionalLight auf die entsprechende Variable im Script.

 

Jetzt sollte das ganze schon funktionieren.

 

Erklärung:

In Start wird die Main-Kamera geholt.

Diese hat einen CameraController, an den das SpielerSchiff angehängt ist.

(Siehe vorige Tutorials)

Wir setzen nun (unser) target auf das Spielerschiff. (Ich habe es erst mit der MainCam versucht, doch mit der Schiffsposition ist es akkurater. Vor allem wenn man zoomt oder so.)

 

In Update wird nun kontinuierlich der Winkel zwischen den 2 Vektoren herausgefunden, und dann wird jedoch nur die y-Rotation bei der Lichtquelle gesetzt.

 

Diese muss noch angepasst werden, wenn target.x < transform.x ist. Das hat ewigs gedauert, bis ich das raus hatte....

 

Leider muss man dazu (wirklich(?)) erst ein Quaternion getten, dann die eulerAngles, dann diese setzen, dann diese wieder in das Quaternion pushen und dann dieses Quaternion als DirectionalLight.transform.rotation setzen, ansonsten motzt die Engine....

 

Leider konnte ich das Video nicht schneiden.

Ab 0.53 ist der Effekt an. Am Anfang ist er aus.

Guck auf die CheckBox neben "Sun Light Direction Effect"

 

PS: Das Licht ist hell-orange mit grossem Weissanteil.

 

 

Have Fun!

bearbeitet von ben0bi
Link zu diesem Kommentar
Auf anderen Seiten teilen

Warum nicht einfach ein PointLight nehmen?

 

Kann ich das IN der Mitte der Sonne platzieren? Leuchtet es dann daraus heraus? Mal sehen. Ich möchte es nicht darüber platzieren, denn eventuell mach ich die Sonne richtig gross, wenn es denn die Engine erlaubt und es gut aussieht...;)

 

Und eventuell soll ja der Schrägheits-Winkel immer gleich bleiben, dann nützt das was ^ ....ansonsten hab ich mich halt vertan, sorry.

 

Ich werde den obigen Code nächstens noch ein bisschen anpassen für die Licht-Intensität.

Link zu diesem Kommentar
Auf anderen Seiten teilen

"Realtime Shadows for Point- and Spot-Lights require Unity Pro"

 

Also für die Benutzer der freien Version ist das sicher nützlich.

 

Und ich will, dass das Licht immer ein bisschen leuchtet, egal wie weit weg man ist. Dafür kann mans auch brauchen.

 

Hier ist noch der Code für die Licht-Intensität:

 

Erst mal ein paar variablen:

public float minIntensity=0.1f;
public float maxIntensity=2.0f;
public float range=100.0f;

 

Und das da kommt in die Update-Funktion:

 

//-------------------------------------------------------------------------------------------------------------------
  // LIGHT INTENSITY
//-------------------------------------------------------------------------------------------------------------------
  float dist=Vector3.Distance (target.transform.position, transform.position);
  float actualIntensity=0.0f;

  if(dist>=range)
  {
actualIntensity=minIntensity;
  }else{
float ir=maxIntensity-minIntensity;
actualIntensity=((ir/range)*(range-dist))+minIntensity;
  }
  directionalLight.intensity=actualIntensity;

 

Viel Spass!

bearbeitet von ben0bi
Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 years later...

Hallo,

 

ich hoffe man kann mir helfen.

 

ich hab das Tutorial bis hierhin durchgemacht und es funktioniert auch alles. Dann hab ich versucht den Effekt für Projektileinschläge selbst zu schreiben und bin kläglich gescheitert :D dann hab ich mir dein package runtergeladen um mir anzuschauen wie du das ganze geregelt hast.

Allerdings funktioniert das ned so richtig. Ich hab das Package zwar unter unity 5 zum laufen gebracht aber der Effekt is immer noch ned da an was kann das liegen? Ich bin noch nen ziemlicher neuling und hab halt wirklich keinen plan an was es liegt.

 

Gruß Spevil

 

 

Edit: Oh Gott ich bin so ein blutiger Anfänger :D ich hab vergessen im Projektil prefab den Impacteffekt zu setzen... :rolleyes: nun Funktioniert alles so wies soll

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...