4

I have a door, with buttons on the both sides of the door. Each button should open the door.

When I press Button1, door opens, press it again, door closes. But if I press Button1 then press Button2, the door will open again, instead of closing.

enter image description here

I open/close using animation. Can't understand, what is wrong

Fattie
  • 27,874
  • 70
  • 431
  • 719
Amazing User
  • 3,473
  • 10
  • 36
  • 75
  • 1
    Is this script is attached to both buttons gameobjects? – Paweł Marecki Feb 05 '16 at 11:19
  • 1
    `ìsDoorClosed` is a private field, can the second button even access this field? Or is this script attached to both buttons? – Christoph K Feb 05 '16 at 11:28
  • Yes, script attached to the both buttons. Is it wrong? – Amazing User Feb 05 '16 at 11:49
  • 1
    Each gameobject has its own `isDoorClosed`. For test purposes you can make this field `static` and check if it helps. – Paweł Marecki Feb 05 '16 at 11:53
  • 1
    I think, Unity3D creates a new instance for each assignment of scripts. So, for example: The first script got executed but the second script is still not active. When the second script got executed it'll create its own instance, so everything is back to normal. Door is closed, and will be opened again, because it doesn't know about his friend the first script. – Christoph K Feb 05 '16 at 11:54
  • Really, making it static helped, thanks =) – Amazing User Feb 05 '16 at 11:57
  • 1
    Great :) But, keep in mind one thing. When you create more doors like that the `static` field will shared between all of them :) – Paweł Marecki Feb 05 '16 at 12:04
  • It is incredibly wrong to suggest using a static here guys. @dima do not do that – Fattie Feb 05 '16 at 12:31
  • I can agree, its not a good sollution. But its really simple and fast way to check what causes the problem. – Paweł Marecki Feb 05 '16 at 12:39
  • I'm really sorry I can't agree with you on this occasion, Pawel. It is incredibly anti-Unity pattern, don't forget this is on a MonoBehaviour! @dima you need to remove it or it will break at some point – Fattie Feb 05 '16 at 12:41

1 Answers1

4

It's critical that you

do not use static variables

in this case.

You'll be pleased to know the solution is simple. Have a script called AttachToDoor

public void AttachToDoor()
 {
 private bool isOpen;
 public float doorSpeed;
 etc etc
 public void OpenCloseDoor()
   {
   your code to open/close a door
   }
 }

Drag AttachToDoor on to your door. Notice OpenCloseDoor() is marked public.

Next have ANOTHER, SEPARATE script, AttachToButton

public void AttachToButton()
{
public AttachToDoor amazaingDoorScript;
etc etc
void Update()
 {
  if (Input.GetButton("Fire1"))
   if (DoPlayerLookAtButton() && isAnimationReadyToPlay)
    amazaingDoorScript.OpenCloseDoor();
 }
}

Drag an AttachToButton on to any of your "buttons".

Look at the Inspector, and notice the slot "amazaingDoorScript".

Literally drag the door, to that slot, and it will connect the AttachToDoor to the "amazaingDoorScript" variable.

But note ... you can do this to as many buttons as you want.

Any time you make a button, just put an AttachToButton on the button.

You could even have another script which, just as an example, opens and closes the door randomly:

   public AttachToDoor amazaingDoorScript; ...
   Invoke("test",Random.Range(5f,10f)); ...
   private void test()
     {
     // have a ghost mess with the door occasionally
     amazaingDoorScript.OpenCloseDoor();
     Invoke("test",Random.Range(5f,10f));
     }

This is a really basic concept in Unity, and once you can do this you can do anything. Enjoy!


Take the opportunity, to learn how to use UnityEvent.

If you're learning Unity, this is a good opportunity to learn about UnityEvent. Using UnityEvent is really the heart of everyday Unity engineering.

Here is a excellent tutorial: https://stackoverflow.com/a/36249404/294884

On the BUTTON, do this

public void AttachToButton()
{
public UnityEvent buttonClicked;
 void Update()
 {
  if (Input.GetButton("Fire1"))
   if (DoPlayerLookAtButton() && isAimationReadyToPlay)
    {
    Debug.Log("Button pressed!");
    if (buttonClicked!=null) buttonClicked.Invoke();
    }
 }
}

Hit save. Run the game, and notice that when a button is pressed in the game, you will see the Log "Button pressed!".

Now, look in the editor, at your buttons.

Notice that actually in the editor, you have added an amazing drag and drop area at the bottom of your AttachToButton.

Now stop the game, and try this. Look at one of your buttons. Look at the drag and drop area for the event buttonClicked. In fact, drag your door ON TO that ... and select the routine OpenCloseDoor.

Run the game and watch what happens. Voilà! Amazing right?

Community
  • 1
  • 1
Fattie
  • 27,874
  • 70
  • 431
  • 719