Jump to content
Unity Insider Forum
Mark

Wir bauen uns ein Space Shoot em Up [Teil 3 - Antrieb]

Recommended Posts

Um das automatische abbremsen zu deaktivieren reicht es aus dieses if hier zu erweitern:

 

if (!hasChangedCurrentForce)

 

zu:

 

if (!hasChangedCurrentForce && allowAutoBrake)

 

Wobei allowAutoBrake dann das bool ist was angibt ob automatisch abgebremst werden soll oder nicht.

 

Den Antrieb komplett deaktivieren kannst du indem du

 

rigidbody.AddForce(CurrentForce * Time.deltaTime * transform.forward);

 

Entweder hinter einer Bedingung versteckst oder CurrentForce auf 0 setzt (was ja eigentlich Autobrake macht).

 

Zusätzlich musst du den Drag Wert des Rigidbodies auf 0 setzen, denn dies ist quasi der Luftwiederstand (machts Steuern einfacher wenns gesetzt ist).

Share this post


Link to post
Share on other sites

Wenn ich pro Sekunde eine gewisse Kraft auswirken möchte ist das doch ok, oder hab ich irgendwas grandios falsch gemacht/übersehen?

Share this post


Link to post
Share on other sites

Woah, ich krieg' noch nen Krampf. Hatte irgendwo im Hinterstübchen gespeichert, dass AddForce das intern schon drauf multipliziert. Hab's gerade nochmal gestestet, ist Käse.

Share this post


Link to post
Share on other sites

Ich habe die Drive-Klasse neu geschrieben und vereinfacht (max- und minForce braucht es nicht mehr.)

 

Damit kann man sich nun realistisch im Weltraum bewegen.

(Dazu muss man beim Rigidbody "Drag" auf 0 stellen.)

 

--> @Marrrk: Das ist das Problem bei deiner Drive-Klasse: Die Geschwindigkeit wird in der Physik nicht begrenzt. Deshalb bekommt man unendliche Geschwindigkeit, wenn man bei dir "Drag" auf 0 stellt.

 

Wenn man Enter (bei mir) drückt, dreht sich das Raumschiff - in die kürzere Richtung (wenn backThrustForce > 0) bzw. mit dem Hauptantrieb gegen die Flugrichtung und gibt DANN Gas (bzw. bremst ab) - kürzere Richtung: wenn das Schiff fast in Flugrichtung gedreht ist UND es einen "Back-Thruster" hat, dann dreht es sich VORWäRTS in Flugrichtung und bremst mit dem BACK-Thruster ab....

 

maxSpeed ist der Speed in Units/Sekunde. Das finde ich ein bisschen genauer als mit Force.

 

Der Speed wird direkt an rigidbody.velocity begrenzt.

sqrSpeed ist nur für die Performance da, man könnte es auch "nur" mit maxSpeed machen.

 

Es gibt noch zwei Funktionen: "Halt" und "ResetHalt", welche in "Drive.cs" als virtual deklariert sind.

Sie setzen einfach den bool isHalting auf true bzw. false.

 

"Halt" (hier) dreht das Schiff und bremst ab.

 

Im PlayerController noch diese Linien einfügen:

 

DriveEffects habe ich woanders schon erklärt, das könnt ihr ignorieren. ;)

 

Update()
{
...
if(Input.GetKey(Key.Enter)
drive.Halt();
else
  drive.ResetHalt();
...
}

 

Hier ist mal der komplette Code, es ist mitten in der Nacht....weitere Erklärungen gibts auf Anfrage.

DriveEffects könnt ihr ignorieren, bzw. hab ich schon irgendwo erklärt.

 

Der bool backThrust sollte anders heissen, back=hinten - also wenn true = main-engine und nicht die vorderen...O.o

 

using UnityEngine;
using System.Collections;
public class Drive_Thruster_noDrag : Drive
{
// Max velocity in units/second (?)
public float maxSpeed = 20.0f;
// force to push forward
public float thrustForce = 300.0f;
// force to push backwards
public float backThrustForce = 150.0f;
public float rotationForce=3000.0f;

protected float currentForce;
protected float sqrSpeed;
protected float controlSpeed=0.0f;
protected bool backThrust = false;

// rotation to turn to when halting.
protected Quaternion targetRotation;

public override void RotateRight(float factor)
{
 Static.FindRigidBody(transform).rigidbody.AddTorque(0, Time.deltaTime * rotationForce * factor, 0);
 if (driveEffects)
driveEffects.RotateRight();
}

public override void RotateLeft(float factor)
{
	Static.FindRigidBody(transform).AddTorque(0, -Time.deltaTime * rotationForce * factor, 0);
 if (driveEffects)
driveEffects.RotateLeft ();
}

public override void Accelerate(float factor)
{
	currentForce = thrustForce*factor;
	if (driveEffects)
		driveEffects.Accelerate();
}
public override void DeAccelerate(float factor)
{
	currentForce = -(backThrustForce*factor);
	if (driveEffects)
		driveEffects.DeAccelerate();
}
public override void Halt(float factor)
{
	Rigidbody rb=Static.FindRigidBody(transform);
	if(!rb)
		return;

	Vector3 lookRotation = new Vector3(rb.velocity.x, 0.0f, rb.velocity.z);
	if (lookRotation == Vector3.zero)
		return;
	GameObject ship = Static.FindShip(gameObject);
	if (!ship)
		ship = gameObject;
	float sy = ship.transform.rotation.eulerAngles.y;
	if (!isHalting)
	{
		backThrust = false;
		if (backThrustForce > 0)
		{
			// check if forward angle is smaller than backward angle.
			// [TODO]: Works not properly! (y=0 / 180)
			float yf = Quaternion.LookRotation(lookRotation).eulerAngles.y;
			float yb = Quaternion.LookRotation(-lookRotation).eulerAngles.y;
			float forwardAngle = Mathf.Abs(sy - yf);
			float backwardAngle = Mathf.Abs(sy - yb);
			if (forwardAngle > backwardAngle)
			{
				lookRotation = -lookRotation;
				backThrust = true;
			}
		}
		else
		{
			// if there is no back thruster, just switch the forward rotation to backward,
			// so the main thruster looks into the forward direction.
			lookRotation = -lookRotation;
			backThrust = true;
		}
		// set the target rotation.
		targetRotation = Quaternion.LookRotation(lookRotation);
	}else{
		// AI Script to rotate and stop the drives.
		float ty = targetRotation.eulerAngles.y;
		if (sy - ty >= 5.0f)
		{
			RotateLeft(1.0f);
		}
		else if (sy - ty <= -5.0f)
		{
			RotateRight(1.0f);
		}else{
			if (rb.velocity.magnitude > 2.0f)
			{
				if (backThrust)
					Accelerate(1.0f);
				else
					DeAccelerate(1.0f);
			}
		}
	}
	//transform.rotation=Quaternion.LookRotation(lookRotation);
	base.Halt(factor);
}

void Update()
{  
	if (maxSpeed != controlSpeed)
	{
		controlSpeed = maxSpeed;
		sqrSpeed = maxSpeed * maxSpeed;
	}
	// stop the drives, they will be started when a button is pressed.
	if (driveEffects)
		driveEffects.StopDrives();
}
void FixedUpdate()
{
	Rigidbody rb = Static.FindRigidBody(transform);
	if (!rb)
		return;
	rb.AddForce(currentForce * Time.deltaTime * transform.forward);
	currentForce = 0.0f;
	// limit the rigidbodys velocity.
	var v = rb.velocity;
	if (v.sqrMagnitude > sqrSpeed)
		rb.velocity = v.normalized * maxSpeed;
}
}

Share this post


Link to post
Share on other sites

Moin Moin,

könnte mir hier mal jemand helfen?

Was genau dies hier macht?

var forwardFactor = Vector3.Dot(transform.forward, rigidbody.velocity);

Kann das mal jemand erklären was genau in der Variable gespeichert wird?

Danke schon mal. 

Share this post


Link to post
Share on other sites

Join the conversation

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

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

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

Loading...

×
×
  • Create New...