Jump to content
Unity Insider Forum

GameObject schiebbar, aber nicht drehbar machen


Noob

Recommended Posts

Hallo zusammen,

für meine kleine Welt fehlt mir noch eine entscheidene Kleinigkeit:

Ich greife über meinen Datenhandschuh Objekte in der VR. Sobald dabei ich ein Objekte berühre, wird es zum Child meiner Hand. Soweit so gut.

Jetzt solls aber Objekte geben, die ich zwar greifen und verschieben, aber nicht drehen kann. Grund dafür wäre z.B. das das Objekt auf einer Schiene ist oder Ähnlichem befestigt ist. Ich habs schon mit LockRotation des RBs. versucht, was aber wenig bringt, wenn das Object ein Child meiner Hand ist. Auch habe ich versucht, das Objekt immer wieder zu einem bestimmten Winkel zuf drehen. Was dann aber wiederrum zu Zuckungen führt.

Hat jemand noch eine andere Idee wie ich das lösen kann?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Anstatt das Objekt als Child unterzuordnen, gib ihm halt ein Script.

public Transform attachmentBase;

void LateUpdate()
{
  if(attachmentBase)
  {
    transform.position = attachmentBase.position;
    transform.rotation = attachmentBase.rotation;
  }
}

Und dann kannst du das abwandeln. Die Rotation-Zeile lässt du weg (oder packst ein if drum) und die Positionszeile änderst du so, dass eben in Abhängigkeit der Handposition auf die Schiene gesetzt wird.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das geht schon ziemlich genau in die richtige Richtung.

Mit der Translation funktioniert das schonmal mit dem Code ziemlich zufriedenstellend

    void OnTriggerEnter(Collider other)
    {
        startpos = transform.position - attachmentBase.position;       
    }

	void OnTriggerStay(Collider other)
    {
        transform.position = attachmentBase.position + startpos;
    }

Die Differenz deshalb, weil Target und die Hand nicht an der selben Startposition sind.

Versuche ich das auch mit der Rotation, dreht sich das Object zwar um den Winkel vom attachmentBase,  logischerweise aber um seine eigene Achsen. Eigentlich müsste sich das Object einfach nur um die Achsen von der Hand drehen. Als wäre es ein stupides Child also.

Ich dachte zuerst an RotateAround, was ich aber nicht zum Laufen gebracht habe, da ich ja nicht um eine spezifische Achse drehe.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Oh maaaaan. Ist ja eigentlich ganz einfach, wenn ich noch ein Child in die Hand reinlegen. Das Child verschiebe und drehe ich bei OnTriggerEnter() einfach zum Target und führ die von dir oben beschriebene transforms durch.

Werd ich morgen gleich mal ausprobieren.
Danke dir!

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...

HiHo,

ich habs mal versucht umzusetzen:

using UnityEngine;
using System.Collections;

public class Grab : MonoBehaviour
{
    private bool _thumbInTrigger = false;
    private bool _indexInTrigger = false;
    private bool _middleInTrigger = false;
    private bool _ringInTrigger = false;
    private bool _pinkyInTrigger = false;
    private GameObject HelpObject;
    private Vector3 HelpVec;
  
      public void OnTriggerEnter(Collider other)
    {      
        if (other.CompareTag("Thumb")) _thumbInTrigger = true;
        if (other.CompareTag("Index")) _indexInTrigger = true;
        if (other.CompareTag("Middle")) _middleInTrigger = true;
        if (other.CompareTag("Ring")) _ringInTrigger = true;
        if (other.CompareTag("Pinky")) _pinkyInTrigger = true;
        if (_thumbInTrigger && (_indexInTrigger || _middleInTrigger || _ringInTrigger || _pinkyInTrigger))
        {

            HelpVec = transform.position;

            HelpObject.transform.position = transform.position;
            HelpObject.transform.rotation = transform.rotation;

        }

    }

    private void OnTriggerStay(Collider other)
    {

        if (other.CompareTag("Thumb")) _thumbInTrigger = true;
        if (other.CompareTag("Index")) _indexInTrigger = true;
        if (other.CompareTag("Middle")) _middleInTrigger = true;
        if (other.CompareTag("Ring")) _ringInTrigger = true;
        if (other.CompareTag("Pinky")) _pinkyInTrigger = true;
        if (_thumbInTrigger && (_indexInTrigger || _middleInTrigger || _ringInTrigger || _pinkyInTrigger))
        {


            if (anim_roberta.lockrotation && CompareTag("Target"))
            {
                transform.position = HelpObject.transform.position;

            }

            if (CompareTag("Pumpenkoerper"))
            {
                transform.position = new Vector3(HelpObject.transform.position.x, HelpVec.y, HelpObject.transform.position.z);
            }

            if (CompareTag("Pen"))
            {
                transform.position = HelpObject.transform.position;

            }

            else
            {
                transform.position = HelpObject.transform.position;
                transform.rotation = HelpObject.transform.rotation;
            }
        }

    }

    private void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Thumb")) _thumbInTrigger = false;
        if (other.CompareTag("Index")) _indexInTrigger = false;
        if (other.CompareTag("Middle")) _middleInTrigger = false;
        if (other.CompareTag("Ring")) _ringInTrigger = false;
        if (other.CompareTag("Pinky")) _pinkyInTrigger = false;

        if (!_thumbInTrigger || !_indexInTrigger || !_middleInTrigger || !_ringInTrigger || !_pinkyInTrigger)
        {

            transform.position = transform.position;
            transform.rotation = transform.rotation;
          
        }

    }

}

Im Prinzip funktionierts. Allerdings mehr schlecht als recht.

Das Problem ist, dass die Objekte nur teilweise gegriffen werden. Manchmal klappt das ganz gut, manchmal gar nicht. Beweg ich die Hand schneller, folgt kein Bauteil der Hand :(

Wie könnte ich das denn lösen? Wenn ich sie wieder als Child von der Hand mache, springen die manchmal wild durch den Raum. Wer weiß warum...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe noch nicht mit VR gearbeitet, aber ich könnte mir vorstellen, daß sich dein Datenhandschuh sich zu "schnell" durch die Szene bewegt. Die Physikengine läuft in einen FixedUpdate-Intervall und hängt daher den tatsächlichen Frames hinterher.
Du müsstet also die Bewegung des Datenhandschuhs mit dem Updatezyklus der Physikengine synchronisieren, ansonsten rutscht der Datenhandschuh quasi immer durch die Collidertrigger hindurch. Da gibt es nun 2 Möglichkeiten, entweder du bewegst den Datenhandschuh nur im Fixedupdateintevall (hier weiß ich nicht allerdings nicht, wie du daß mit dem Datenhandschuh umsetzen kannst, evtl musst du die Bewegung des Handschuhs auslesen und die Bewegung nur über die Fixedupdate "ausführen") oder du hebst das Fixedupdateintervall der Physikengine an, damit eine schnelle Positionsveränderung des Datenhandschuhs von den Collidern auch tatsächlich registriert wird. Letzteres wäre allerdings eine "schlechte" Lösung, da es auf die Performance geht.

Du kannst auch noch einmal mit der Einstellung des RB des Datenhandschuhs experimentieren, hier gibt es 2 Settings, die helfen könnten:
"Collision Detection"
Used to prevent fast moving objects from passing through other objects without detecting collisions.
(Das ist genau dein beschriebenes Problem)
Interpolate
(ist aber vermutlich nicht das Problem)

Ansonsten gefällt mir die Lösung mit OnTriggerStay und dem Verschieben der Objekte hierüber nicht so richtig. Dadurch wird das oben beschriebene Problem eben noch einmal verschärft.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke für deine Hilfestellung.

Die Fingerbewegungen führ ich tatsächlich nur im FixedUpdate durch.

Der Datenhandschuh hat keinen Rigidbody. Ich bewege die Hand/Finger eines First-Person-Models. Die einzelnen Fingerkuppen haben Collider, denen ich einen RB verpassen könnte.

Wie könnte ich denn die OnTriggerStay - Sache weglassen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dann sollt ich schonmal alle OnTriggerXX zu OnCollision ändern? Aber wie löse ich das, dass OnCollisionStay wegfallen würde?

Wird überhaupt eine Collision erkannt, wenn beide Partner isKinematic=true gesetzt haben? Anders hatte ich bisher große Schwierigkeiten

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn sich alle deine Objekte nicht über die Physikengine bewegen sollen (d.h. sie stoßen sich nicht gegenseitig ab und es wirkt keine Gravitation), dann sollte lt. "Theorie" dein Datenhandschuh einen kinematic RB haben und alle deine Objekte die du verschiebst auch... Ich würde die Scene mal dahingehend umstellen. Zudem wenn du den Handschuh nur in der Fixedupdate bewegen kannst, dann würde ich das auch so einstellen, da ansonsten die Objekte die Verschiebung des Handschuhs ggf. nicht mitbekommen, da sich der Handschuh zwischen 2 Fixedupdate-Intervallen zu viel bewegt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 8 Minuten schrieb Zer0Cool:

Soll auf deine Objekte auch Gravitation wirken und sollen sich die Objekte gegenseitig abstoßen?

Dann setz ich den Handschuh mal wieder in Update() und schau, dass alle GO RBs mit CollisionDetectionMode.Continuous versehen werden. Die Fingerkuppen bekommen auch einen RB mit CollisionDetectionMode.ContinuousDynamic. Dann setz ich mal alles auf OnCollisionEnter. Die CollisionDectection wird mir bei OnTriggerEnter nichts bringen...

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Den Handschuh bitte nur in der FixedUpdate-Methode bewegen ... und an den Handschuh der OnTriggerEnter auslösen soll einen kinmatic RB und an alle Objekte in der Szene die du verschiebst auch einen kinematic RB....
OnCollisionXXX verwendet man bei non-Trigger Collidern und OnTriggerXXX bei Trigger-Collidern.

In deinem Fall solltest du allerdings nur Trigger-Collider verwenden und damit eben auch die OnTriggerXXX-Methoden!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das mit den kinematic RB ist soweit alles klar.

Warum ich aber nur Trigger-Collider verwenden soll, eher nicht.

Dein Post mit den CollisionDectection-Settings komplett hinfällig?

Meinst du, dass das Setzen der kinematic RBs an den Handschuh das Problem lösen wird?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, ich würde es erst einmal ohne "Feintuning" an den RBs-Collisions-Settings (des Handschuhs) versuchen. Und wann es sich nicht verbessert, dann nicht mehr die XXXStay-Methoden verwenden, um die Objekte zu verschieben, sondern die Childobjekte in der Fixedupdate-Methode kontinuierlich verschieben (nach der Position des Handschuhs) und zwar solange wie die Finger das Objekt gegriffen haben...

Kurze Todo-Map:
- Datenhandschuh greift in das Objekt, OnTriggerEnter der Finger wird ausgelöst, das gegriffene Objekt wird mit dem Handschuh verbunden: Es wird eine Variable gesetzt, die das gegriffene Objekt speichert - kann man auch für mehrere Objekte machen.
- Zusätzlich wird ein Offset des Objektes zum Handschuh gespeichert (Offset = Objektposition - Handschuhposition)
- FixedUpdate-Methode: Solange die Variable gesetzt ist, wird das gespeicherte Objekt an die Position des Handschuhs verschoben, der Offset wird jeweils zur Position hinzugefügt (Objektposition = Handschuhposition + Offset)
- wird die Hand geöffnet, dann verlassen die Finger das Objekt, dabei wird OnTriggerExit der Finger ausgelöst, das zuvor gegriffene Objekt wird vom Handschuh gelöst: Die Variable wird gelöscht, das Objekt bewegt sich nicht mehr mit.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...