For my recent project i need a Door to open if the user is in front of it and has pressed "e".
This is the Code for the Button:
using UnityEngine;
public class Button : MonoBehaviour
{
public Animator Door; // In the editor, give a reference to your door. It must have an Animator script for this to work
void OnTriggerEnter(Collider c)
{
if (c.gameObject.tag == "Player")
{
//Text = "E to interact!"
if (Input.GetKeyDown("e"))
{
print("´Test");
GetComponent<Animator>().SetTrigger("OnPress"); // The button's animator goes to "pressed" state
Door.SetTrigger("Open"); // The door's animator goes to "open" state
}
}
}
}
The Animator looks like this:
The Transition from Idle to Open:
The Button has the Door attached to it:
So i got two issues here, the first is - With the above Code nothing happens if i press E. No Error, No Action, whatsoever.
If i delete the Input.GetKeyDown("e") and make the Button-Mesh to a Trigger and run in it, it says
MissingComponentException: There is no 'Animator' attached to the
"Button" game object, but a script is trying to access it. You
probably need to add a Animator to the game object "Button". Or your
script needs to check if the component is attached before using it.
If you need more Information, just let me know. Thanks!
Ok, your approach to the interaction is wrong. First of all, On trigger enter will work only once. That is when you enter the trigger. So it won't take the Keypress event. You will have to move the code in OnTriggerStay(Collider col) where it will constantly be called. There if it takes any key event, then it will fire up. That will solve your problem 1.
As for the second problem, I'm pretty sure you copy paste this code from somewhere else. Only the canvas UI Button has animator state. Your button is Normal mesh and not the UI one. So setting the state button in that code won't work, ie
GetComponent<Animator>().SetTrigger("OnPress"); // The button's animator goes to "pressed" state
Unless you are using the Canvas Button that script does not work. And the error description already mentioned the error you Button Mesh Does not have an animator. Try commenting the line and see how it works.
Edit:
I went through your transition your code should be
door.GetComponent<Animator>().SetTrigger("OnPress");
and not
GetComponent<Animator>().SetTrigger("OnPress");
As it is trying to call the OnPress state of door animator. If any trouble comes comment below with more info. Sorry did not notice this first.
Related
I am trying to start an animation by pressing a key on my keyboard.
For this I am using the following code:
[HideInInspector] public Animation animation;
private void Start()
{
animation = GetComponent<Animation>();
}
private void Update()
{
if (Input.GetKeyDown("1"))
{
animation.Play("AnimationName");
}
}
This gives me the following error:
The animation state AnimationName could not be played because it
couldn't be found!
Although, the animation DOES start, but how can I clear this error?
I think the only possible explaination is that your animation clip is not marked as Legacy.
https://www.unity3dtips.com/zh/the-animation-state-could-not-be-played-because-it-couldnt-be-found/
EDIT with step by step here:
Animations must be marked as legacy to be used with the animation component.
In the project window select the animation clips you’re trying to play.
Set the inspector to debug mode which exposes hidden variables, in this case it’ll make the “Legacy” checkbox appear.Unity Inspector Debug Mode
Tick the “Legacy” checkbox and change the inspector back to normal mode.
Unity Inspector Animation Clip Legacy Checkbox
But there is one thing you should know: you should avoid, if possible, the old legacy way to play animation.
Learn how to use an Animator component. Just create an animator, assign your animation clip, decide a boolean for start the animation in the animator component and set it to true in your code (for basic use).
Sure there is some things to do beside code but it will be easier to control your animation, bleand different animations and change them to your needs (it's for example much easier to loop or stop the animation at some point).
It would be also easier to understand when it start and when is playing.
Another thing to check is the legacy 'Animation' component on your gameObject that is supposed to perform the animation. In my case things were marked as legacy for the animation on the imported animation but somehow when adjusting settings on my import it dropped the animation it was complaining about from the actual 'Animation' component so once I added it things worked as expected
Inspector in Debug mode showed my animation marked as 'Legacy' true
My Animation component showed the missing animation
I know this is a really simple question but I can't figure out how to archive this:
I have a UI button in my scene and I want Vuforia to instantiate one AR Model ONLY when I press a button.
Following the tutorial on the net I was able to instantiate a model on the screen when I touch it but I need to know how to set up Vuforia for archive the same result only when I press a button.
I have to disable the "Anchor Input Listener Behaviour"?
And then?
I want to call for the PositionContentAtPlaneAnchor but I can't figure out how to call it in the right way in the OnClick field of the button. I need to make a custom script for this?
Thanks for any answer.
Ok, sorry for the delay.
I deduce that you are working with the ground plane, if you have the Ground Plane Stage and the Plane Finder in the scene and works, we're at a good point.
Now, you must only add a button to the scene and into the script add something like this:
public PlaneFinderBehaviour plane;
void Start()
{
...
buttonOnTheScene.onClick.AddListener(TaskOnClick);
...
}
void TaskOnClick()
{
Vector2 aPosition = new Vector2(0,0);
...
plane.PerformHitTest(aPosition);
}
What does it mean?
First of all, you must move the Plane Finder from Hierarchy to the script variable, so we have a reference to the plane into the script.
Then when you click (or tap) on the button you simulate the click (or tap) on the display with the PerformHitTest.
If you're wondering why my question in the comment, it's because the Plane Finder Behaviour Script has two modes type: Interactive and Automatic. The Interactive intercept the tap on the display and shows the object (on the ground plane) in the exact position of the tap, the automatic shows the object in the center of the plane.
So if you want the object in an exact position you can pass a Vector2 position in the PerformHitTest and if you want to show an object programmatically or do something when it shows the object you can call a custom method OnInteractiveHitTest.
That's all.
I am trying to create a Minesweeper + clicker/idle game for practice. For now, I can't get the clicking to work properly. I spawned in all objects through code meaning they are all the same prefabs but at different locations. When I click them the code activates for all of them and all of the tiles change to being open. I am not sure if I'm using the wrong click function here, as I know there is also an OnMouseDown() function instead of Input.GetMouseButtonDown(0) but the only one where the code activates is in the second one.
public class TileClick : MonoBehaviour {
public GameObject openTile;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown(0)) {
Instantiate(openTile, transform.position, Quaternion.identity);
Object.Destroy(this.gameObject);
}
}
}
That's my clicking detection. While it does detect clicks, as I said before, it detects them for ALL tiles and activates them all. I only want it to activate on one of them. I've seen RayCasting stuff but I really need more explanation on how that thing works (if that's the solution).
If the TileClick script component is attached to your prefab, then for every tile you instantiate, you have a corresponding TileClick component attached.
When you click, the input is detected by all of these blocks simultaneously, and each of them calls Instantiate but the transform.position is the one corresponding to the tile that makes the call. This is why it seems like all the tiles open up simultaneously, because you are, in fact, instantiating an "open" tile on each of them every time you click.
You should keep all your user input code in a separate MonoBehaviour, and attach that to a single empty GameObject in your scene. For detecting the hit, you should attach a 2DCollider component to your tile prefab (you can decide the type according to the shape of your tiles), and then just use a simple RayCast in your user input code to instantiate an "open" tile at the position where the hit occurs:
void Update () {
if (Input.GetMouseButtonDown(0)) {
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition),
Vector2.zero);
if(hit.collider != null)
{
Instantiate(openTile,
hit.collider.gameObject.transform.position,
Quaternion.identity);
}
}
I highly recommend understanding how RayCast works since it is a very useful tool. Here's a good place to start: https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html
So I'm making a simple "puzzle" using lights. Simply, there are 3 buttons with lights on them (red, blue, green). Each button has it's own trigger volume but when I go to play, nothing prints that I even enter, stay, or leave the trigger. I've never used Collider Variables before so I feel like I'm doing something wrong (obviously or it would be working!). But then I just did "Collider entity" in the OnTriggerStay/Enter/Exit Method and it still didn't print to the console that my player was entering. Why are my Triggers not working?
Click here for the code I'm trying
Click here to see how I have it in the Unity Scene
Triggers only respond to other colliders that have rigid bodies on them.
Try adding a Ridgidbody component to your player and set it to kinematic.
OnTriggerEnter/Stay/Exit works when the Object has a Collider Component and BluePuzzle2 doesn't have that.
Also OnTrigger function gets a Collider as parameter. Check the reference page
So in order to make that work put a script on every light and on that script copy this function
void OnTriggerEnter(Collider col) {
if (col.CompareTag("Player")) {
print("Entered the trigger");
}
}
Hope it helps.
Tried to find this kind of problem around the net but failed so...
Here's the thing - I have a prefab gameobject that is to represent a unit, portrait more specifically. It has several scripts attached and an Animation component with two animations: Static and Selected.
The prefab is instantiated, moved freely and, after placing, it can be clicked to select it, which should, aside from executing a bit of code, start the Selected animation.
Using this code:
void OnMouseDown(){
//
//Some inside stuff
//
if (this.GetComponent<UnitHandling> ().thisUnit.Selected)
this.animation.Play("Selected");
if(this.animation.IsPlaying ("Selected"))
Debug.Log("Animation of selection is playing");
}
I checked that the animation seems to be playing (at least the Debug message is showing) but I see no animation... What am I doing wrong?
Try making an animation state using mechanim, and play it using this:
GetComponent<Animator>().CrossFade("Selected", 0);
https://docs.unity3d.com/Documentation/ScriptReference/Animator.CrossFade.html
https://docs.unity3d.com/Documentation/Manual/MecanimAnimationSystem.html