Jump to content
Unity Insider Forum
Sign in to follow this  
Flowmaster

Button bei VR

Recommended Posts

Hallo.

Ich habe statt eines UI Buttons einen cube, der als Button dient in VR. Wie kann ich dem einen onclick geben, so dass eine Aktion passiert?

Beispiel 1: bei onclick vom cube wird eine Animation bei einem animierten Objekt abgespielt.

Beispiel 2: bei onclick vom cube wird ein Video bei easymovietexture abgespielt.

 

Diese Verlinkung, also das Ansprechen eines anderen Objekts im Script, ist mein Problem.

Beim Standard-Button kann ich ein Objekt in den Slot ziehen und einen Befehl auswählen, diese Funktion suche ich als Script-Variante.

 

 

Danke und Gruß

Christian

Share this post


Link to post
Share on other sites

Hey, mal schauen ob ich dir weiterhelfen kann.

 

Du könntest folgendes machen:

void Update(){
  if (Input.GetMouseButtonDown(0)){ // if left button pressed...
 Ray ray = camera.ScreenPointToRay(Input.mousePosition);
 RaycastHit hit;
 if (Physics.Raycast(ray, out hit)){
   // the object identified by hit.transform was clicked
   // do whatever you want
 }
  }
}

Das ist ein Beispiel vom Link:

http://answers.unity3d.com/questions/332085/how-do-you-make-an-object-respond-to-a-click-in-c.html

 

Du überprüfst damit im Prinzip ob du das Objekt angeklickt hast.

Ich denke das wolltest du wissen. Ob das allerdings statt mit einer Maus auch im VR

funktioniert bzw. ob das überhaupt geht weiß ich nicht, kenne mich mit VR/AR nicht aus.

 

Ich denke andere können dir da sicher besser weiterhelfen ;)

LG Tobi :)

Share this post


Link to post
Share on other sites

Für welche Platform entwickelst du?

 

Falls es sich um Cardboard handelt, schau dir mal den Cube, das EventSystem und den GvrReticle in der HeadsetDemo Scene an. Die Scene befindet sich im Ordner der GoogleVR SDK.

Damit brauchst du keine Script Variante um das Problem zu lösen.

 

Und falls das Problem unbedingt mit einem eigenen Script gelöst werden soll, musst du das wie oben beschrieben mit nem Raycast machen. Bei VR ist es dann aber am besten einen Punkt in der Mitte des Sichtfeldes zu plazieren (z.B. über eine Canvas mit dem Render Mode "World Space", welche Child der Camera ist). Und der Raycast wird anschließend dann von der Camera Position gesendet.

In etwa so:

 

if (Input.anyKeyDown)
{
  if (Physics.Raycast(playerCamera.position, playerCamera.forward, out hit, range))
  {
  if(hit.transform.tag == "Cube")
  {

  }
  }
}

Share this post


Link to post
Share on other sites

Hallo.

Danke für eure Antworten.

Also ich gebe für die Gear VR aus. Funktioniert damit auch das angesprochene GoogleVR sdk?

Ich habe mir von Unity die VR samples angesehen und habe daraus die Kamera genommen, die ein gaze input hat.

Das heisst mein cube (Button) reagiert auf den Pointer im Gesichtsfeld und er macht auch Farbenwechsel bei Aktivierung, genau

wie ein normaler Button ( on hover, on click usw). VR input läuft also prinzipiell.

Nur der eigentliche Befehl zum klicken, um wirklich die Aktion auch auszuführen, fehlt mir. Das hat bei mir glaube ich nix mit VR zu tun, sondern "nur" wie ein Befehl im script ein anderes Objekt in der Szene anspricht.

Bin auch nicht so der Oberscripter, eher der copy-paste-Typ :-)

Danke und VG Chris

Share this post


Link to post
Share on other sites

Wenn ich das jetzt richtig verstehe möchtest du wissen wie das OnClick() funktioniert?

Sorry ich stelle eigentlich eher Fragen als Antworten zu geben ;)

 

Kannst du einen Screenshot posten, in welchem das Objekt, auf dass du drücken möchst,

im Inspektor gezeigt wird?

 

Ich verstehe dass jetzt so, dass du in dem Objekt eine OnClick()-Komponente hast und nur nicht

weißt wie du mit der umgehen sollst.

 

Vielleicht stehe ich aber auch auf dem Schlauch^^

Liebe Grüße Tobi :)

 

Edit: Halte dich im Zweifelsfall immer an die anderen, nicht an mich ;)

Share this post


Link to post
Share on other sites

Hallo.

Jetzt habe ich mal was vorbereitet:

post-6186-0-66170000-1479388877_thumb.jpg

Der obere Würfel dreht sich per Animator component.

Das ani_play Script ist eigentlich genau das, was ich möchte, nur nicht dort ausgelöst, sondern

von einem Button (unterer Würfel). Atm dreht sich der Würfel einmal am Anfang und steht dann still.

 

post-6186-0-32353000-1479388953_thumb.jpg

Der untere Würfel ist mein Button. Er hat das Menu Button Script und reagiert wie ein normaler Button in VR. Heisst ich schaue mit dem Cursor drauf, er wechselt die Farbe und wenn ich den Knopf an der GearVR drücke baut sich in 2 sek ein kleiner Ring am Cursor auf, der den click dann macht.

 

post-6186-0-30211100-1479389210_thumb.jpg

Das ist das Menu Button Script von den unity VR samples. Ich habe oben eine public Variable eingefügt (gelb), um auf meinen Drehwürfel zu verweisen, siehe shot 2. Ganz unten wird dort ein Szene-Wechsel durchgeführt (gelb). Das wollte ich löschen und ein animation.play für den Drehwürfel hinzufügen. So wie in dem kleinen ani_play Script:

 

post-6186-0-46185400-1479389453_thumb.jpg

Das nur zur Info. Der Befehl ist da, ich muss in nur in dem Menu Button Script ausführen, welches partout nicht klappt. Er sagt immer, dass er die component oder das Objekt nicht findet.

 

Danke für einen Wink mit dem Zaunpfahl :-)

Sag mal, arbeitest Du in Köln? Weil da bin ich öfters, da ich dort in einer Agentur arbeite.

Share this post


Link to post
Share on other sites

So langsam kommen wir dem Problem näher^^

Am besten ist es du postest auch die Fehlermeldung(en). Dann können wir

viel mehr damit anfangen.

 

Ganz unten wird dort ein Szene-Wechsel durchgeführt (gelb). Das wollte ich löschen und ein animation.play für den Drehwürfel hinzufügen. So wie in dem kleinen ani_play Script:

 

Wenn du den Szenenwechsel nicht drin haben möchst kannst du denn einfach aus dem Script rausnehmen und

ein Animator.play ausführen. Müsstest du zumindest.

Du müsstest nur korrekt auf den Animator verweisen und den Namen entsprechen ändern, falls

der nicht schon stimmt.

 

Ich bin leider nicht so der VR-King (bekomme davon Kopfschmerzen) und habe da auch nicht viel Ahnung von, letzten

Endes dürfte es sich aber kaum oder gar nicht vom normalen 2D/3D unterscheiden.

 

Ein Beispiel:

 

public Animator animatorObject;
// dann erscheint der im Editor, wo du den Animator zuweisen musst.
public functionName() {
  this.GetComponent<Animator>().Play("Name", -1, 0.0f);
  // Hier würdest du auch wieder den Animator suchen und die entsprechenden
  // Einträge machen.
  // Alternativ:
  // animatorObject.Play("Name", -1, 0.0f);
}

 

Ich kenne mich leider mit Animationen nicht genug aus um sicher zu sein.

Nur wie gesagt, eigentlich müsste es reichen, wenn du deinem Objekt, dass animiert werden soll, sagst,

dass es die Animation abspielen soll.

Eventuell könnte dir auch folgender API-Eintrag weiterhelfen:

https://docs.unity3d...ation.Play.html

 

Da wird ganz gut erklärt wie du deine Animation abspielen kannst.

Wenn er sagt, dass er die Komponente nicht findest, hast du die auch nicht übergeben.

 

Ich werde mir das heute Abend noch mal etwas genauer anschauen, vielleicht kann ich dir

dann besser weiterhelfen, oder jemand anders hat dich bereits gerettet ;)

 

Wie gesagt, probiere einfach mal aus den Code den du weghaben willst durch meinen vorgeschlagenen Code

zu ersetzen und schau was bei rauskommt.

Musst du natürlich noch die Namen etc. entsprechend eintragen.

 

Falls das nicht geht poste mir auch mal die Fehlermeldungen, da kann man dann manchmal ganz gut draus schließen.

Scripts wie den vom Menu Button Script kannst du auch einfach kopieren und

einfügen, indem du wenn du einen Post schreibst die "<>" andrückst und den da reinkopierst.

 

 

Sag mal, arbeitest Du in Köln? Weil da bin ich öfters, da ich dort in einer Agentur arbeite.

Ich brauche 20-30min bis Köln HbF, arbeiten tue ich allerdings (noch) in Bergisch Gladbach.

 

LG Tobi ;)

 

Edit: Mir ist gerade aufgefallen dass sich Animator.Play() von Animation.Play() unterscheidet.

Vielleicht kannst du in deinem Button Script auch einfach das Objekt was animiert werden soll holen

und dann mit Animation.Play() dass einfach ausführen.

Würde den Umweg über den Animator umgehen, falls das funktioniert.

 

Ich bin übrigens auch nicht so der Coder, eher Game Designer ;)

Share this post


Link to post
Share on other sites

Bin auch überhaupt kein Coder, deshalb fand ich auch UE4 ganz nett mit den Blueprints. Allerdings ist UE recht buggy, ich hatte damit echt zu kämpfen. Bei Unity klappt es viel besser, allerdings muss ich öfters in Scripts rein, und da bin ich wirklich Anfänger.

Zum Problem:

Der Drehwürfel (der obere lilafarbene) hat ja schon einen Animator mit zugewiesener Bewegung und das kleine ani_Play funktioniert auch, der Würfel dreht sich.

Ich möchte nur von dem Menu_Button_Script aus dem Animator sagen: ey, spiel jetzt mal ab.

this.getcomponent kann ich doch nicht im Menu_Button_Script eintragen, weil der Animator dem nicht zugewiesen ist, sondern dem Drehwürfel. Das ani_Play-Script ist dem Drehwürfel zugewiesen und dort steht auch this.getcomponent.

Soll ich Dir mal die Szene schicken?

Share this post


Link to post
Share on other sites

Du musst ja eine Referenz zu dem Objekt haben, also eine Zuweisung.

Der muss ja wissen was mit Animator gemeint ist.

 

Wenn du das gemacht hast, schau mal ob du den private gesetzt hast und

änder das mal zu public.

 

Ist nicht wirklich die beste Lösung aber um zu schauen ob es daran liegt langt es ;)

Share this post


Link to post
Share on other sites

Du musst aber m_AnimationPlay schreiben, also den Namen der Variable, nicht den Typ.

Außerdem ist es schön, wenn du deinen Code nicht als Screenshot hochlädst, sondern als Code:

[ CODE ]

Dein Code

[ /CODE ]

(ohne die Leerzeichen)

Share this post


Link to post
Share on other sites

Jetzt habe ich das unten umgeschrieben und es gibt keine Fehlermeldung, aber der obere Würfel dreht sich nicht bei click.

Was mache ich da falsch?

 

Script MenuButton:

 

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using VRStandardAssets.Utils;
namespace VRStandardAssets.Menu
{
   // This script is for loading scenes from the main menu.
   // Each 'button' will be a rendering showing the scene
   // that will be loaded and use the SelectionRadial.
   public class MenuButton : MonoBehaviour
   {
    public event Action<MenuButton> OnButtonSelected;				   // This event is triggered when the selection of the button has finished.

    [serializeField]
    private string m_SceneToLoad;					  // The name of the scene to load.
    [serializeField]
    private VRCameraFade m_CameraFade;				 // This fades the scene out when a new scene is about to be loaded.
    [serializeField]
    private SelectionRadial m_SelectionRadial;		 // This controls when the selection is complete.
    [serializeField]
    private VRInteractiveItem m_InteractiveItem;	   // The interactive item for where the user should click to load the level.
    [serializeField]
    public Animator m_animationPlay;
    private bool m_GazeOver;										    // Whether the user is looking at the VRInteractiveItem currently.

    private void OnEnable()
    {
	    m_InteractiveItem.OnOver += HandleOver;
	    m_InteractiveItem.OnOut += HandleOut;
	    m_SelectionRadial.OnSelectionComplete += HandleSelectionComplete;
    }

    private void OnDisable()
    {
	    m_InteractiveItem.OnOver -= HandleOver;
	    m_InteractiveItem.OnOut -= HandleOut;
	    m_SelectionRadial.OnSelectionComplete -= HandleSelectionComplete;
    }

    private void HandleOver()
    {
	    // When the user looks at the rendering of the scene, show the radial.
	    m_SelectionRadial.Show();
	    m_GazeOver = true;
    }

    private void HandleOut()
    {
	    // When the user looks away from the rendering of the scene, hide the radial.
	    m_SelectionRadial.Hide();
	    m_GazeOver = false;
    }

    private void HandleSelectionComplete()
    {
	    // If the user is looking at the rendering of the scene when the radial's selection finishes, activate the button.
	    if (m_GazeOver)
		    StartCoroutine(ActivateButton());
    }

    private IEnumerator ActivateButton()
    {
	    // If the camera is already fading, ignore.
	    if (m_CameraFade.IsFading)
		    yield break;
	    // If anything is subscribed to the OnButtonSelected event, call it.
	    if (OnButtonSelected != null)
		    OnButtonSelected(this);
	    // Wait for the camera to fade out.
	    // yield return StartCoroutine(m_CameraFade.BeginFadeOut(true));
	    // Load the level.
	    // SceneManager.LoadScene(m_SceneToLoad, LoadSceneMode.Single);
	    // Animation.Play("CINEMA_4D_Basis", -1, 0.0f);
	    m_animationPlay.Play("CINEMA_4D_Basis");


    }

   }
}

Share this post


Link to post
Share on other sites

Ich sehe da direkt kein Problem. An deiner Stelle würde ich jetzt daher alles mit prints vollkleistern, um zu sehen, wo es hakt.

Share this post


Link to post
Share on other sites

Nachdem ich die unterste Zeile eingefügt habe funktioniert es.

Das fbx02 ist die eigentliche Animation (die Bewegungsdaten) aus C4D heraus, die im fbx enthalten war.

Danke für eure Bemühungen.

 

Jetzt habe ich gelernt, wie ich eine Button-Funktionalität für VR einem beliebigen Mesh geben kann.

VG Chris

 

	    // Load the level.
	    // SceneManager.LoadScene(m_SceneToLoad, LoadSceneMode.Single);
	    // Animation.Play("CINEMA_4D_Basis", -1, 0.0f);
	    // m_animationPlay.Play("CINEMA_4D_Basis", -1, 0.0f);
	    m_animationPlay.Play("fbx02", -1, 0.0f);

Share this post


Link to post
Share on other sites

Hallo Leute,

eine Frage ergibt sich gerade noch:

Ich habe dem Button eine zweite Funktion gegeben.

Erste Funktion: Animation spielt ab (Würfel dreht sich).

Zweite Funktion: Video spielt ab.

Wenn ich das Script auf einen zweiten Button lege, um dem einen

die Animator.Play zu geben und dem anderen die video.Play, dann geht's nicht.

Nur der erste Button führt auch beide Funktionen aus, der zweite Button macht einfach

generell nix.

Kann ich das selbe Script nicht mehrmals vergeben? In den VR samples von Unity ist das glaube ich so.

 

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using VRStandardAssets.Utils;
namespace VRStandardAssets.Menu
{
// This script is for loading scenes from the main menu.
// Each 'button' will be a rendering showing the scene
// that will be loaded and use the SelectionRadial.
public class MenuButton : MonoBehaviour
{
	public event Action<MenuButton> OnButtonSelected;				   // This event is triggered when the selection of the button has finished.

	[serializeField]
	private string m_SceneToLoad;					  // The name of the scene to load.
	[serializeField]
	private VRCameraFade m_CameraFade;				 // This fades the scene out when a new scene is about to be loaded.
	[serializeField]
	private SelectionRadial m_SelectionRadial;		 // This controls when the selection is complete.
	[serializeField]
	private VRInteractiveItem m_InteractiveItem;	   // The interactive item for where the user should click to load the level.
	[serializeField]
	public Animator m_animationPlay;
	[serializeField]
	public MediaPlayerCtrl m_videoplay;
	private bool m_GazeOver;											// Whether the user is looking at the VRInteractiveItem currently.

	private void OnEnable()
	{
		m_InteractiveItem.OnOver += HandleOver;
		m_InteractiveItem.OnOut += HandleOut;
		m_SelectionRadial.OnSelectionComplete += HandleSelectionComplete;
	}

	private void OnDisable()
	{
		m_InteractiveItem.OnOver -= HandleOver;
		m_InteractiveItem.OnOut -= HandleOut;
		m_SelectionRadial.OnSelectionComplete -= HandleSelectionComplete;
	}

	private void HandleOver()
	{
		// When the user looks at the rendering of the scene, show the radial.
		m_SelectionRadial.Show();
		m_GazeOver = true;
	}

	private void HandleOut()
	{
		// When the user looks away from the rendering of the scene, hide the radial.
		m_SelectionRadial.Hide();
		m_GazeOver = false;
	}

	private void HandleSelectionComplete()
	{
		// If the user is looking at the rendering of the scene when the radial's selection finishes, activate the button.
		if (m_GazeOver)
			StartCoroutine(ActivateButton());
	}

	private IEnumerator ActivateButton()
	{
		// If the camera is already fading, ignore.
		if (m_CameraFade.IsFading)
			yield break;
		// If anything is subscribed to the OnButtonSelected event, call it.
		if (OnButtonSelected != null)
			OnButtonSelected(this);
		m_animationPlay.Play("CINEMA_4D_Basis", -1, 0.0f);
		// Wait for the camera to fade out.
		// yield return StartCoroutine(m_CameraFade.BeginFadeOut(true));
		// Load the level.
		// SceneManager.LoadScene(m_SceneToLoad, LoadSceneMode.Single);
		// Animation.Play("CINEMA_4D_Basis", -1, 0.0f);
		// m_animationPlay.Play("CINEMA_4D_Basis", -1, 0.0f);
           m_animationPlay.Play("fbx02", -1, 0.0f);
		m_videoplay.Play();


	}

}
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×