Почему при добавлении Rigidbody к двери и включается ли Kinematic в положение true при открытии двери автоматически при запуске игры? - PullRequest
0 голосов
/ 06 февраля 2019

Идея состоит в том, чтобы добавить Rigidbody к некоторым дверям и использовать Is Kinematic, чтобы, когда NPC / враг проходил через двери, они открывались / закрывались.

Но когда я запускаю игру, двериоткрывать автоматически, ничего не вызывая.Может быть, я не добавил Rigidbody в нужное место в двери нужного объекта / ребенка?

Скриншот одной из немногих дверей, которые у меня есть:

Door

Каждое Столкновение (1) к Столкновению (11) прикрепило Коллайдер Коробки.На каждом из них отключен Is Is Trigger!

К Horizontal_Doors_Kit прикреплен Box Collider и включена проверка Is Trigger!А также прикрепленный к нему скрипт 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 прикрепили Mesh Renderer.

Door_Left и Door_Right имеют Mesh Renderer, Audio Source, скрипт и Box Colliderгде отключен триггер!

Сценарий прикреплен к левой двери и правой двери:

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();
    }
}

Когда я добавил Rigidbody, он был добавлен к родителю. Wall_Door_Long_01 также добавил к нему Box Collider..

Затем при запуске игры дверь / двери открывались автоматически без чего-либо, что вызывало бы их, как вражеский персонаж NPC.

Двери работают нормально, и когда я перемещаю свой FPSController через двери, они прекрасно открываются и закрываются.Моя проблема в том, что когда NPC / персонаж, которые двигаются автоматически, когда игра начинается через двери, я не мог найти, чтобы персонаж хорошо шел с Rigidbody, поэтому я решил добавить Rigidbody к дверям.Но теперь при открытии игры двери открываются автоматически.

Этот сценарий я использую, чтобы проверить, заблокированы или разблокированы двери, с помощью общедоступной статической переменной doorLockState:

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 Ответ

0 голосов
/ 06 февраля 2019

Я думаю, ваша проблема в том, что вы обнаружили столкновение двери.Твердое тело на самой двери не должно иметь никакого эффекта.

Во-первых: ваша функция OnTriggerEnter не имеет правильного шаблона для работы, поскольку в ней отсутствует параметр Collider collidername.

private void OnTriggerEnter(Collider other)
{
}

Вы можете называть коллайдер как хотите (IntelliSenseпо умолчанию other), но ваш метод должен иметь такой параметр, чтобы Unity распознавал его как OnTriggerEnter функцию.

Второе: вы никогда не проверяете, является ли объект, запускающий ваш коллайдер, действительно объектом, который выхочу открыть дверь.

Попробуйте пометить своего игрока и неигровых персонажей какими-нибудь тегами вроде Player или что-то в этом роде.

Затем вы проверяете, привязан ли к сталкивающемуся объекту этот тег и только , затем вы открываете дверь.

Примерно так:

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

Или, если для каждого тега есть только одно действие:

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

Обратите внимание, что для OnTriggerEnter для обнаружения коллизии одному или нескольким объектам, сталкивающимся, необходим присоединенный компонент RigidBodyдля них, так что вы не совсем ошибаетесь с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...