为什么在运行游戏时将刚体添加到门并且在打开的门上自动启用了运动学功能?

时间:2019-02-06 07:34:38

标签: c# unity3d

这个想法是在某些门上添加一个刚体,并使用Is Kinematic,这样当npc /敌人走过门时,它们就会打开/关闭。

但是当我在运行游戏时,门会自动打开而不会触发它。 也许我没有将刚体添加到门中正确的物体/孩子的正确位置?

我所拥有的几扇门的屏幕截图:

Door

每个碰撞(1)到碰撞(11)都连接了一个Box Collider。在每个触发器上,都未选中“触发器”!

Horizo​​ntal_Doors_Kit已附加了Box Collider,并启用了“触发”功能!并附加了脚本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已附加了网格渲染器。

Door_Left和Door_Right具有网格渲染器,音频源,脚本和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();
    }
}

当我将刚体添加到父级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 :(得分:1)

我认为您的问题在于门的碰撞检测。门上的刚体本身不起作用。

首先:您的OnTriggerEnter函数缺少正确的模式,因为它缺少Collider collidername参数。

private void OnTriggerEnter(Collider other)
{
}

您可以随意调用对撞机(IntelliSense默认为other),但是您的方法必须具有这样的参数才能被Unity识别为OnTriggerEnter函数。

第二:您永远不会检查触发对撞机的对象是否确实是您要打开门的对象。

尝试使用诸如Player之类的标记为播放器和NPC标记。

然后,您检查碰撞对象是否附加了此标签并且仅,然后您打开门。

类似这样的东西:

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组件,所以您对此并不完全错误。