I have defined some custom functions in the following script and attached with my gameobject. I want to declare my function OnReticleEnter() to mimick OnPointerEnter(). Is it possible? I want this because I want to access my function OnReticleEnter() in the inspector so that I can define multiple actions like EventTrigger's Point Enter, Exit etc.
Is it possible to make the function OnReticleEnter() to behave as OnPointerEnter() programmatically?
using UnityEngine;
using System.Collections;
public class MyObject : MonoBehaviour
{
// Custom reticle events
public GameObject gOBJ;
public void OnReticleEnter()
{
gOBJ.SetActive(true);
}
public void OnReticleExit()
{
gOBJ.SetActive(false);
}
public void OnReticleHover()
{
gOBJ.SetActive(true);
}
}
You need to inherit the interfaces for the pointerEnter and PointerExit events in your class to be able to implement them. Your code might look something like this :
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
public class MyObject : MonoBehaviour,IPointerEnterHandler, IPointerExitHandler
{
// Custom reticle events
public GameObject gOBJ;
public void OnPointerEnter(PointerEventData eventData){
gOBJ.SetActive(true);
}
public void OnPointerExit(PointerEventData eventData){
gOBJ.SetActive(false);
}
}
Related
I'm pretty new to Unity and C# scripting.
In my scene I have four buttons. I declared them in my script as public and put the items (on type Button) via drag and drop in my inspector in unity. Depending on which button is clicked, i want my program to do something. You can see in the script below what I've done. That scripts works perfectly just like I want it to.
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Example : MonoBehaviour
{
public Button Left;
public Button Right;
public Button Starten;
public Button Zurueck;
private void Start()
{
loadRezept(0);
Right.onClick.AddListener(iterationUp);
Left.onClick.AddListener(iterationDown);
Starten.onClick.AddListener(starten);
Zurueck.onClick.AddListener(zurueck);
}
... (here are the methods "iterationUp" and so on...)
This script work perfectly. But now there is my question: how can I do the same on using gameobjects?
If I just change the type "Button" to "GameObject" I don't have the possibility to use "onClick.AddListener". I don't want a script for every single gameobject. I just want something like I posted above.
GameObject itself has no such events.
Sounds like what you are asking for is a custom UnityEvent
You can create your own component like e.g.
public class HighlightController : MonoBehaviour
{
public UnityEvent OnHighlight;
// Somewhere Invoke the event e.g.
public void SetHighlighted()
{
OnHighlight.Invoke();
}
}
where you can add listeners now either via code or via the Inspector (just like the onClicked).
So put this on your GameObjects and then e.g. have fields like
[SerializeField] private HighlightController highlight;
//etc...
private void Awake()
{
highlight.OnHighlight.AddListener(HandleHighlight);
//etc...
}
private void HandleHighlight ()
{
...
}
// Make sure to cleanup listeners when not needed anymore
private void OnDestroy()
{
highlight.OnHighlight.RemoveListener(HandleHighlight);
//etc...
}
Or yes as mentioned as simple event could do the same without the serialization:
public class HighlightController : MonoBehaviour
{
public event Action OnHighlight;
public void SetHighlighted ()
{
OnHighlight?.Invoke();
}
}
and do
private void Awake()
{
highlight.OnHighlight += HandleHighlight;
}
private void OnDestroy ()
{
highlight.OnHighlight -= HandleHighlight;
}
I'm trying to create a FMV game and I would like to figure out a way to control the video player with a UI button to change scene but only after the clip has finished playing.
If the user doesn't pick anything it will automatically be a default pathway and I have managed to use loopPoinReached and it has worked.
I can figure out how to use the same loopPointReached with a button.
Here is the video player code and it will auto load the next scene.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class loadBaseCampSeq : MonoBehaviour
{
void Start()
{
GameObject camera = GameObject.Find("Main Camera");
var videoPlayer = camera.AddComponent<UnityEngine.Video.VideoPlayer>();
videoPlayer.renderMode = UnityEngine.Video.VideoRenderMode.CameraNearPlane;
videoPlayer.url = "Assets/VideoAssets/intro.mp4";
videoPlayer.isLooping = false;
videoPlayer.Play();
videoPlayer.loopPointReached += EndReached;
}
void EndReached(UnityEngine.Video.VideoPlayer vp)
{
UnityEngine.SceneManagement.SceneManager.LoadScene("baseCampSeq");
}
}
Here is the basic code that I have assigned to the UI Button On Click ()
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class loadTruckButton : MonoBehaviour
{
public void truckSeq()
{
SceneManager.LoadScene("truckSeq");
}
}
I have been trying to reference the "EndReached" from the other script in the button but I cannot figure it out.
Any help would be awesome!
Thanks
You'll have to segregate the videoplayer functionality from the loadBaseCampSeq class into a new class. In the loadBaseCampSeq class create a videoplayer (instance) field and an abstract EndReached method:
public abstract class loadBaseCampSeq
{
public VideoPlayer videoPlayer;
public abstract void EndReached();
}
Create a button class which inherits from the loadBaseCampSeq base class. In the button class override the EndReached method that uses the videoplayer instance from it's base class:
public class Button : loadBaseCampSeq
{
public override class EndReached()
{
videoPlayer.EndReached();
}
}
I wrote little script yesterday but it isn't working. (Serialize fields isn't showing in unity and few errors eg. I can't use reference to non-static member (serialize Field)). Can You help me please.
Eg.
using UnityEngine;
public class sExample : MonoBehaviour
{
[SerializeField] public static GameObject gameObj;
public void serializeUse()
{
//Do something with gameObj
}
}
public class serializeEx : NetworkBehaviour
{
public void Update()
{
If (!isLocalPlayer)
{
sExample.serializeUse()
}
}
}
Thanks alot
That should work.
I think that you can't use static, when you want to expose something to the Editor.
using UnityEngine;
[Serializable]
public class sExample : MonoBehaviour
{
[SerializeField] public GameObject gameObj;
public void serializeUse()
{
//Do something with gameObj
}
}
public class serializeEx : NetworkBehaviour
{
public void Update()
{
If (!isLocalPlayer)
{
sExample.serializeUse()
}
}
}
Edit:
Statics seem to work for JavaScript as mentioned in this post.
To make this work you'll have to switch to the debug view in the inspector.
Like in the image shown below:
Edit2:
The explanation what the Serializeable does is taken from the unity documentation.
The Serializable attribute lets you embed a class with sub properties
in the inspector.
You can use this to display variables in the inspector similar to how
a Vector3 shows up in the inspector. The name and a triangle to expand
its properties. To do this you need create a class that derives from
System.Object and give it the Serializable attribute. In JavaScript
the Serializable attribute is implicit and not necessary.
using UnityEngine;
[System.Serializable]
class Test : System.Object
{
public int p = 5;
public Color c = Color.white;
}
Let's say I would like to add functionality to the OnSelect() Event of a dropdown element.
Normally I would just add a new script to the specific dropdown gameObject:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
//Do this when the selectable UI object is selected.
public void OnSelect(BaseEventData eventData)
{
Debug.Log(this.gameObject.name + " was selected");
}
}
Hint: The script simply outputs a message if the Dropdown is getting selected.
Question: Is it possible to define the functionality inside another script?
E.g. I have a script attached to the master parent "Menue" where I am referencing this specific dropdown gameobject.
How can I define the OnSelect inside another script?
PS: Is this the correct place to ask this question, or should I ask it on gamedevelopement instead?
Use event and delegate. You can find a simplified tutorial for that here if this is new to you.
It should be something like this:
public delegate void SelectAction(GameObject target);
public static event SelectAction OnSelectedEvent;
Add that to your LanguageDropdown script and you should get this:
public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
public delegate void SelectAction(GameObject target);
public static event SelectAction OnSelectedEvent;
//Do this when the selectable UI object is selected.
public void OnSelect(BaseEventData eventData)
{
Debug.Log(this.gameObject.name + " was selected");
//Invoke Event
if (OnSelectedEvent != null)
{
OnSelectedEvent(this.gameObject);
}
}
}
Now, you can subscribe and un-subscribe to the event in the OnEnable and OnDisable functions respectively script from another script:
void OnEnable()
{
//subscribe to event
LanguageDropdown.OnSelectedEvent += SelectAction;
}
void OnDisable()
{
//Un-subscribe to event
LanguageDropdown.OnSelectedEvent -= SelectAction;
}
//This will be called when invoked
void SelectAction(GameObject target)
{
Debug.Log(target.name + " was selected");
}
Basically I wanted to know if I am forced to attach the script
LanguageDropdown to the gameobject, or If this is not required and I
can setup everything from another script which is not attached to that
specific dropdown.
No, you can use the EventTrigger class to register the events like below and you won't have to attach it to each object:
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Select;
entry.callback.AddListener((eventData) => { SelectAction(); });
Please, do not use that. It is slow and I have verified this from multiple people too.
A Unity-centric solution would be to use a UnityEvent which lets you make these changes in the inspector.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
public UnityEvent Selected;
//Do this when the selectable UI object is selected.
public void OnSelect(BaseEventData eventData)
{
Debug.Log(this.gameObject.name + " was selected");
Selected.Invoke();
}
}
Then the LanguageDropdown component will have a Selected member visible in the inspector to which you can then assign an Object and method target (much like a Button).
Note: You can change UnityEvent to UnityEvent<LanguageDropdown> if you want to include the source object:
public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
public UnityEvent<LanguageDropdown> Selected;
//Do this when the selectable UI object is selected.
public void OnSelect(BaseEventData eventData)
{
Debug.Log(this.gameObject.name + " was selected");
Selected.Invoke(this);
}
}
The target method must then have the correct parameter list
(i.e. public void method(LanguageDropdown dropdown) )
You can define public method in another script, and call it int OnSelect() implementation.
For example:
public interface IDropdownContext
{
void OnDropdownSelected(BaseEventData eventData);
}
public class Test : MonoBehaviour, IDropdownContext
{
public void OnDropdownSelected(BaseEventData eventData)
{
Debug.Log("OnDropdownSelected");
}
}
public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
[SerializeField]
public Test context;
//Do this when the selectable UI object is selected.
public void OnSelect(BaseEventData eventData)
{
Debug.Log(this.gameObject.name + " was selected");
context.OnDropdownSelected(eventData);
}
}
I have defined three functions (OnReticleEnter(),Exit() and hover()) in the script and attached with a game object:
using UnityEngine;
using System.Collections;
using TMPro;
public class MyObject : MonoBehaviour
{
// Custom reticle events
public GameObject gOBJ;
void OnReticleEnter()
{
gOBJ.SetActive(true);
}
void OnReticleExit()
{
gOBJ.SetActive(false);
}
void OnReticleHover()
{
gOBJ.SetActive(true);
}
}
My problem is I want these functions in the inspector window so that I can define multiple actions like event trigger's pointer enter.
Is there any way I can make these functions available as event trigger on inspector window?