- Home /
How to open the door when I need
I have a door and buttons on the both sides of the door, which open it.
When I press Button1, door opens. When I press it again, door closed. But if I will press Button1 (door opens), then walk into the room and press Button2, the door will opens again, but this time I need to close it.
I open/close using animation. Can't understand, what is wrong
public Animation button1;
public Animation button2;
public Animation gate;
public AudioSource myAudio;
private bool isDoorClosed;
private bool isAimationReadyToPlay = true;
private Collider thisCollider;
public void Start()
{
thisCollider = GetComponent<Collider>();
}
void Update()
{
if (Input.GetButton("Fire1"))
if (DoPlayerLookAtButton() && isAimationReadyToPlay)
OpenCloseDoor();
}
bool DoPlayerLookAtButton()
{
RaycastHit _hit;
Ray _ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
bool isHit = Physics.Raycast(_ray, out _hit, 1.5f);
if (isHit && _hit.collider == thisCollider) return true;
else return false;
}
void OpenCloseDoor()
{
myAudio.Play();
StartCoroutine("DelayBetweenAnimations");
if (!isDoorClosed) // Play animation with normal speed
{
button1["pressDoorButton"].speed = 1.0f;
button1.Play();
button2["pressDoorButton"].speed = 1.0f;
button2.Play();
gate["openDoor"].speed = 1.0f;
gate.Play();
}
if (isDoorClosed) // Play animation with revert speed
{
button1["pressDoorButton"].speed = -1.0f;
button1["pressDoorButton"].time = button1["pressDoorButton"].length;
button1.Play();
button2["pressDoorButton"].speed = -1.0f;
button2["pressDoorButton"].time = button2["pressDoorButton"].length;
button2.Play();
gate["openDoor"].speed = -1.0f;
gate["openDoor"].time = gate["openDoor"].length;
gate.Play();
}
isDoorClosed = !isDoorClosed;
}
IEnumerator DelayBetweenAnimations()
{
isAimationReadyToPlay = false;
yield return new WaitForSeconds(0.5f);
isAimationReadyToPlay = true;
}
Answer by BigHandInSky · Feb 04, 2016 at 05:13 PM
It is most likely because you haven't defined isDoorClosed in your variable declaration/Start(), and also because you aren't forcing the door to start from 0.0f time - unless specified with a "bool = " all bools are defined as false, which I think may be leading to your script triggering the wrong way around, so either use:
private bool isDoorClosed = true;
or use:
public void Start()
{
thisCollider = GetComponent<Collider>();
IsDoorClosed = true;
}
Alongside this in OpenCloseDoor():
gate["openDoor"].speed = 1.0f;
gate["openDoor"].time = 0.0f;
gate.Play();
That may be the fix for it.
Time should be zero wen I play it in forward direction (open door). But when I close door, time must be equals to the length of animation and speed = -1. And I should call variable isDoorOpen
, but with name isDoorClosed
it works fine.
The problem is when I open door, variable isDoorClosed
change it's value, but only for Button1 because of it: if (isHit && _hit.collider == thisCollider)
.So for Button2 door is still closed and for Button1 it is opened. I don't know, how to change it for both buttons
I think I see the problem - you have the script on both buttons, but when you update one, the other is still in the starting state (I was reading it as a general script on the door itself), what you can do is one of the following:
Have a reference to another DoorScript, when the door is opened update the other script:
public DoorScript OtherDoorButton;
...
public void UpdateDoorState(bool newState)
{
isDoorClosed = newState;
}
...
isDoorClosed = !isDoorClosed;
OtherDoorScript.UpdateDoorState(isDoorClosed);
Or, what I would recommend, is have the script be just one on the door itself, rather than a script per button. Then have a collider variable for both buttons, keeping your detection but checking whether the ray has hit either button's collider then update.