- Home /
Player to Door Collision and Animation
I could really use some help with this. I'm new to Unity scripting have previously been using just Visual Studio C# and I'm finding it difficult to get started.
Basically what I'm trying to do is have a door slide open when the player approaches it.
Now I've got my Capsule which is tagged as Player and I've got a Door which is tagged as MainDoor. Each of them has a collision box. The door has a Box Collider with Is Trigger ticked.
I've created my animation and called it DoorA and attached it to the Door object.
Now I've been trying to get the script working, at first I had it attached to the Door, then I had it attached to the player. What is confusing me is how to reference another objects collider and what it means when I'm calling a collider other?
Here is my code below:
using UnityEngine;
using System.Collections;
public class MainDoor : MonoBehaviour {
// Use this for initialization
void Start () {
}
void OnTriggerEnter(Collider other) {
animation.Play ("DoorA");
}
// Update is called once per frame
void Update () {
}
}
Now at present it is attached to the Door. In pseudo code this is what I think I should be doing
When Doors trigger is hit by Player Collider play door animation.
But I'm unsure how to do it! Help would be appreciate, I'm a novice!
When I put a tag on the OnTriggerExit function I can see that it happens right away as soon as the game starts. Which suggest that the Player is leaving the trigger area on game launch. That doesn't make sense to me.
This script by the way is attached to the door not the player object.
Answer by Cherno · Apr 26, 2014 at 02:09 AM
Here is my door script, fairly comprehensive but you can just pick the parts you really need from it. You might have to set your door animation import setting so that the opening and closing animations are Clamp Forever, so CrossFade works (if the player opens it while it is closing). Also consider editing the physics layer interaction in Project Settings -> Physics so the door collider only interacts with player characters, or anything else that should block the door.
using UnityEngine;
using System.Collections;
public class Door : MonoBehaviour
{
private int state;//0 = closed/idle, 1 = opening, 2 = closing, 3 = open
private float openTimer;
private float closeTimer;
private float autoCloseTimer;
public bool blocked;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(state == 3) {
if(blocked == false) {
autoCloseTimer += Time.deltaTime;
}
else {
autoCloseTimer = 0.0f;
}
}
else {
autoCloseTimer = 0.0f;
}
if(autoCloseTimer >= 5.0f && blocked == false) {
ActivateDoor();
}
if(state == 1) {
openTimer += Time.deltaTime;
}
if(openTimer >= 1.5f) {
state = 3;
ResetTimer();
}
if(state == 2) {
closeTimer += Time.deltaTime;
if(blocked == true) {
animation.CrossFade("door1_open", 1.0f, PlayMode.StopAll);
state = 1;
ResetTimer();
}
}
if(closeTimer >= 1.5f) {
state = 0;
ResetTimer();
}
}
void OnTriggerStay() {
blocked = true;
ActivateDoor();
}
void OnTriggerExit() {
blocked = false;
}
public void ActivateDoor() {
if(state == 0) {
animation.Play("door1_open", PlayMode.StopAll);
state = 1;
ResetTimer();
return;
}
if(state == 1) {
return;
}
if(state == 2) {
animation.CrossFade("door1_open", 1.0f, PlayMode.StopAll);
state = 1;
ResetTimer();
return;
}
if(state == 3) {
animation.Play("door1_close", PlayMode.StopAll);
state = 2;
ResetTimer();
return;
}
}
void ResetTimer() {
openTimer = 0.0f;
closeTimer = 0.0f;
}
}
Answer by koray1396 · Apr 24, 2014 at 07:03 PM
I think you need;
if(other.gameObject.tag == "Player"){
animation.Play ("DoorA");
}
In the below line, "other" is the Collider of the triggering object.
void OnTriggerEnter(Collider other) {
So other.gameObject refers to the triggering gameObject. You could also be doing
other.rigidbody.velocity = someSpeedVector;
therefore you would be reaching the rigidbody of the triggering object. Check the link below, you can see what variables you can use with Collider component.
https://docs.unity3d.com/Documentation/ScriptReference/Collider.html
Also as a note, your player should have a rigidbody in order to trigger occur. You can see from the below link, when collisions are detected.
http://docs.unity3d.com/Documentation/Components/class-MeshCollider.html
Thank you, I managed to set that up. However now when I walk into the Trigger area the animation plays continiously. $$anonymous$$y code now looks like this:
using UnityEngine;
using System.Collections;
public class $$anonymous$$ainDoor : $$anonymous$$onoBehaviour {
private int count;
// Use this for initialization
void Start () {
}
void OnTriggerEnter(Collider other) {
count++;
if (other.gameObject.tag == "Player") {
animation.Play ("DoorA");
}
}
void OnTriggerExit(Collider other) {
}
// Update is called once per frame
void Update () {
}
}
I have the "play automatically" button unchecked and I have set the animations Wrap $$anonymous$$ode to "Once". I'm not sure if this is because it is doing my animation code constantly as the player is stood inside the trigger area or because it is half in half out of the trigger area. I thought it would simply run that function once and the player would have to completely exit the area and re-enter for it to trigger again.
no, it should run once. I'm not sure why this is not working. While I think this should work as it is now, you can fix this, by defining another variable. It might be related to how you set up the colliders.
if (other.gameObject.tag == "Player" && !isOpen) {
animation.Play ("DoorA");
isOpen = true;
}
I have managed to refine this code somewhat but with a new error!
So basically what I've done now is to attached an Animator Controller to the Door and in it I have two animations $$anonymous$$DClose and $$anonymous$$DOpen with transistions and a bool value attached to control the doors animation.
The problem is that the door opens when the player approaches as expect. However it does not shut after I leave the box collider.
Any thoughts?
using UnityEngine;
using System.Collections;
public class $$anonymous$$ainDoor : $$anonymous$$onoBehaviour {
private int count;
// Use this for initialization
void Start () {
anim = GetComponent<Animator> ();
}
void OnTriggerEnter(Collider other) {
if (other.gameObject.tag == "Player") {
count++;
}
}
void OnTriggerExit(Collider other) {
if (other.gameObject.tag == "Player") {
count = $$anonymous$$athf.$$anonymous$$ax (0, count-1);
}
}
// Update is called once per frame
void Update () {
anim.SetBool ("Open", count > 0);
}
}
well, I can not see any reason why you are handling this like that. OnTriggerEnter you can use
anim.SetBool ("Open", true);
OnTriggerExit;
anim.SetBool ("Open", false);
you would not need to run this on every update.
Anyway, still in your script, if count goes up to 2 by a chance, then the door would not close. Put the following right under count++
Debug.Log(count);
and under this also. count = $$anonymous$$athf.$$anonymous$$ax (0, count-1);
you can check and see what's happening actually.
Thank you for the help with this. It's such a simple task but it just doesn't seem to want to work.
I stripped my code back and use inputted the true and false you suggested within on on enter and on exit. However now when I run the game the door continuously opens and shuts, it's very strange.
Answer by William_Goodspeed · Apr 28, 2014 at 05:50 PM
The above information was very helpful. As it turns out the problem with my code was that I had included a player controller which uses crouch. That crouch was kicking in when I approached the ceiling near the doors entrance and for whatever reason this was affective the collision and animation. I removed the crouch feature and it now works :)
Your answer
Follow this Question
Related Questions
Collider on Bone changes Bone Origin/Pivot 1 Answer
play a door animation with collider 1 Answer
How to stop an animation on collision 0 Answers
Within sphere collider to click on door that opens 0 Answers
Collision with animations 0 Answers