The function Input.GetMouseButtonDown id true for two frames consecutively in Unity3D. Why - unity3d

I have a code like the following:
void Update()
{
if(Input.GetMouseButtonDown(1))
{
Debug.Log("foo");
}
}
The problem is that if I click the right mouse button once the "foo" is written twice. How is it possible?

As Frohlich stated in comment, If you attach a script on more than one GameObject you will be getting Update method call per frame for each script in scene. So to check that you should use Debug.Log() method as follow:
Debug.Log("foo",gameObject);
and when you will click on log in console window, it will take you to the gameObject which is generating that log.

Related

Unity not detecting F1 and F2 key presses

I am returning to unity after 6 months. I started my fps game yesterday. Today I was trying to make C4 bomb, which worked as follows: the c4 will already be placed, you just have to activate using a remote. In the start the remote will not be in your hand, you have to press F1 to set it active. To put the remote away again, we have to press F2. But the problem is that it won't detect my F1 key press. Here's the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class C4Script : MonoBehaviour
{
public GameObject remote;
private bool remoteHand;
// Start is called before the first frame update
void Start()
{
remote.SetActive(false);
remoteHand = false;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.F1) && !remoteHand)
{
remote.SetActive(true);
remoteHand = true;
}
if (Input.GetKeyUp(KeyCode.F2) && remoteHand)
{
remote.SetActive(false);
remoteHand = false;
}
}
}
The code may be wrongly formatted, I am sorry for that.
Also sorry if I didn't explain it properly.
Thanks!
The code works on my machine, do you maybe have the C4Script or the Gameobject on which it is attached disabled?
Looks like the script is never called rather then that it's not detecting the input. You could add an Debug log or debug breakpoint to the start method to check if it's ever called.
Soo, the problem was that i am dumb. i Put this script on the remote, and at the start it disables the remote thats why it wasn't detecting my key press. I put the script on my player object and now it works fine.

How to get info about completion of one of my animations in Unity?

I have monster named Fungant in my 2D platform game.
It can hide as mushroom and rise to his normal form.
I try to handle it in code, but I don't know how to get information about finished animation (without it, animation of rising and hiding always was skipped).
I think the point there is to get info about complete of the one of two animations - Rise and Hide.
There is current code:
if (
fungantAnimator.GetCurrentAnimatorStateInfo(0).IsName("Fungant Rise")
)
{
fungantAnimator.SetBool("isRising", false);
isRisen = true;
fungantRigidbody.velocity = new Vector2(
walkSpeed * Mathf.Sign(
player.transform.position.x - transform.position.x),
fungantRigidbody.velocity.y
);
}
if (fungantAnimator.GetCurrentAnimatorStateInfo(0).IsName("Fungant Hide"))
{
fungantAnimator.SetBool("isHiding", false);
isRisen = false;
}
I try this two ways:
StateMachineBehaviour
I would like to get StateMachineBehaviour, but how to get it?
No idea how to process this further.
AnimationEvents
Tried to do with animation event but every tutorial have list of functions to choose (looks easy), but in my Unity I can write Function, Float, Int, String or select object (what I should do?).
I decided to write test() function with Debug only inside, and create AnimationEvents with written "test()" in function field, but nothing happens.
Same as above, no more ideas how to process this further.
I personally would use animation events for this. Just add an event to the animation and then the event plays a function after the animation transition is finished.
For more information on how to use animation events you can click here.
This post may also help you to add an event when the animation is finished.
I hope this answer helps you to solve this problem.

Is there any function in Unity 2d , when I die the the game over screen comes only after death animation finishes

Any way to show Game over screen only after the death animation of player is played text
Check in update if animation is playing or not. if animaion.IsPlaying() return false means your animation is finish and then you show your game over screen.
in your player script (or whatever script tells your die animation to play), go below the line where the die animation plays, then write this line of code: StartCoroutine(ExampleCoroutine());. Make sure you replace the 'ExampleCoroutine' part with the name of the IEnumerator method (more on that in the next sentence). Next, go below the function where you typed StartCoroutine(ExampleCoroutine());. and make an IEnumerator method. Inside it type yield return new WaitForSeconds(1f);. and replace the 1 with how long it takes for the die animation to finish. Lastly, below that line, activate your game over screen. Hope this helped a bit!
If you want to attach code functions to animations, you can use animation events to call functions at very specific times during (or at the end of) animations.
If you prefer, you can also use events to transmit animation status from inside your animator controller using state machine behaviours.
You can use a variable playeranimationfinised and use an IEnumerator with WaitUntil like this
using System;
using UnityEngine;
public IEnumerator gameover()
{
//function to check animation finished
Func<bool> animationfinished = () => playeranimationover;
//wait until playeranimationover is true
yield return new WaitUntil(animationfinished);
//show gameoverscreen
}

Unity3D Text not changing after being set in Start()

I have a Canvas (World Space Render mode) with a Text and a Button component displayed in a tridimensional space (it's a VR app). The canvas instantiated at runtime using a prefab.
I get a reference to the Text object using:
_codeTextLabel = canvasPrefab.transform.Find("CodeTextLabel").gameObject.GetComponent<Text>();
I want to update the text at run-time using:
void Update()
{
_codeTextLabel.text = _codeText;
}
where _codeText is just a variable I update based on specific events.
The problem is that the Text gets updated only the first time, but if I try to change the variable nothing happens. I have tried several combinations and also the method _codeTextLabel.SetAllDirty() but it doesn't work.
The only way to update the text is to re-instantiate the prefab.
Are you instantiating your prefab before setting the values. If you are storing the _codeTextLabel reference before instantiating then your reference will point to the prefab not the runtime object. I can't see the rest of your code, so I can't say for sure. (I would have asked as a comment, but as I'm new I don't have the reputation to do so)
edit: I did a test to try and recreate your problem. I made the following script and it appears to work as expected. CanvasPrefab is a worldspace canvas with a UnityEngine.UI.Text component attached. (The script is attached on an empty game object in the scene btw)
public class ChangeText : MonoBehaviour
{
public GameObject CanvasPrefab;
private GameObject runtimeCanvas;
public string runtimeText = "something";
private Text textRef;
// Start is called before the first frame update
void Start()
{
runtimeCanvas = GameObject.Instantiate(CanvasPrefab);
textRef = runtimeCanvas.GetComponentInChildren<Text>();
}
// Update is called once per frame
void Update()
{
textRef.text = runtimeText;
}
}
as long as you did something wrong, It works absolutely so I guess there are several cases
Failed to do "_codeTextLabel = canvasPrefab.transform.Find("CodeTextLabel").gameObject.GetComponent();"
'_codeTextLabel' lost reference from 'GameObject.
Doesn't change runtimeText' change at all
Subscription of events failed I mean, your updating scripts doesn't get proper event to update that text.
Without codes, this is only thing I can guess for yours so please check above I hope there is case among above.

gameObject.name is returning the script name, not the gameobject name

I have a script, LevelCube, which is attached to a gameobject in my scene. When the object is clicked, it calls a function in this script called PickCube()
Right now, I'm just trying to get the position of this gameobject in my scene.
Here is my function:
public void PickCube ()
{
Debug.Log (gameObject.name);
}
Curiously, the output of this log just says "LevelCube", the name of the script. I thought gameObject referenced the GameObject the script is attached to. What's going on here?
If it's any use, here is a pick of the editor. You can see InvertedSphere is highlighted. This is the gameobject I'm trying to get the position of.
Thanks to #Draco18 I realized I was supplying a different object which also has the LevelCube script to the onclick method in my event trigger. So it was calling my function for that object rather than my InvertedSphere.
Try gameObject.transform.name.
What you see in hierarchy is the name of the transform. If you use gameObject.name, it casts it to Object.name and you get the name of your current object.