Jump to content
Unity Insider Forum

Touch Berührung


Tim96

Recommended Posts

Hey,

ich bin relativ neu bei Unity und habe, für die meisten wahrscheinlich, eine eher simple Frage. Ich brauche für mein 2D-Spiel die Funktion, dass sich bei Berührung in einem Kreis ein Pfeil in diesem Kreis um seine Z-Achse dreht. Wobei es zufällig sein soll, wo der Pfeil am hinzeigt.

Ich hoffe Ihr könnt mir helfen

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • Antworten 58
  • Created
  • Letzte Antwort

Hi!

Für den Touch sollte meines Wissens nach OnMouseDown immer noch funktionieren:

private void OnMouseDown()
{
  Debug.Log("Ich wurde gedrückt!");
}

Wird ausgelöst, wenn du den Collider triffst - dein Kreis muss also mit einem CircleCollider2D gebaut sein, um zu definieren, wo man hindrücken kann. Auf das GameObject mit diesem Collider kommt dann das Script mit OnMouseDown.

In OnMouseDown kannst du z.B. mit Random.Range deine Zufallsdrehung bauen:

var z = Random.Range(0f, 360f);
var rotation = Quaternion.Euler(0, 0, z);
arrow.rotation = rotation;

"arrow" kannst du dir als öffentliches (bzw. serialisiertes) Feld deklarieren:

public Transform arrow;

sodass du dein Pfeil-GameObject da im Inspektor reinziehen kannst.

Das ganze Script (also der Inhalt der Klasse) sieht dann so aus:

public Transform arrow;

private void OnMouseDown()
{
  var z = Random.Range(0f, 360f);
  var rotation = Quaternion.Euler(0, 0, z);
  arrow.rotation = rotation;
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Da würde ich ein Script auf den Pfeil legen, das dreht, und das andere auf dem Collider löst das nur noch aus. Da das Drehverhalten eher zum Dreh-Script gehört als zum Auslöser, würde das da hinwandern.

public ArrowRotation arrow;

private void OnMouseDown()
{
  arrow.Spin();
}

Und hier wäre "ArrowRotation":

private Quaternion targetRotation;
public float speed = 20f;

public void Spin()
{
  var z = Random.Range(0f, 360f);
  targetRotation = Quaternion.Euler(0, 0, z);
}

private void Update()
{
  transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi!

Also nochmal danke für die schnelle Antwort. Es hat auch geklappt, aber ich wäre dir super dankbar, wenn du mir dabei hilfst, dass sich der Pfeil zwar ‚ ‚ ‚random‘ bewegt, aber der Pfeil da anfängt zu drehen wo der aufgehört hat.

Und falls du es noch zeitlich schaffst, kannst du mir vielleicht erklären wie man es schafft, dass der Pfeil nur das ganze macht wenn man auf die entgegengesetzte Seite des Pfeils drückt.

schönen tag noch und vielen dank!

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 44 Minuten schrieb Tim96:

dass sich der Pfeil zwar ‚ ‚ ‚random‘ bewegt, aber der Pfeil da anfängt zu drehen wo der aufgehört hat.

Also... das soll er nicht? Denn aktuell tut er das ja. Soll er immer nach oben flippen und von da aus auf die Zufallsposition drehen?

In dem Fall baust du einfach an den Anfang der "Spin"-Methode noch ein

transform.rotation = Quaternion.identity;

 

vor 46 Minuten schrieb Tim96:

Und falls du es noch zeitlich schaffst, kannst du mir vielleicht erklären wie man es schafft, dass der Pfeil nur das ganze macht wenn man auf die entgegengesetzte Seite des Pfeils drückt.

Das wird ein bisschen komplizierter. Mit Vector3.Angle kannst du den Winkel zwischen zwei Richtungsvektoren herausfinden. Einer davon wäre vom Pfeil-Objekt "transform.up" (in der Hoffnung, dass dein Pfeil-Sprite nach oben zeigt). Der andere ist problematischer zu kriegen. Da müsstest du mit Methoden und Eigenschaften aus der Input-Klasse arbeiten - touchCount und GetTouch zum Beispiel. Damit findest du die Position deines Touches auf dem Bildschirm. Diesen musst du noch in eine Position in der Welt umrechnen. Camera.ScreenToWorldPoint sollte dir dabei helfen. Dann hast du die Position deines Touches relativ zur Welt. Diese ziehst du vom Mittelpunkt deines Pfeils bzw. deiner Scheibe ab und hast den Richtungsvektor deines Touches, den du dann mit dem anderen Vektor abgleichen kannst, um den Winkel zu kriegen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 7 Stunden schrieb Tim96:

Der Pfeil fängt halt immer bei der aller ersten Ausgangsposition an und das jedes mal.

Dann machst du was falsch, setzt vielleicht die falsche Transformation in Slerp Methode.

Zitat

Und falls du es noch zeitlich schaffst, kannst du mir vielleicht erklären wie man es schafft, dass der Pfeil nur das ganze macht wenn man auf die entgegengesetzte Seite des Pfeils drückt.

Hier kommt es drauf an, wie genau du es haben willst, entweder wirds ein bischen kompliziert, wie Sascha geschrieben hat, oder halt mit einem Trick, nur mit paar Klicks.

Der Trick wäre, du plazierst auf der Gegenseite des Pfeiles ein neues, empty Objekt mit einem Kollider drauf und machst ihn als Kind des Pfeil Objektes. Und packst den Script von Sascha stattdessen auf dein neues Objekt drauf. In dem Script rotierst du weiterhin dein Pfeilobjekt und wenn du dein Kindobjekt anklickst, rotiert er sich immer mit und bleibt somit auch immer entgegengesetzt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 4.2.2020 um 18:20 schrieb Sascha:

Also... das soll er nicht? Denn aktuell tut er das ja. Soll er immer nach oben flippen und von da aus auf die Zufallsposition drehen?

Nein, im Moment fängt der Pfeil von einer "random" Position an und dreht sich dann in einer Geschwindigkeit zu einer anderen Zufallsposition. Ich hab auch oft kontrolliert ob ich es richtig abgeschrieben habe, aber habe ich eigentlich. 

Was ich meinte war, dass wenn sich der Pfeil aufgehört hat zu drehen, dass dieser sich von der Position, wo er aufgehört hat zu drehen, von da aus weiter dreht, wenn man wieder drückt.

 

Am 4.2.2020 um 18:20 schrieb Sascha:

transform.rotation = Quaternion.identity;

Hiermit fängt der Pfeil immer von der ersten Position an zu drehen und nicht von der Position, wo dieser aufgehört hat.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb Tim96:

Nein, im Moment fängt der Pfeil von einer "random" Position an und dreht sich dann in einer Geschwindigkeit zu einer anderen Zufallsposition. Ich hab auch oft kontrolliert ob ich es richtig abgeschrieben habe, aber habe ich eigentlich. 

Was ich meinte war, dass wenn sich der Pfeil aufgehört hat zu drehen, dass dieser sich von der Position, wo er aufgehört hat zu drehen, von da aus weiter dreht, wenn man wieder drückt.

 

Okay, das Problem habe ich selber gelöst.

 

Aber das Problem mit der Position noch nicht, dass der Pfeil nicht da anfängt, wo der aufgehört hat.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 14 Stunden schrieb Tim96:

im Moment fängt der Pfeil von einer "random" Position an und dreht sich dann in einer Geschwindigkeit zu einer anderen Zufallsposition.

Dann hast du noch alten Code mit drin, denke ich. Auf dem Pfeil oder auf einem Parent-Objekt des Pfeils. Der Code auf seinem letzten Stand enthält keine Änderung der Rotation abgesehen von der auf "targetRotation" zu.

vor 13 Stunden schrieb Tim96:

Wie kriege ich es hin, dass  z und zx abwechselnd ablaufen?

Ganz ehrlich... ich glaube nicht, dass das das ist, was du willst, aber probier's gerne mal aus:

private bool lessThan180 = true;
float angle;

if (lessThan180)
{
  angle = Random.Range(0f, 180f);
}
else
{
  angle = Random.Range(180f, 360f);
}

targetRotation = Quaternion.Euler(0, 0, angle);
lessThan180 = !lessThan180;

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Will wirklich nicht aufdringlich sein, aber ich wäre dir sehr dankbar, wenn ich mit deiner Hilfe dieses kleine Programm schnell fertig hab.

Also ich bräuchte deine Hilfe dabei, dass sich der Pfeil mit einem mindestens 90 Grad bis maximal 270 Grad winkel von der Postion wegbewegt, wo man den markierten Bereich gedrückt hat.

Aber auch wirklich von der Position wo man gedrückt und nicht dass der Pfeil zuerst an eine Random Postion springt und dann zu einer anderen Random Postion geht.


Ich weiß, war jetzt sehr direkt, aber ich bräuchte halt im moment relativ schnell die Codes dafür 🙏

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 8 Stunden schrieb Tim96:

Also ich bräuchte deine Hilfe dabei, dass sich der Pfeil mit einem mindestens 90 Grad bis maximal 270 Grad winkel von der Postion wegbewegt, wo man den markierten Bereich gedrückt hat.

Dachte ich mir schon, dass das eher das ist, was du willst :)

Um einen Winkel zu würfeln, der vom vorherigen abhängig ist, kannst du entweder den aktuellen Winkel erfragen oder dir dein letztes Zufallsergebnis merken. Ich würde, auch wenn in einigen Fällen beides geht, sicherheitshalber immer Letzteres empfehlen.

private float currentAngle = 0f;

Wenn du dann 90° bis 270° davon weiter willst, einfach draufaddieren:

currentAngle += Random.Range(90f, 270f);

Damit du immer zwischen 0 und 360 bleibst, knallst du noch ein Mathf.Repeat drauf:

currentAngle = Mathf.Repeat(currentAngle, 360f);

Dann baust du dir damit dein targetRotation-Quaternion und arbeitest damit wie gehabt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Habe das Programm schon fast fertig, aber zu der Geschwindigkeit.

Meinte das so, dass wenn man klickt, dass der Pfeil dann pro "Runde" die Geschwindigkeit ("Speed")um 0.8 erhöht. Und dann wenn "Speed" einen Wert von 20 erreicht hat, behält es den Wert und erhöht sich nicht mehr.

Währenddessen soll es so sein, dass der Pfeil am Anfang 1 Sekunde "wartet" bis der gedrückt wird und an seiner Position bleibt. Sozusagen wie ein Timer eigentlich. Wenn der Pfeil nicht gedrückt wird, soll das Spiel stoppen. Pro Klick soll der Pfeil immer 0.05 Sekunden weniger "warten" und dann bei 0.1 die Zeit als Timer beibehalten.

 

Ich weiß ist wieder sehr viel. Aber keine Sorge, das Programm ist fast fertig haha.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hey,

ich habe ein Problem, dass mein Counter zwar läuft, aber ich kriege es nicht hin, dass der Counter bei Berührung im Circle collider auf 1 sek resetet wird.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Zeitcount : MonoBehaviour
{
    public double myTimer = 3;
    private Text timerText;
    private bool timerIsActive = true;

    // Start is called before the first frame update
    void Start()
    {
        timerText = GetComponent<Text>();
    }

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

            if (timerIsActive)
            {
                myTimer -= Time.deltaTime;
                timerText.text = myTimer.ToString();
                print(myTimer);
                if (myTimer <= 0)
                {
                    myTimer = 0;
                    timerIsActive = false;
                }
            }
        }
    }
}

 

Das ist das Script für den Counter, wie der von 5 sek am Anfang runterzählt. Jetzt will ich es aber hinbekommen, dass dieser Counter immer wieder bei Berührung auf die Startzeit resetet wird.

Die anderen Scripts sind ja hier im Chat schon drin.

 

Danke im vorraus!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

Ankündigungen


Hy, wir programmieren für dich Apps(Android & iOS):

Weiterleitung zum Entwickler "daubit"



×
×
  • Neu erstellen...