Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

1

31.10.2012, 13:42

Unity3d Objekt bewegen ohne Beachtung der Rotation

Hi,
schon wieder eine Unity3d/C#-Frage von mir, ich glaube diesmal ist es aber leicht zu lösen, ich weiß nur noch nicht wie :S

Also, als Objekt habe ich eine Kamera. Diese wird durch die Tasten WASD gesteuert.
Hier mal ein Ausschnitt für die Aktion beim Druck der Taste W:

C#-Quelltext

1
transform.Translate(0, 0, 0.03f);

Die Kamera kann auch gedreht werden, hier mal ein Beispiel für die obere Pfeiltaste:

C#-Quelltext

1
transform.Rotate(-0.8f, 0, 0);


Allerdings wenn man nun im Spiel erst etwas nach oben schaut, und dann mit W geht, "fliegt" man immer weiter vorwärts+gewinnt an Höhe.

Meine Frage also:
Wie kann ich von einem Objekt nur die Z-Koordinate verändern, da mit der Translate-Methode man sich ja immer in "Blickrichtung" bewegt?

Und ja, Google hab ich schon bemüht, allerdings konnte ich nichts passendes finden, nur solche Methoden zum Abfragen der Z-Koordinate, ich will diese aber festlegen...

Danke schon mal für eure Hilfe!

Gruß,
MitgliedXYZ

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

2

31.10.2012, 17:47

Also dass du Google bemüht hast, glaube ich dir nicht so ganz...

Zitat

If relativeTo is left out or set to Space.Self the movement is applied relative to the transform's local axes. (the x, y and z axes shown when selecting the object inside the Scene View.) If relativeTo is Space.World the movement is applied relative to the world coordinate system.
Quelle: Unity Script Reference ;)

Also:

C#-Quelltext

1
transform.Translate(0, 0, 0.03f, Space.World);


Mfg Harry222

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

3

31.10.2012, 20:19

Ähm doch, auf so etwas bin ich gestoßen, aber das hab ich wohl überflogen...

Auf jedenfall Danke! Problem gelöst :thumbup:

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

4

01.11.2012, 16:59

Ähm ja, ich weiß, Doppelposts sind nervig, sorry.

Bei der Rotation funktioniert das aber nicht.

Hier mal der Code für die Linke Pfeiltaste:

C#-Quelltext

1
transform.Rotate(0, -0.8f, 0, Space.World);

(Wie die anderen Pfeiltasten aussehen, kann man sich ja jetzt denken :rolleyes: )

Wenn ich aber jetzt wieder um ca. 45° nach oben schaue und dann die linke Pfeiltaste drücke, kann ich die Ansicht sogar auf den Kopf drehen.
Ich dachte das wenn ich "Space.World" dazuschreibe, würde Unity immer von den Standardachsen ausgehen, oder geht das nur bei "translate", nicht aber bei "rotate"?
Zudem nutzt mir "Space.World" nicht wirklich etwas, denn wenn ich die Kamera jetzt um 90° nach links drehe, und dann W (zum vorwärtslaufen) drücke, bewege ich mich jetzt natürlich seitwärts :hmm:

Hat jemand vielleicht eine bessere Idee, wie ich ein first-person Ansicht umsetzen könnte, ohne das Charakter-Controler Objekt zu nutzen?

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

5

01.11.2012, 18:08

Also ich weiß jetzt nicht genau, was dann passiert, wenn man das bei rotate dazusetzt, aber ich hatte in meinem Post nur von translate geredet! ;)

Mfg Harry222

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

6

01.11.2012, 18:10

Also ich weiß jetzt nicht genau, was dann passiert, wenn man das bei rotate dazusetzt, aber ich hatte in meinem Post nur von translate geredet! ;)

Mfg Harry222
Ich weiß schon, dachte nur ich könnte es vielleicht auch bei "Rotate" benutzen, da hat es aber keine Wirkung ;(

Gruß,
MitgliedXYZ

Renegade123

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

7

02.11.2012, 00:11

Hey XYZ,

ich habe vor kurzem eine Strategy Kamera gebaut und hatte die selben Probleme, weil man mit einem Winkel auf die Karte sieht. Hier der Code der dir helfen könnte:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using UnityEngine;
using System.Collections;

public class CameraMove : MonoBehaviour {
    
    //TODO: there arent any borders which stops zu from scrolling of the map
    
    //some public stuff
    public float movingSpeed = 5.0f;
    public float scrollingSpeed = 5.0f;
    public float rotationSpeed = 5.0f;
    public float maxScrollingHeight = 50.0f;
    public float minScrollingHeight = 50.0f;
    public bool showMouse = true;
    
    
    //Directions
    private Vector3 forward = Vector3.forward;
    private Vector3 back = Vector3.back;
    private Vector3 left = Vector3.left;
    private Vector3 right = Vector3.right;
    
    
    //For rotating around
    private RaycastHit hit;
    private Ray ray;
    //"Map"
    private LayerMask layerMask = 1 << 8;
    
    // Use this for initialization
    void Start () {
        if(showMouse)
        {
            Screen.showCursor = true;
        }
        else
        {
            Screen.showCursor = false;
        }
        
    }
    
    // Update is called once per frame
    void Update () {
        //Checking for Window Scrolling
        WindowScrolling(Input.mousePosition,movingSpeed,Input.GetAxis("Horizontal"),Input.GetAxis("Vertical"));
        //Scrolling in and out
        MouseWheelScrolling(Input.GetAxis("Mouse ScrollWheel"), scrollingSpeed);
        //Rotate the Camera
        MouseRotation(Input.GetKey(KeyCode.Mouse2), rotationSpeed);
    }
    
    
    void WindowScrolling(Vector3 mousePos, float speed, float horizontalAxis, float verticalAxis)
    {
        //width
        if(mousePos.x <= 0.0f || horizontalAxis < -0.2f)
        {
            Scrolling(left, speed);
        }
        else if(mousePos.x >= Screen.width || horizontalAxis > 0.2f)
        {
            Scrolling(right, speed);
        }
        //height
        if(mousePos.y <= 0.0f || verticalAxis < -0.2f)
        {
            Scrolling(back, speed);
        }
        else if(mousePos.y >= Screen.height || verticalAxis > 0.2f)
        {
            Scrolling(forward, speed);
        }
    }
    
    void MouseWheelScrolling(float scrolling, float speed)
    {
        //up
        if(transform.position.y < maxScrollingHeight && scrolling < 0.0f)
        {
            Scrolling(Vector3.up, scrollingSpeed);
        }
        //down
        else if(transform.position.y > minScrollingHeight && scrolling > 0.0f)
        {
            Scrolling(Vector3.down, speed);
        }
    }
    
    
    void MouseRotation(bool isKeyDown, float speed)
    {
        if(isKeyDown)
        {   
            ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, 0.0f));
            
            //if mouseposition < the middle of the screen rotate left and > rotate right
            float tempSpeed = Screen.width * 0.5f - Input.mousePosition.x;
            
            //adjustment and speed multiplikation
            tempSpeed *= speed * Time.deltaTime * 0.1f;
            
            //sending a ray to the map...
            //ps: wtf,why does the layermask not work?
            if(Physics.Raycast(ray,out hit,Mathf.Infinity,layerMask))
            {
                //...and rotating around
                transform.RotateAround(hit.point,Vector3.up,tempSpeed);
                //calculate the new directions for moving the camera
                NewDirectionsUntilRotation(hit.point);
            }
        }
    }
    
    //-----------------------
    //Helpfunctions
    //-----------------------
    
    //For moving and scrolling in a direction with a speed
    void Scrolling(Vector3 direction, float speed)
    {
        transform.position += direction * speed * Time.deltaTime;
    }
    
    //To calculate the new directions after rotating the Camera
    void NewDirectionsUntilRotation(Vector3 rotationPoint)
    {
        //x---z    x is the camera position, y is the hit of the ray
        //-\--|    and z is our new position to calculate the directions
        //--\-|    norm(z-x) is the new forward
        //---\|
        //----y
        
        Vector3 upperMiddlePos = new Vector3(rotationPoint.x,transform.position.y,rotationPoint.z);
        forward = upperMiddlePos - transform.position;
        forward.Normalize();
        
        back = -forward;
        
        left = transform.TransformDirection(Vector3.left);
        right = transform.TransformDirection(Vector3.right);
    }
}


lg René
Liebe Grüße,
René

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

8

04.11.2012, 11:06

Danke schon mal für deinen Code, auch wenn er mir irgendwie nicht direkt hilft, aber vielleicht später mal...

Mir ist jetzt noch eine andere Möglichkeit eingefallen, aber dazu müsste ich, ohne Beachtung der aktuellen Werte, den Y-Achsenwert neu festlegen.
Gibt es dafür evtl. eine Möglichkeit?

Renegade123

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

9

05.11.2012, 18:19

Neu berechnen bedeutet, das du den Up-Vektor für das lokale Koordinatensystem im Weltkoordinatensystem haben möchtest?

Speicher dir am besten den Up-Vektor und verändere ihn jedes mal wenn du rotierst mit TransformDirection

Genau so habe ich es ihm Code über dir bei NewDirectionUntilRotation nach der Drehung der Kamera mit den Richtungs-Vektoren gemacht.

PS: Warum ohne Beachtung der aktuellen Werte?
Liebe Grüße,
René

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

10

06.11.2012, 17:19

Neu berechnen bedeutet, das du den Up-Vektor für das lokale Koordinatensystem im Weltkoordinatensystem haben möchtest?

Speicher dir am besten den Up-Vektor und verändere ihn jedes mal wenn du rotierst mit TransformDirection

PS: Warum ohne Beachtung der aktuellen Werte?
Naja, ist das nicht etwas sehr umständlich, wenn ich die Veränderung jeweils speichern muss und es dann "zurückändern" muss.
Kann ich nicht einfach sagen: Rotationgrad der x,y,z-Achse = ...; x,y,z-Kordinate=...; So etwas geht etwa nicht?

Und dann existiert ja noch der Fehler, wenn ich beispielsweise die Kamera nach oben bewege und danach zur Seite, steht sie am Schluß auf dem Kopf. Ich glaube solche Probleme könnte ich dann nicht einfach durchs "Zürückrechnen" beheben, da ich ja nicht weiß, wie sich jeweils die aktuellen Rotationswerte verändert haben, wenn der Spieler sich in mehrere Richtungen dreht, und ich danach nur eine/mehrere Achsen zurücksetzen will.

Mit "ohne Beachtung der aktuellen Werte", meinte ich, dass ich einfach - ganz egal was die aktuellen Werte sind - den jeweiligen Wert auf einen bestimmten festlegen wollte, ohne dass ich immer nur eine Veränderung angeben muss.

Ist schon komisch, Unity ist so beliebt zurzeit, aber so etwas einfaches geht nicht?

Gruß,
MitgliedXYZ

Werbeanzeige