Call function from a premade script in Unity - unity3d

How do I call a function from a Unity (XR Interaction Toolkit) script that's appended to a Ray Interactor? Precisely what I have is a GameObject made as an XR Ray Interactor and appended the XR Direct Interactor script. I want to call the function GetValidTargets from that script to see with what GameObject it targets. How do I call this function in another script? I already have the GameObject specified and tried different methods to implement it, for example GetComponent<>().
This is what the function says in the script so that comes after I call it.
/// Retrieve the list of interactables that this interactor could possibly interact with this frame.
/// This list is sorted by priority (in this case distance).
/// <param name="validTargets">Populated List of interactables that are valid for selection or hover.</param>
public override void GetValidTargets(List<XRBaseInteractable> validTargets)
How do I call this function?

Calling the function if you want to call the function, append the XRBaseInteractable component to every GameObject that you want to able to hover or interact with. Create a List (which are in the System.Collections.Generic namespace), add each XRBaseInteractable instance to it and pass it in to the GetValidTargets() function.
GameObject[] interactableObjects; // Set in inspector or somewhere in code
List<XRBaseInteractable> interactables = new List<XRBaseInteractable>();
foreach(GameObject interactableObject in interactableObjects)
{
interactables.Add(interactableObject.GetComponent<XRBaseInteractable>());
}
GetComponent<XRDirectInteractor>().GetValidTargets(interactables);

Related

MRTK Add ManipulationHandler in C#

I'm attempting to dynamically add Manipulation Events to a ManipulationHandler that is being added to child objects of a parent. The parent object will be what the user is inspecting, but the user will be able to grab parts off of the parent and inspect them more closely. (i.e. you can look at an engine (parent object), but if you want to inspect the pistons (child objects) you can grab them and look at them)
Instead of having to go into every child object and manually add it in Unity I'd like to be able to add the parent object and just procedurally add the ManipulationHandler and ManipulationEvents on start or awake.
So far I have the following code for adding the ManipulationHandler script, but to add the ManipulationEvent I'm not sure how to set up the pointers so I can use the script and function I want from the source:
gameObject.AddComponent<ManipulationHandler>();
ManipulationHandler handler = gameObject.GetComponent<ManipulationHandler>();
ManipulationEvent newevent = new ManipulationEvent();
ManipulationEventData eventdata = new ManipulationEventData();
eventdata.ManipulationSource = gameObject;
The program works when I grab the objects, but I'd like to add manipulation events when I grab them so I can display additional data.
I see there's a getter and setter for Pointer in ManipulationEventData, but I'm not sure how to instantiate IMixedRealityPointer and how to get it to work. I'm also not sure if that's the object I actually need to accomplish what I'd like to accomplish.
I apologize in advance if I've missed something obvious. I'm new to MRTK.
Thanks!
The ManipulationHandler has four callback events among them OnManipulationStarted and OnManipulationEnded you can simply add listeners to. (see UnityEvent.AddListener)
Unless I understood your question wrong you don't have to instantiate any IMixedRealityPointer. You don't create the event data yourself but rather the ManipulationHandler feeds these events with the current event data including the interacting pointer information. The ManipulationHandler uses OnPointerDown and OnPointerDragged and OnPointerUp via the IMixedRealityPointerHandler interface in order to manage the interacting pointers and invokes the according events where needed.
Instead of using AddComponent followed by GetComponent directly store and use the return value of AddComponent which will be the reference of the newly added Component. MRTK also has an extension method
T EnsureComponent<T>(this Component component) where T : Component
so that you can simply use e.g.
var handler = this.EnsureComponent<ManipulationHandler>();
which internally first checks whether the component already exists, and if not it adds it.
Note that in order to enable near interactions you will also need a NearInteractionGrabbable so you should add this one too.
You also will have to make sure that your objects have some sort of Collider attached to the same GameObject as the NearInteractionGrabbable.
...
gameObject.transform.EnsureComponnet<NearInteractionGrabbable>();
var handler = gameObject.transform.EnsureComponnet<ManipulationHandler>();
handler.OnManipulationStarted.AddListener(HandleOnManipulationStarted);
handler.OnManipulationEnded.AddListener(HandleOnManipulationEnded);
...
/// <summary>
/// If you need it later you need to store the pointer since unfortunately in
/// OnManipulationEnded the <see cref="ManipulationEventData.Pointer"/> is null
/// (no idea why they do it this way :D )
/// </summary>
private IMixedRealityPointer _pointer;
private void HandleOnManipulationStarted(ManipulationEventData eventData)
{
_pointer = eventData.Pointer;
// whatever shall happen when manipulation started
}
private void HandleOnManipulationEnded(ManipulationEventData eventData)
{
// whatever shall happen when manipulation ended
}
Note: I am not sure if this thing you are trying to achieve is possible with this architecture ... it is very possible that nesting various ManipulationHanlder leads to strange behavior here and there. Especially very small parts will be almost impossible to grab ...

What is the difference between GetComponent<Image> ().enabled and .SetActive (false); in unity

I have been trying to use SetActive () to turn on and off GameObjects.
I couldn't figure it out and ended up using:
GameObject.Find ("ObjectName").GetComponent<Image> ().enabled = false;
to turn off an image.
I am not trying to use the same script to turn off a GameObject that has multiple animations nested inside it.
GameObject.Find ("ObjectName").GetComponent<???> ().enabled = false;
GameObject.Find ("ObjectName").SetActive (false);
I am not sure what goes in the <>, but I have read I can do it with SetActive (), but that doesn't seem to work and gives me an "Object Reference not set to object" error.
So what is the difference between these two and how would I use them properly?
Using GetComponent allows you to enable/disable and interact with specific components on a GameObject.
For example, you may need to disable a GameObject's rigidbody at some point, but you still want that object, and everything else on it to be active. So you could simply say:
GameObject.Find("MyObject").GetComponent<Rigidbody>().enabled = false;
Note that what goes inside the "<>" is the class name of the component you want to interact with.
For example, if you had a script you have written yourself on a gameobject called MyScript, you could grab hold of it like so:
MyScript script = GamesObject.Find("MyObject").GetComponent<MyScript>().enabled = true;
Additionally, another good use of GetComponent is reading information from a script on an object.
For example, if you had a script called Health with a public variable HitPoints on an object, another script could gain access to that information using GetComponent.
if( enemyGameObject.GetComponent<Health>().HitPoints < 0 )
{
enemyGameObject.SetActive(false);
}
Using SetActive will enable and disable a GameObject entirely. This is less expensive than deleting / making a new object, and is thus often used in techniques like Object Pooling.
For example, if you had a GameObject that you needed disabled, but you knew you were going to need it again soon, it is far less expensive to just call
MyGameObject.SetActive(false);
...
MyGameObject.SetActive(true);
Than it is to delete that object entirely, and then make a new one when you are ready for it again.
To add up to the other answers, when a component is disabled it means the MonoBehaviour callbacks are not called anymore. So no Update, FixedUpdate, OnCollisionXXX and so on.
Awake is called when the object is created so it is obviously enabled by default at that stage. Start is called on the first run after Awake. So if you set the component off in Awake, Start will wait until you set it back on from elsewhere.
OnEnable/OnDisable are called when you modify the enabled property.
SetActive works on the GO and is pretty much a shortcut to disable all components at once.
gameObject.SetActive(false);
foreach(var comp in GetComponentsInChildren<MonoBehaviour>()){
comp.enabled = false;
}
those are fairly similar in result (maybe not in efficiency). Actually, when you set a game object on/off, the OnEnable/OnDisable of each component is called. All MonoBehaviour callbacks are not called anymore if you set the object off.
So, the choice is dependent on what you are after, if you wish to disable movement but still see the object and other actions:
GetComponent<Movement>().enabled = false;
if you wish to kill an enemy:
enemy.gameObject.SetActive(false);
Note that even though a component is disable, does not mean you cannot interact with it. You can still manually call any method on it. Consider this:
AnyComponent ac = gameObject.GetComponent<AnyComponent>();
ac.enabled = false;
ac.AnyMethod();
Valid and will do what it is meant to do considering it does not require an Update or a FixedUpdate (Physics action).
A deactivated component cannot be found with GetComponent, you can get it with GetComponentInChildren(true) since it also searches the game object and its children. I am not sure whether it returns the first found or the first active found.
myGameObject.SetActive(false);
AnyComponent ac = myGameObject.GetComponent();
AnyComponent acic = myGameObject.GetComponentInChildren(true);
even though the GO has a AnyComponent attached, ac is null, acic is not (seems to be a 5.3 feature though).
http://docs.unity3d.com/ScriptReference/Component.GetComponentInChildren.html
Finally, for a component to expose the tick, it needs to have a Start method in the script (don't ask why...).
Setting .enabled turns one component on a GameObject on or off, e.g. an Image. Using SetActive() turns the whole GameObject on or off.
Choosing which to use should correspond with what you want to disable.

How to use components of one script into another?

I want to use components (variable, function, objects) of one UnityScript into another. To do so I use following script code, but it throws an exception called nullpointerreference and is not displaying value in log.
public var hitCar:camrot;
function Update()
{
if(hitCar.hit==1)
Debug.Log(hitCar.hit);
}
camrot is another UnityScript where hit variable is declared as public integer, and above code is implemented in different script than camrot UnityScript file.
If you want to access variables from another script, you may have to find the GameObject that the script is attached to in order to use it.
(C#, I don't know JavaScript)
Script 1 - Attached to "Player" GameObject, script is called PlayerScript
public bool canJump;
void Update()
{
//code
}
Script 2 - Attached to a different GameObject
GameObject player;
void Start()
{
player = GameObject.Find("Player"); //finds the gameobject called "Player"
}
void Update()
{
player.GetComponent<PlayerScript>().canJump = false; //use the variable in another script!
}
Hope this helps :)
depending on the scope you are looking for just remember if you don't declare a variable and simply assign a value it will automatically be of the GLOBAL scope.
So simply assigning hitCar.hit=1 without declaring it will assign a GLOBAL scope and will work across all interrelated scripts and functions. If you assigned the hitCar.hit in another script then redeclare it in this script it will also revert back to null as well. So remove all declarations and see what happens.
If UNITY is "strict" then declare these variables at the top of the first script file to be executed.

Tetris in unity3d

I'm designing a 3D Tetris game. I'm new to unity and just started to learn some basics in this site
My plan is not to create a regular tetris board, but to create a 3D surface, with width,height and depth so the user will need to build a surface in order to destroy the objects.
So in my design I know that I need an object generator and to create an object (Tetris cube) in they that I'm calling the object generator in the update method with some timer.
Also the idea is to make a 3d matrix that represent the game board so I could check in the game logic if there is a "surface" in that matrix.
This is a part of the game logic script.. and my problem is that i don't know where to put this script.. I mean in the game logic I need to create a random cube, and to check if there is a surface that can be destroyed.. but where should I put the game logic script?
I always used IDE's like visual studio or eclipse so there you can have a main class with the main method that start your program.. and now in unity i'm confused..
Edit:
Thanks for your replying.. I forgot to mention that I have something like 3 scenes (levels) in the game.. so for each level (scene) should I create an empty game object?
make an empty gameobject and attach your object that you want to spawn(as child) to it and attach your spawn code to that empty object(parent)
Create an empty gameobject like mentioned and put a script on it that saves it from being destroyed on scene-change (some sort of singleton).
Some basic way to do it:
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
private static GameController instance
public static GameController Instance
{
get { return instance; }
}
private void Awake()
{
instance = this;
DontDestroyOnLoad(instance);
}
}
The DontDestroyOnLoad will hold the whole gameobject with everything attached to stay loaded on scene-change.

Should I use Start or Update to call the given method in Unity3d

1.I have a class in which I have a method called ProjectileMotion() with return type IEnumerator and this method is being called from Start().
2. The above script is attached to a prefab that is instantiated from another class.
Problem:
In IENumerator ProjectileMotion() method, I need to have updated position of an object which is moving continuously,so I declared
//assigned the o=gameobject to it and it is moving continuously
Public Transform Target;
In ProjectileMotion(), if I do Target.transform,position, it gives the starting position only and not where it was at the time of instantiation of the prefab to which this script is attached, However, I am able to get the updated position of Target in Update method(checked using Debug.Log).
But I can not call the ProjectileMotion() in Update method of course, what should I do to get updated position of Target every time the prefab is instantiated and so the script is called.
Simply put ...
If you want the code to execute when the component is "started" then call it on start.
OR
If you want the code to execute each frame after the component has started then call it on update.
Judging by the name of this method I would think this is something that updates the position of a projectile after a gun has instantiated it.
The position being updated is likely a per frame operation so.
I would put this in the update method.
EDIT:
UNLESS ...
Does this function do a multiframe animation?
Unity has the concept of coroutines that allow to do certain actions of several frames. in this case you might be better off doing something like this in your start method ...
StartCoroutine(ProjectileMotion)