Jump to content
Unity Insider Forum

Diskussion, wie man die Maus-Steuerung eines Raumschiffes realisieren könnte


Footloose

Recommended Posts

Hello again ;) 

Ich hab da folgendes Problem:
Ich habe ein Raumschiff mit mehreren Türmen.
Diese Türme tragen Geschütze.
 

Die Türme selbst sollen sich um die y-Achse drehen, was auch wunderbar funktioniert.

public float speed;
 
	void FixedUpdate () 
	{
		
		/*if(!isLocalPlayer) {
			
			return;
		
		}*/
		
    	// Generate a plane that intersects the transform's position with an upwards normal.
    	Plane playerPlane = new Plane(Vector3.up, transform.position);
 
    	// Generate a ray from the cursor position
    	Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
 
    	// Determine the point where the cursor ray intersects the plane.
    	// This will be the point that the object must look towards to be looking at the mouse.
    	// Raycasting to a Plane object only gives us a distance, so we'll have to take the distance,
    	//   then find the point along that ray that meets that distance.  This will be the point
    	//   to look at.
    	float hitdist = 0.0f;
    	// If the ray is parallel to the plane, Raycast will return false.
    	if (playerPlane.Raycast (ray, out hitdist)) 
		{
        	// Get the point along the ray that hits the calculated distance.
        	Vector3 targetPoint = ray.GetPoint(hitdist);
 
        	// Determine the target rotation.  This is the rotation if the transform looks at the target point.
        	Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
 
        	// Smoothly rotate towards the target point.
        	transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
		}
    }

Nun habe ich mir für die Geschütze dasselbe vorgenommen.
Nur sollen sich diese halt um die X-Achse drehen. Dazu habe ich
"Vektor3.up" durch "Vektor3.right" ersetzt (in einem eigenen Script, dass den Guns zugewisen ist,
die Guns sind ChildObjects der Türme).

Leider funktioniert das nicht so wie gewünscht.
Zwar drehen sich die Guns langsam nach unten bzw. oben, aber dafür muss man schon snipen, ansonsten drehen
sie sich auch mal anders, so dass sie sich um den Turm rausdrehen.

Ich finde leider nicht heraus warum das so ist.  Bei der Y-Achse funktioniert das ja, bei der X-Achse nicht.
Vielleicht könnt ihr mir ja helfen.
Wäre jedenfalls super :)

LG Tobi ;) 

Edit:
Schön wärs auch wenn ich die ° der Rotation begrenzen könnte, also zum Beispiel einen Waffenrichtbereich von 45° einbauen könnte.
Vllt. könnt ihr dabei ja auch helfen ;) 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also, vielleicht ist die Lösung auch nicht geeignet?
Wie würdet ihr das machen, dass das Objekt sich (mit einer Speed-Variablen für
die Drehgeschwindigkeit) an den Mauscursor ausrichtet (also in 3D)?

Mein eigener Ansatz wäre es mit

die Position des Mauscursors (ScreenToViewPoint) rauszufinden und mit der Distanzvariablen einen
Abstand zum Spielerschiff herzustellen.
Dann (irgendwie) das Schiff darauf auszurichten, wo dann halt die genannte Speed-Variable zum Einsatz kommt.

Also ungefähr so: 

transform.rotation = Quaternion.Slerp(transform.rotation, /*ZIELROTATION*/, speed * Time.deltaTime);

Ich bräuchte halt eigentlich nur die Zielrotation oder?
 

Sorry aber ich komme da alleine nicht klar mit^^
Ich bin wohl zu doof dafür.

Es gibt ja im Netz viele Lösungen, aber entweder funktionieren die nicht oder sind für mein Problem nicht geeignet :(

 

Ich hoffe sehr ihr könnt mir helfen damit ich endlich mit meinem Schiff rumfliegen kann ;) 

Liebe Grüße,
Tobi :) 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Kannst du mal Screenshots / Bildchen machen, die veranschaulichen was genau du machen möchtest und was aktuell passiert?

Ich hab mal Türme an Raumschiffen gemacht, in einem 3D Spiel. Diese haben sich dann zum Ziel gedreht. Die Geschütze ebenfalls.

Dafür hab ich für jeden Teil des Turms (Drehteller und Kanone) die Koordinate des Ziels in lokale Koordinaten umgerechnet. Dann wusste ich, um wieviel der Turm in eine Achse drehen sollte. Der Teller hat sich um die Y Achse gedreht und das Geschütz um die X Achse. Dann konnte ich relativ gut mit Eulerangles arbeiten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das ist exakt das was ich auch möchte^^

Du hast das quasi gesplittet. y-Achse für die Türme, x-Achse für die Geschütze.
Das möchte ich auch.

Das ganze soll dann kombiniert auch für mein Raumschiff funktionieren.
Als Beispiel habe ich mir "Star Conflict" genommen.

Bei Minute 30 kann man das sehen, dass er das Raumschiff (und die Waffen) mit der Maus steuert
 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also die Lösung nur kurz umrissen und teilweise so wie du schon sagtest:
- Mausposition in Worldkoordinaten bestimmen
- Richtungsvektor vom Raumschiff zur Maus berechnen: forwardDirection = (mousepos3D.transform.position - spaceship.transform.position).normalized;
- Zielrotation berechnen: Quaternion lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.up);
- Raumschiff rotieren: transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, speed * Time.deltaTime);

Eventuell musst du statt Vector3.up auch spaceship.transform.up nehmen, insofern dein Raumschiff auch auf der Seite liegen kann!

PS:
Um die Mausposition um 3D-Raum zu bestimmen, musst du den Abstand zwischen der Z-Koordinate Raumschiffes und der Kamera bestimmen und folgende Funktion verwenden (und dieser Funktion in Z diesen Abstand übergeben):
https://docs.unity3d.com/ScriptReference/Camera.ScreenToWorldPoint.html

Eine Rotation um Z funktioniert mit dieser Methode natürlich am besten. Bei Rotationen um X und Y kann ich nur spekulieren wie geht es funktioniert, da wir ja die Mausposition in Z auf die Position des Raumschiffen legen. Normalerweise müsse man ja beispielsweise für eine Rotation um Y die Position der Maus in Z einmal hinter das Raumschiff und einmal vor das Raumschiff legen..., kann also sein, das Rotationen um X und Y nicht funktionieren ohne das du die Z-Koordinate der Maus entsprechend anpasst. Bei Rotation um Y müsste man die Y-Position der Maus auf die Z-Position hinzuaddieren, um eine räumliche Tiefe zu simulieren. Bei Rotation um X ebenfalls. Vielleicht reicht es, dies generell zu machen..., also den Abstand in Y zwischen Maus und Raumschiff generell auf die Z-Koordinate zu addieren:

float distanceCameraZ = spaceship.transform.position.z - Camera.main.transform.position.z;
Vector3 mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
mousepos3D.z = mousepos3D.z + (mousepos3D.y - spaceship.transform.position.y);

Damit hast du dann auch deinen Abstand zum Raumschiff in Z. Die räumliche Tiefe der Maus wird dann einfach anhand der Y-Koordinate der Maus simuliert. Alles ungetestet, prüfe halt, ob ich nicht noch irgendwo einen Zahlendreher drin hab. Die Umrechnung auf eine 3D-Koordinate sollte stimmen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also, der Link in deinem Post Zer0Cool, ich hab
mal versucht den nachzubauen.

Da gibt es allerdings noch so Punkte die ich noch nicht ganz verstehe (wie zum Beispiel das mit dem Event).
Außerdem weiß ich leider noch nicht so ganz wie ich deienen gezeigten Code anzuwenden habe.

 

public float rotationspeed;
	public Vector3 v3 = new Vector3();
	public Vector2 v2 = new Vector2(); // MousePosition
	public Event e = Event.current;
	public Camera c = Camera.main;
// Get the mouse position from Event
			v2.x = e.mousePosition.x;
			// y from Event is inverted
			v2.y = c.pixelHeight - e.mousePosition.y;
			
			v3 = c.ScreenToWorldPoint(new Vector3(v2.x, v2.y, c.nearClipPlane));
			
			Quaternion targetRotation = Quaternion.LookRotation(v3 - transform.position);
			transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationspeed);

Mein Code führt leider nicht zum Ziel und so 100% verstehe ich das leider auch nicht :( 

Ich bekomme irgendwie vieles nach einiger Zeit zum laufen, nur an dem Problem hänge ich schon echt lange :(

Doch danke schonmal das du mir hilfst :)


LG ;) 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Na, vergiss das Event, das ist aus dem schlechten Unitybeispiel und baut noch auf der alten UnityGUI auf:

using UnityEngine;
using System.Collections;

public class Rotator : MonoBehaviour {

    public float rotationspeed;
    private Transform spaceship;
    private Camera mainCamera;

    // Use this for initialization
    void Start()
    {
        mainCamera = Camera.main;
        spaceship = this.transform;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 mousePos = Input.mousePosition;

        float distanceCameraZ = spaceship.transform.position.z - mainCamera.transform.position.z;
        Vector3 mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
        mousepos3D.z = mousepos3D.z + (mousepos3D.y - spaceship.transform.position.y);
        Debug.DrawLine(mousepos3D, spaceship.transform.position, Color.red);

        Vector3 forwardDirection = (mousepos3D - spaceship.transform.position).normalized;
        Quaternion lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.up);
        transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
    }
}

Funktioniert nicht so ganz wie ich dachte, das Objekt kippt leider zusätzlich in Richtung Mauszeiger, man muss wohl noch die anderen beiden Rotationsachse nfixieren.

Link zu diesem Kommentar
Auf anderen Seiten teilen

using UnityEngine;
using System.Collections;

public class Rotator : MonoBehaviour {

    public float rotationspeed;
    private Transform spaceship;
    private Camera mainCamera;

    // Use this for initialization
    void Start()
    {
        mainCamera = Camera.main;
        spaceship = this.transform;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 mousePos = Input.mousePosition;

        float distanceCameraZ = spaceship.transform.position.z - mainCamera.transform.position.z;
        Vector3 mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
        mousepos3D.z = mousepos3D.z + (mousepos3D.y - spaceship.transform.position.y);
        Debug.DrawLine(mousepos3D, spaceship.transform.position, Color.red);

        Vector3 forwardDirection = (mousepos3D - spaceship.transform.position).normalized;
        Quaternion lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.up);
        
        // Fix X and Z axes
        float originalRotationX = transform.eulerAngles.x;
        float originalRotationZ = transform.eulerAngles.z;
        transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
        transform.eulerAngles = new Vector3(originalRotationX, transform.eulerAngles.y, originalRotationZ);
    }
}

Das ganze funktioniert jetzt erst einmal nur für Rotation um Y. Für die anderen beiden Rotationen müsste man es entsprechend machen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Für alle 3 Achsen. Allerdings muss man für Achse X wohl noch was ändern.

using UnityEngine;
using System.Collections;

public class Rotator : MonoBehaviour
{

    public float rotationspeed;
    private Transform spaceship;
    private Camera mainCamera;
    
    // Nur jeweils eines aktivieren
    public bool rotateX; // funktioniert noch nicht
    public bool rotateY; 
    public bool rotateZ;

    // Use this for initialization
    void Start()
    {
        mainCamera = Camera.main;
        spaceship = this.transform;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 mousePos = Input.mousePosition;

        float distanceCameraZ = spaceship.transform.position.z - mainCamera.transform.position.z;
        Vector3 mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
        mousepos3D.z = mousepos3D.z + (mousepos3D.y - spaceship.transform.position.y);
        Debug.DrawLine(mousepos3D, spaceship.transform.position, Color.red);

        Vector3 forwardDirection = (mousepos3D - spaceship.transform.position).normalized;

        Quaternion lookRotation;
        float originalRotationX;
        float originalRotationY;
        float originalRotationZ;

        if (rotateY)
        {
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.up);

            // Fix X and Z axes
            originalRotationX = transform.eulerAngles.x;
            originalRotationZ = transform.eulerAngles.z;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(originalRotationX, transform.eulerAngles.y, originalRotationZ);
        }


        if (rotateZ)
        {
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.forward);

            // Fix X and Y axes
            originalRotationX = transform.eulerAngles.x;
            originalRotationY = transform.eulerAngles.y;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(originalRotationX, originalRotationY, transform.eulerAngles.z);
        }

        if (rotateX)
        {
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.right);

            // Fix Y and Z axes
            originalRotationY = transform.eulerAngles.y;
            originalRotationZ = transform.eulerAngles.z;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(transform.eulerAngles.x, originalRotationY, originalRotationZ);
        }

    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie gesagt die Rotation um X funktioniert leider nicht, da dies eine Kreisbewegung in Z-Richtung wäre, was mit der Maus eben nicht geht (man kann bestimmt das Koordinatensytem der Maus so drehen, das man mit einer Kreisbewegung in XY der Maus auch die Rotation um X zum Laufen bekommt, aber da stehe ich gerade auf dem Schlauch. Aber du kannst jeweils in Y oder in Z rotieren lassen (nur nicht gleichzeitig).

Link zu diesem Kommentar
Auf anderen Seiten teilen

So noch ein Hack für die Drehung um X. Ich habe dabei die X-Koodinate der Maus dafür verwendet, um die Z-Koordinate zu setzen und damit dreht die virtuelle Maus quasi in die Tiefe.

using UnityEngine;
using System.Collections;

public class Rotator : MonoBehaviour
{

    public float rotationspeed;
    private Transform spaceship;
    private Camera mainCamera;
    public bool rotateX;
    public bool rotateY;
    public bool rotateZ;

    // Use this for initialization
    void Start()
    {
        mainCamera = Camera.main;
        spaceship = this.transform;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 mousePos = Input.mousePosition;

        float distanceCameraZ = spaceship.transform.position.z - mainCamera.transform.position.z;
        Vector3 mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
        mousepos3D.z = mousepos3D.z + (mousepos3D.y - spaceship.transform.position.y);
        Debug.DrawLine(mousepos3D, spaceship.transform.position, Color.red);

        Vector3 forwardDirection = (mousepos3D - spaceship.transform.position).normalized;

        Quaternion lookRotation;
        float originalRotationX;
        float originalRotationY;
        float originalRotationZ;

        if (rotateY)
        {
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.up);

            // Fix X and Z axes
            originalRotationX = transform.eulerAngles.x;
            originalRotationZ = transform.eulerAngles.z;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(originalRotationX, transform.eulerAngles.y, originalRotationZ);
        }


        if (rotateZ)
        {
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.forward);

            // Fix X and Y axes
            originalRotationX = transform.eulerAngles.x;
            originalRotationY = transform.eulerAngles.y;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(originalRotationX, originalRotationY, transform.eulerAngles.z);
        }

        if (rotateX)
        {
            mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
            mousepos3D.z = spaceship.transform.position.z - mousepos3D.x;
            mousepos3D.x = spaceship.transform.position.z;
            forwardDirection = (mousepos3D - spaceship.transform.position).normalized;
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.right);

            // Fix Y and Z axes
            //originalRotationY = transform.eulerAngles.y;
            //originalRotationZ = transform.eulerAngles.z;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            //transform.eulerAngles = new Vector3(transform.eulerAngles.x, originalRotationY, originalRotationZ);
        }

    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn du allerdings die Originalrotation der Achsen des Schiffes die nicht gedreht werden beibehalten möchtest, dann musst du wieder Vector3.up durch this.transform.up ersetzen und Vector3.forward durch this.transform.forward. Die Rotation um X funktioniert dann wiederum nicht mehr.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also so ganz funktioniert das leider noch nicht :( 

So schaut der Script eingebaut in mein Programm aus.
Beim Testen habe ich mein Beschleunigungs-Script auskommentiert, es hatte also keinen Einfluss.
Dein Code wirft auch keine Fehler :) 

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class CorvetteMovement : NetworkBehaviour {
	
	// Zer0Cools Deklarationen
	public float rotationspeed;
    private Transform spaceship;
    private Camera mainCamera;
    public bool rotateX;
    public bool rotateY;
    public bool rotateZ;
	
	void Start () {
	
		mainCamera = Camera.main;
		spaceship = this.transform;
	
	}
	
	// Meine Deklarationen
	public GameObject laserBeamPrefab;
	public Transform laserBeamSpawnt11;
	public Transform laserBeamSpawnt12;
	public Transform laserBeamSpawnt21;
	public Transform laserBeamSpawnt22;
	public Transform laserBeamSpawnt31;
	public Transform laserBeamSpawnt32;
	public Transform laserBeamSpawnt41;
	public Transform laserBeamSpawnt42;
	public float z;
	public float x;

	
	// Update is called once per frame
	void Update () {
		
		// Check if Object is a Player Object
		if(!isLocalPlayer) {
			
			return;
		
		}
		
		// Beschleunigung
		x = Input.GetAxis("Horizontal") * Time.deltaTime * 0.12f;
		z = z + (Input.GetAxis("Vertical") * Time.deltaTime * 0.24f);
		if(z >= 1.64f) {
			
			z= 1.6f;
			
		}
		transform.Translate(x, 0, 0);
		transform.Translate(0, 0, z);
		// Ende des Beschleunigungsscripts
		
		// Zer0Cools Script Anfang
        Vector3 mousePos = Input.mousePosition;

        float distanceCameraZ = spaceship.transform.position.z - mainCamera.transform.position.z;
        Vector3 mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
        mousepos3D.z = mousepos3D.z + (mousepos3D.y - spaceship.transform.position.y);
        Debug.DrawLine(mousepos3D, spaceship.transform.position, Color.red);

        Vector3 forwardDirection = (mousepos3D - spaceship.transform.position).normalized;

        Quaternion lookRotation;
        float originalRotationX;
        float originalRotationY;
        float originalRotationZ;

        if (rotateY)
        {
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.up);

            // Fix X and Z axes
            originalRotationX = transform.eulerAngles.x;
            originalRotationZ = transform.eulerAngles.z;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(originalRotationX, transform.eulerAngles.y, originalRotationZ);
        }


        if (rotateZ)
        {
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.forward);

            // Fix X and Y axes
            originalRotationX = transform.eulerAngles.x;
            originalRotationY = transform.eulerAngles.y;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(originalRotationX, originalRotationY, transform.eulerAngles.z);
        }

        if (rotateX)
        {
            mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
            mousepos3D.z = spaceship.transform.position.z - mousepos3D.x;
            mousepos3D.x = spaceship.transform.position.z;
            forwardDirection = (mousepos3D - spaceship.transform.position).normalized;
            lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.right);

            // Fix Y and Z axes
            //originalRotationY = transform.eulerAngles.y;
            //originalRotationZ = transform.eulerAngles.z;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            //transform.eulerAngles = new Vector3(transform.eulerAngles.x, originalRotationY, originalRotationZ);
        }
		
		// Zer0Cools Script Ende
    }
}

Also was passiert?
Ich habe verschiedene Szenarios getestet:

1.) Nur X: 
Das Schiff dreht sich einmal komisch nach hinten. Schwer zu beschreiben. Erst nach oben, dann nach hinten.
Danach bewegt es sich gar nicht mehr, auch wenn ich mit der Maus was mache.

2.) Nur Y:
Das Schiff dreht sich kurz schnell nach Links und dann langsam wieder zurück. Danach passiert auch nichts mehr, egal was
ich mit der Maus mache. Der Lichtblick ist dass ich in meinem Programm erst auf "Host" drücken muss, damit das Schiff spawnt.
Ich denke dass es sich deshalb kurz nach links dreht, weil ich mit der Maus von Links komme. Warum der aber nicht da bleibt und
danach nichts mehr passiert wenn ich die Maus bewege, weiß ich leider nicht.
Edit: Auch wenn ich mit der Maus links bleibe dreht der sich zurück (genau gleich), dürfte also doch nicht an der Maus liegen.
 

3.) Nur X:
Das Schiff dreht sich um seitlich (nach rechts) im Kreis, unaufhörlich.

4.) Y und X:
Ähnliches Problem wie bei Szenario 3.
Das Raumschiff dreht sich erst nach rechts (ca. 180°), dann nach links, dann wieder nach rechts usw.
 

Ich konnte mich mit deinem Script nicht genau genug beschäftigen und muss jetzt auch erstmal Essen holen.
An sich würde ich sagen dass dein Script irgendwie falsche Mauskoordinaten bekommt, übergibt oder die Koordinaten nicht richtig verwendet.

Vielleicht findest du ja den Fehler und denkst dir "Oh Mann wie kann mir das nur passieren" ;) 
Ich schaue nachher auch noch mal drüber.
 

Danke nochmal für die Mühe die du dir machst :)

Liebe Grüße,
Tobi ;) 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Schwer zu sagen, warum es bei dir nicht funktioniert. Ich habe bei deinem Skript NetworkBehaviour durch MonoBehaviour ersetzt und einen Cube genommen. Z steht auf 0.01 und X auf 10. Die Kamera steht dabei statisch vor dem Objekt, könnte sein, daß eine sich frei bewegende Kamera Probleme macht, evtl. auch eine Verfolgerkamera. Auf jeden Fall darf die Kamera nicht unter dem Raumschiff hängen.
https://uploadfiles.io/ymnaz

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hier noch einmal eine ganz andere Variante, damit bewegt sich das Raumschiff auf die Mouseposition zu (LookAt = true / Rest = false). Der Flug in Z-Richtung ist natürlich etwas eingeschränkt. da wir die Y-Position der Maus in eine Z-Koordinate gewandelt haben.

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class CorvetteMovement : MonoBehaviour
{

    // Zer0Cools Deklarationen
    public float rotationspeed;
    private Transform spaceship;
    private Camera mainCamera;
    public bool rotateX;
    public bool rotateY;
    public bool rotateZ;
    public bool LookAt;
    public bool localRotation = false;

    void Start()
    {

        mainCamera = Camera.main;
        spaceship = this.transform;

    }

    // Meine Deklarationen
    public GameObject laserBeamPrefab;
    public Transform laserBeamSpawnt11;
    public Transform laserBeamSpawnt12;
    public Transform laserBeamSpawnt21;
    public Transform laserBeamSpawnt22;
    public Transform laserBeamSpawnt31;
    public Transform laserBeamSpawnt32;
    public Transform laserBeamSpawnt41;
    public Transform laserBeamSpawnt42;
    public float z;
    public float x;


    // Update is called once per frame
    void Update()
    {

        // Beschleunigung
        x = Input.GetAxis("Horizontal") * Time.deltaTime * 0.12f;
        z = z + (Input.GetAxis("Vertical") * Time.deltaTime * 0.24f);
        if (z >= 1.64f)
        {

            z = 1.6f;

        }
        transform.Translate(x, 0, 0);
        transform.Translate(0, 0, z);
        // Ende des Beschleunigungsscripts

        // Zer0Cools Script Anfang
        Vector3 mousePos = Input.mousePosition;

        float distanceCameraZ = spaceship.transform.position.z - mainCamera.transform.position.z;
        Vector3 mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
        mousepos3D.z = mousepos3D.z + (mousepos3D.y - spaceship.transform.position.y);
        //Debug.DrawLine(mousepos3D, spaceship.transform.position, Color.red);

        Vector3 forwardDirection = (mousepos3D - spaceship.transform.position).normalized;

        Quaternion lookRotation;
        float originalRotationX;
        float originalRotationY;
        float originalRotationZ;


        if (LookAt)
        {
            transform.LookAt(mousepos3D);
        }


        if (rotateY)
        {
            if (localRotation) lookRotation = Quaternion.LookRotation(forwardDirection, this.transform.up);
            else lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.up);

            // Fix X and Z axes
            originalRotationX = transform.eulerAngles.x;
            originalRotationZ = transform.eulerAngles.z;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(originalRotationX, transform.eulerAngles.y, originalRotationZ);
        }


        if (rotateZ)
        {
            if (localRotation) lookRotation = Quaternion.LookRotation(forwardDirection, this.transform.forward);
            else lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.forward);

            // Fix X and Y axes
            originalRotationX = transform.eulerAngles.x;
            originalRotationY = transform.eulerAngles.y;
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            transform.eulerAngles = new Vector3(originalRotationX, originalRotationY, transform.eulerAngles.z);
        }

        if (rotateX)
        {
            mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, distanceCameraZ));
            mousepos3D.z = spaceship.transform.position.z - mousepos3D.x;
            mousepos3D.x = spaceship.transform.position.z;
            forwardDirection = (mousepos3D - spaceship.transform.position).normalized;

            if (localRotation) lookRotation = Quaternion.LookRotation(forwardDirection, this.transform.right);
            else lookRotation = Quaternion.LookRotation(forwardDirection, Vector3.right);
            Debug.DrawLine(mousepos3D, spaceship.transform.position, Color.red);

            // Fix Y and Z axes
            if (localRotation)
            {
                originalRotationY = transform.localEulerAngles.y;
                originalRotationZ = transform.localEulerAngles.z;
                transform.localRotation = Quaternion.Slerp(transform.localRotation, lookRotation, rotationspeed * Time.deltaTime);
                transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, originalRotationY, originalRotationZ);
            } else
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, rotationspeed * Time.deltaTime);
            }

            // Zer0Cools Script Ende
        }
    }
}

So ganz optimal ist die Lösung vermutlich für deinen Anwendungsfall nicht, vor allem dadurch, wenn sich dein Raumschiff bewegt, dann verdreht es sich im Raum und es liegt nicht mehr parallel zu den Worldkoordinatenachsen. Derzeit dreht das Skript das Raumschiff immer nach den Worldkoordinatenachsen und nicht nach den lokalen Achsen des Schiffes. Ich habe eben noch eine lokale Rotation eingebaut, aber diese funktioniert wie immer nur für Y und Z. Seltsamerweise dreht er in X immer nur um 50%, ich aber keine Ahnung woran das liegt. Normal sollte man ja denken das Koordinatensystem verhalt sich symmetrisch, scheint aber für die Funktion "LookRotation" nicht zu gelten. Ich habs mal mit eingebaut, wenn du es auf "LocalRotation" und "Rotate X" einstellst siehst du es, es dreht dann nur um 180 Grad und nicht um 360.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Naja ich habe natürlich eine Verfolgerkamera. Der Spieler will ja auch bei dem Raumschiff bleiben ;)

Also leicht erhöht hinter dem Raumschiff.

Ich nehme mal an es reicht fürs erste wenn das Raumschiff sich nach links und rechts sowie nach oben und unten drehen kann.
Das soll ja ohnehin nur ein Prototyp werden.

Ich teste das auch mal an meinem Raumschiff aus, sollte ja eigentlich kein Unterschied zu deinem Cube sein.

LG ;) 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Test1.aviAlso, solange ich nur(!) die Y-Achse aktiviere, funktioniert wenigstens diese eine Achse.
Das Video ist leider nicht sehr flüssig muss da nochmal in den Einstellungen meines Recorder-Programms schauen.

LookAt scheint schon nicht so zu funktionieren wie es soll. Da hängt der zwar schön an der Maus, allerdings doch etwas komisch^^
Die X-Achse funktioniert auch nicht so ganz, ebenso die Z-Achse.
Das mit der LocalRotation muss ich nochmal schauen, hab da keinen Unterschied feststellen können. Vllt. hab ich das auch falsch getestet.

Ich hoffe wir finden da überhaupt eine Lösung, ich meine, irgendwie muss das doch möglich sein oder? :D 

Test1.avi

LG ;) 

Edit: Ich weiß nicht aber vielleicht hilft sowas?
Das scheint was mit der Mausposition zu tun zu haben^^
https://www.assetstore.unity3d.com/en/#!/content/66097

Link zu diesem Kommentar
Auf anderen Seiten teilen

Naja, wie ich schon sagte, das Rotieren über die Mausposition hat so ein paar Probleme.
2 Dinge stören das Rotieren über die Mauspostion:
1) Wenn sich das Raumschiff während der Rotation selbst bewegt.
2) Wenn die Kamera zu dicht am Raumschiff ist.
3) Wenn ein anderes Skript die Kamera selbst bewegt.
und eine Rotation um 2 Achsen gleichzeitig kann nicht funktionieren, d.h. du darfst immer nur entweder RotateX, RotateY oder RotateZ aktivieren.
Was ich komisch fand, war die Rotation um Z, wo der Mauszeiger still stand, hier sollte das Raumschiff eigentlich nicht rotieren. Nimm vielleicht mal die letzte Version des Skriptes und teste auch mal die Einstellung "Lokal Rotation" aus.

Zusammenfassend bin ich mir nicht sicher, ob die Lösung evtl. schon zu komplex ist. Ich dachte einfach du nimmst du aus dem Code die entsprechenden Sachen raus, die du brauchst und passt es solang an bis es passt. Da sich dein Raumschiff bewegt und noch eine bewegliche Kamera im Spiel ist, ist es schwer ein allgemein funktionierendes Skript zu entwerfen. Ich bin mir auch nicht sicher, was genau genau das Ziel ist, eine Steuerung des Raumschiffes oder eine Rotation des Raumschiffes (für eine einfache Rotation eines stehenden Objektes mit einer stationären Kamera)?

Für eine Steuerung wäre vielleicht eine (einfachere) Lösung besser, die das Raumschiff einfach mit Hilfe der Maus in alle Richtungen des Raumes rotiert. Hier ein entsprechendes Skript das ich schnell aus einem anderen Skript für eine ("Free Movement")Kamera modifiziert habe. Die Linke Maustaste aktiviert die Rotation, über die beiden Schalter kannst du jeweils einstellen, ob über eine Achse oder 2 Achsen rotiert werden soll:

using UnityEngine;
using System.Collections;

public class RotateObject : MonoBehaviour
{
    //
    // VARIABLES
    //

    public float turnSpeed = 4.0f; // Speed of camera turning when mouse moves in along an axis
    public bool RotateX = true;
    public bool RotateY = true;

    private Vector3 mouseOrigin;   // Position of cursor when mouse dragging starts
    private bool isRotating;       // Is the camera being rotated?

    void Update()
    {

            // Get the left mouse button
            if (Input.GetMouseButtonDown(0))
            {
                // Get mouse origin
                mouseOrigin = Input.mousePosition;
                isRotating = true;
            }

            // Disable movements on button release
            if (!Input.GetMouseButton(0)) isRotating = false;

            // Rotate camera along X and Y axis
            if (isRotating)
            {
                Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);

                if (RotateX) transform.RotateAround(transform.position, transform.right, pos.y * turnSpeed);
                if (RotateY) transform.RotateAround(transform.position, Vector3.up, -pos.x * turnSpeed);
            }
    }
}


Man könnte nun auch dieses Skript noch soweit verändern. daß es an dieser Stelle "pos.y" und "-pos.x" sich an der Lage das Mauszeigers (relativ zum Raumschiff) im 3D-Raum orientiert.

using UnityEngine;
using System.Collections;
using Opsive.ThirdPersonController;

public class RotateObject : MonoBehaviour
{
    //
    // VARIABLES
    //

    public float turnSpeed = 1.0f; // Speed of camera turning when mouse moves in along an axis
    public bool RotateX = true;
    public bool RotateY = true;

    private Vector3 mouseOrigin;   // Position of cursor when mouse dragging starts
    private bool isRotating;       // Is the camera being rotated?

    private Vector3 forwardDirection;

    void Update()
    {

        // Get mouse origin
        mouseOrigin = Input.mousePosition;
        isRotating = true;

        float distanceCameraZ = this.transform.position.z - Camera.main.transform.position.z;
        Vector3 mousepos3D = Camera.main.ScreenToWorldPoint(new Vector3(mouseOrigin.x, mouseOrigin.y, distanceCameraZ));
        mousepos3D.z = mousepos3D.z + (mousepos3D.y - this.transform.position.y);
        Debug.DrawLine(mousepos3D, this.transform.position, Color.red);

        forwardDirection = (mousepos3D - this.transform.position);


        // Disable movements on button release
        if (!Input.GetMouseButton(0)) isRotating = false;

        // Rotate camera along X and Y axis
        if (isRotating)
        {
            Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
            if (RotateX) transform.RotateAround(transform.position, transform.right, forwardDirection.y * turnSpeed);
            if (RotateY) transform.RotateAround(transform.position, Vector3.up, forwardDirection.x * turnSpeed);

        }
    }
}

Der Nachteil (oder Vorteil) hier ist eben, daß das Objekt eben weiter rotiert, auch wenn die Position der Maus erreicht ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Bin mir nicht sicher. ob ich verstehe was du meinst. Das 2.Skript (Version B ) dreht das Raumschiff einfach um einen gewissen Betrag (abhängig von dem Abstand der Maus zum Raumschiff). Es "weiß" daher nicht, wann es zuviel gedreht hat. Ein Rotation exakt auf die Mausposition hat nur mein 1. Skript gemacht, aber das hat ja so seine Macken, mit der Lage des Raumschiffes im Raum und der Lage der Kamera. Ich denke generell eine gute Raumschiffsteuerung ist mal eben nicht im Handumdrehen gemacht, man muss viel ausprobieren und experimentieren. Du hast nun ein paar Varianten. Die  1 Skriptvariante dreht "eigentlich" das Raumschiff auf die Mausposition, funktioniert aber eben nur um jeweils eine Achse und die X-Achse macht zusätzlich Probleme (bin mir immer noch nicht sicher, woran das genau liegt, vermutlich ein "unschönes" Verhalten der LookRotation-Funktion - wie ein plötzlicher "Flip" bei der Ausrichtung). 
Vielleicht reicht es dir auch, wenn das Raumschiff immer in Richtung der Maus "blickt" und sich dorthin bewegt (das wäre die Variante LookAt vom 1. Skript). Vielleicht muss man sich nun auch Gedanken darüber machen, wie die Steuerung eigentlich genau aussehen soll. Es wäre ja auch eine (Rotations)-Variante komplett ohne Beachtung der Mausposition denkbar. Rotieren einfach über Keys und vielleicht nur ein Bewegen des Schiffes von Position A nach B über einen Mausklick (Point & Click) in Verbindung mit LookAt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...