Hi,
I have problem with event triggers. I don't know how can I pass an argument to my function. I need to do it through editor, because I have a lot of objects that use this script and this method is only difference between them.
It is fragment of my code, simplify for question:
public override void OnEndDrag(PointerEventData data)
{
lpbc = null;
if (data.pointerCurrentRaycast.gameObject == null || data.pointerCurrentRaycast.gameObject.tag!="Field")
{
return;
}
if (data.pointerCurrentRaycast.gameObject.tag == "Field")
{
//some methods to define my go
GameObject go;
//HERE I want to call function from picture BUT with my go
//when I do below line, I can call EndDrag with my function, but how to pass my argument??????????
base.OnEndDrag(data);
}
}
Related
I have an InputField for search terms in my application witch develop with unity.
On android mobile device , I need to find when Ok or Done clicked by user or edit the inputfield end to call a method to doing search.
Ok, After try many code and document ! solved it :
public void Start()
{
//Adds a listener that invokes the "LockInput" method when the player finishes editing the main input field.
//Passes the main input field into the method when "LockInput" is invoked
termInputField.onEndEdit.AddListener(delegate { LockInput(termInputField); });
}
void LockInput(TMP_InputField input)
{
if (input.text.Length > 2)
{
Debug.Log("Text has been entered");
DoSearch();
}
else if (input.text.Length == 0)
{
Debug.Log("Main Input Empty");
}
}
public void DoSearch()
{
//My Code For Doing Search!
}
In Unity I have GameObjectName which has script 1 and script 2 attached to it. Script1 is an IEnumerator like this.
public IEnumerator Sunglasses()
{
// Do stuff
}
Script2 looks like this.
public void Start()
{
Function1();
String blah = "Things";
Function2();
StartCoroutine(Routine2());
StartCoroutine(Routine3());
}
I need script 1 to finish Sunglasses before script 2 does anything. If I try accessing GameObjectName.Script1 from Script2, Unity says it doesn't exist. How can I make sure that script 1 finishes before starting script 2?
You can add a boolean variable in script one, after the Sunglasses function call is done, set it to true.
Script1:
public bool isDone = false;
public IEnumerator Sunglasses()
{
// Do stuff
isDone = true;
}
Script2:
Then in your Script2, you can make your Start function to be a coroutine or IEnumerator instead of a void function. After this, you can wait for isDone to be true every frame.
public bool isDone;
Script1 script1Ref;
public IEnumerator Start()
{
GameObject s1Obj = GameObject.Find("GameObjectScript1IsAttachedTo");
script1Ref = s1Obj.GetComponent<Script1>();
//Wait here until we are done
while (!script1Ref.isDone)
yield return null;
//Done Waiting, now continue with the rest of the code
Function1();
String blah = "Things";
Function2();
StartCoroutine(Routine2());
StartCoroutine(Routine3());
}
Finally, if you also need to make sure that Script1 is dine before doing something in the Update function of Script2, just check the isDone variable and return if it it still false.
void Update()
{
//Return if script 1 is not done
if (!script1Ref.isDone)
return;
//The rest of your code below
}
Note that you want StartCoroutine(Routine3()) to wait until StartCoroutine(Routine2()) is done, you have to yield it.
Replace StartCoroutine(Routine3()) with yield return StartCoroutine(Routine3()).
You can try studying events, or observer pattern. What I have been using is the latter which allows me to add callbacks with a string identifier. For events, you do something like
public static event System.Action onSunglassesCompleted;
public IEnumerator Sunglasses()
{
//Sunglasses logic here
//if there is a listener to the event, call it
if(onSunglassesCompleted != null)
{
onSunglassesCompleted();
}
}
Then on Script2, you just have to add the listener to the event
void Start()
{
Script1.onSunglassesCompleted += DoThisAfterSunglasses;
}
//This will be called in Script1
void DoThisAfterSunglasses()
{
//Make sure you do this to avoid memory leaks or missing reference errors once Sprite1 is destroyed
Script1.onSunglassesCompleted -= DoThisAfterSunglasses;
Function1();
String blah = "Things";
Function2();
StartCoroutine(Routine2());
StartCoroutine(Routine3());
}
One thing you can do in events to avoid leaks is by setting it to null after you call it.
if(onSunglassesCompleted != null)
{
onSunglassesCompleted();
onSunglassesCompleted = null;
}
Possible to reset looping of void Start using button in unity ?
void Start()
{
if (NoAnsweredQuestion == null || NoAnsweredQuestion.Count == 0)
{
NoAnsweredQuestion = question.ToList<Question>();
}
StartCoroutine("CountDownTimer");
SetcurrentQuestion();
}
If your goal is to execute the code the in the Start Method multiple times, you have a bad design, but if you really need to have it in the start Method just destroy the script with a diffrent one and put it on again.
What I would recommend is, that you move this code just in the method that gets executed if the button gets pressed.
Anyway like 'Lestat' said your question is really strange and I can not really understand it aswell.
You can create a function using:
public void YourFunctionName (){
if (NoAnsweredQuestion == null || NoAnsweredQuestion.Count == 0)
NoAnsweredQuestion = question.ToList<Question>();
StartCoroutine("CountDownTimer");
SetcurrentQuestion();
}
If you are using Canvas (which I recommend you do!), you simply add a new button:
And then add the function to the button using the '+' sign, drag your GameObject (with your script attached to it) and select the class and then the function (must be public in order to work).
And I guess this will solve your problem.
Alright, I have a Dialogue system in place in my game. It is pretty simple in its design. Each dialogue contains a list of nodes which would be what the NPC would say and for each node there is also a list of options that the player can choose from either to end the conversation or continue on. The dialogue part works flawlessly. What I am trying to do is combine it with a questing system. Before I get too far into my questing system I need to figure out a way to connect my dialogue system to my questing system or NPC (preferably my NPC). The way my dialogue system is set up is with a Singleton pattern and each NPC would just call a method on it that starts a dialogue with a player based on its local dialogue variable.
I've been sitting here thinking about how I can pass a value from my dialogue manager to my NPC but, considering that my run method is a Coroutine I can't figure out how to return that value after I exit the coroutine if I need to. I feel like this should be possible but, I really can't think of a way to do this. Any help would be appreciated.
An ideal situation is to get the RunDialogue method to return a variable type(bool?), but only after EndDialogue has been called from within the run method. If it returns true then assign the quest otherwise do nothing.
From DialogueManager:
public void RunDialogue(Dialogue dia)
{
StartCoroutine(run(dia));
}
IEnumerator run(Dialogue dia)
{
DialoguePanel.SetActive(true);
//start the convo
int node_id = 0;
//if the node is equal to -1 end the conversation
while (node_id != -1)
{
//display the current node
DisplayNode(dia.Nodes[node_id]);
//reset the selected option
selected_option = -2;
//wait here until a selection is made by button click
while (selected_option == -2)
{
yield return new WaitForSeconds(0.25f);
}
//get the new id since it has changed
node_id = selected_option;
}
//the user exited the conversation
EndDialogue();
}
From NPC:
public override void Interact()
{
DialogueManager.Instance.RunDialogue(dialogue);
}
There is a way to make a coroutine return a value. Requires some nesting, you can have a look at this video if you want to go this way: Unite 2013 - Extending Coroutines # 20m38s on "adding return values"
Otherwise, you can pass a callback to the coroutine. This will probably do it for you.
Add some function at a point where it makes sense (e.g. the NPC):
public void OnGiveQuest()
{
// Add the quest
}
Add it to the dialogue call:
public override void Interact()
{
DialogueManager.Instance.RunDialogue(dialogue, OnGiveQuest);
}
Then change your RunDialogue and run to take a callback:
public void RunDialogue(Dialogue dia, System.Action callback = null)
{
StartCoroutine(run(dia, callback));
}
Now, for the coroutine, you either pass the callback further to EndDialogue or handle it in here too after the end call.
IEnumerator run(Dialogue dia, System.Action callback = null)
{
...
//the user exited the conversation
EndDialogue();
if(callback != null)
callback();
}
Now, I made it the way that you would only add the callback if you want to start a quest. Otherwise you just leave it out (default value of null).
private void CheckingSelection() {
Transform child = Selection.activeTransform;
Transform[] patchesTransform = builder.GetLevelEditorPatchesTransform();
foreach (var parent in patchesTransform) {
if (child.IsChildOf(parent) && child != parent) {
Debug.Log("Set active " + parent.gameObject);
Selection.activeGameObject = parent.gameObject;
}
}
}
That's what I do, but it does not select the parent. What am I do wrong ?
The deal is how I called method CheckingSelection();
I added this method to delegate Selection.selectionChanged. And I thought its kind of logical things to do my checking after selecting something. But it was not working. It might be of internal Unity things, that block recursy or some.
So, I addedCheckingSelection() method to EditorApplication.update delegate, and it works.