0
votes

The idea is to add a Rigidbody to some doors and use Is Kinematic so when a npc/enemy will walk through the doors they will open/close.

But when I'm running the game the doors open automatic without anything triggering it. Maybe I didn't add the Rigidbody to the right place in the door the right object/child ?

A screenshot of a door one of few I have:

Door

Each Collision (1) to Collision(11) have attached a Box Collider. On each one the Is Trigger is unchecked !

The Horizontal_Doors_Kit have attached a Box Collider and the Is Trigger is check enabled ! And also attached to it a script Hori Door Manager:

using UnityEngine;
using System.Collections;

public class HoriDoorManager : MonoBehaviour
{
    public DoorHori door1;
    public DoorHori door2;
    public static bool doorLockState;

    void OnTriggerEnter()
    {
        if (doorLockState == false)
        {
            if (door1 != null)
            {
                door1.OpenDoor();
            }

            if (door2 != null)
            {
                door2.OpenDoor();
            }
        }
    }
}

Wall_Door_Long_01 have attached a Mesh Renderer.

Door_Left and Door_Right have a Mesh Renderer , Audio Source , a script and a Box Collider where Is Trigger unchecked !

The script is attached to door left and to door right:

using UnityEngine;
using System.Collections;

public class DoorHori : MonoBehaviour {

    public float translateValue;
    public float easeTime;
    public OTween.EaseType ease;
    public float waitTime;

    private Vector3 StartlocalPos;
    private Vector3 endlocalPos;

    private void Start(){
        StartlocalPos = transform.localPosition;    
        gameObject.isStatic = false;
    }

    public void OpenDoor(){
        OTween.ValueTo( gameObject,ease,0.0f,-translateValue,easeTime,0.0f,"StartOpen","UpdateOpenDoor","EndOpen");
        GetComponent<AudioSource>().Play();
    }

    private void UpdateOpenDoor(float f){       
        Vector3 pos = transform.TransformDirection( new Vector3( 1,0,0));
        transform.localPosition = StartlocalPos + pos*f;

    }

    private void UpdateCloseDoor(float f){      
        Vector3 pos = transform.TransformDirection( new Vector3( -f,0,0)) ;

        transform.localPosition = endlocalPos-pos;

    }

    private void EndOpen(){
        endlocalPos = transform.localPosition ;
        StartCoroutine( WaitToClose());
    }

    private IEnumerator WaitToClose(){

        yield return new WaitForSeconds(waitTime);
        OTween.ValueTo( gameObject,ease,0.0f,translateValue,easeTime,0.0f,"StartClose","UpdateCloseDoor","EndClose");
        GetComponent<AudioSource>().Play();
    }
}

When I added the Rigidbody it was to the parent Wall_Door_Long_01 also added to it a Box Collider.

Then when running the game the door/s opened automatic without anything to trigger it like a npc enemy character.

The doors are working fine and when I'm moving my FPSController through the doors they open and close fine. My problem is when a npc/character that move automatic when the game start through the doors I could not find to make the character walking fine with a Rigidbody so I decided to add a Rigidbody to the doors. But now the doors open automatic when running the game.

This script I'm using to check if the doors are locked or unlocked using the public static doorLockState variable:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DoorsLockManager : MonoBehaviour
{
    public bool locked;
    public bool lockStateRealTime = false;
    public Renderer rend;

    private Shader unlitcolor;
    private GameObject[] doorPlanes;

    private void Start()
    {
        doorPlanes = GameObject.FindGameObjectsWithTag("DoorPlane");
        ChangeColors(new Color32(255, 0, 0, 255), new Color32(0, 255, 0, 255));
    }

    private void ChangeMaterialSettings()
    {
        unlitcolor = Shader.Find("Unlit/Color");
        rend.material.shader = unlitcolor;
        rend.material.SetFloat("_Metallic", 1);
    }

    private void ChangeColors(Color32 lockedColor, Color32 unlockedColor)
    {
        for (int i = 0; i < doorPlanes.Length; i++)
        {
            rend = doorPlanes[i].GetComponent<Renderer>();
            ChangeMaterialSettings();
            if (locked)
            {
                HoriDoorManager.doorLockState = true;
                rend.material.color = lockedColor;
            }
            else
            {
                HoriDoorManager.doorLockState = false;
                rend.material.color = unlockedColor;
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (lockStateRealTime)
        {
            ChangeColors(new Color32(255, 0, 0, 255), new Color32(0, 255, 0, 255));
            lockStateRealTime = false;
        }
    }
}
1
I provided a answer below but just out of curiosity: why is doorLockStatestatic? - TehMightyPotato
@TehMightyPotato The reason it's static is that I'm using this in other script/s to check if the door/s in a lock state or unlocked and changing lighs on door of planes I added to them this way I know when it's green unlocked and red locked. I added the script I'm using the doorLockState to my question so you can see how I'm using it. Is that wrong make it public static ? - Dubi Duboni
The static keyword means that this variable is not associated with your objects but rather with the class itself. Think about it like a variable you can access without the need of creating a object of that type. But that's the problem. There is only one doorLockState and it belongs to the class itself, not a specific door. If you change this variable it changes globally for every door. - TehMightyPotato
@TehMightyPotato Then how would I check if the door/s are locked/unclocked in other scripts ? You right about the static if I ever sometime will change this variable from other script it will effect the whole doors. - Dubi Duboni
You could add a reference to your script like public HoriDoorManager doorManagerand access its variable like that: doorManager.doorLockState. Either set it in the inspector or via GetComponent<HoriDoorManager>() - TehMightyPotato

1 Answers

1
votes

I think your problem is in your collision detection for the door. A rigidbody on the door itself should have no effect.

First: Your OnTriggerEnterfunction does not have the correct pattern to work since it is missing the Collider collidername parameter.

private void OnTriggerEnter(Collider other)
{
}

You can call you collider whatever you want (IntelliSense defaults to other) but your method has to have a parameter like this to be recognized as a OnTriggerEnterfunction by Unity.

Second: You never check if the object triggering your collider is actually the object you want to open the door.

Try tagging your player and NPCs with some kind of tag like Playeror something like that.

Then you check if the colliding object has this tag attatched to it and only then you open the door.

Something like this:

private void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Player"))
    {
        //do stuff
    }
    if(other.CompareTag("NPC"))
    {
        //do other stuff
    }
}

Or if there is only one action for every tag:

private void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Player") || other.CompareTag("NPC"))
    {
        //do stuff
    }
}

Note that for OnTriggerEnterto detect a collision one or more objects colliding need a RigidBodycomponent attached to them, so you are not entirely wrong with that.