Jump to content
Unity Insider Forum

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


Mark

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...

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;
}
}

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 5 years later...

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