为啥将刚体添加到门并且在运行游戏时自动打开门时是不是启用了运动学?
Posted
技术标签:
【中文标题】为啥将刚体添加到门并且在运行游戏时自动打开门时是不是启用了运动学?【英文标题】:Why when adding a Rigidbody to a door and Is Kinematic is enabled true on the door open automatic when running the game?为什么将刚体添加到门并且在运行游戏时自动打开门时是否启用了运动学? 【发布时间】:2019-02-06 07:34:37 【问题描述】:这个想法是在一些门上添加一个刚体并使用 Is Kinematic 所以当一个 npc/敌人穿过门时,他们会打开/关闭。
但是当我运行游戏时,门会自动打开而没有任何触发。 也许我没有将刚体添加到正确的对象/子门的正确位置?
我拥有的少数门之一的屏幕截图:
每个 Collision (1) 到 Collision(11) 都附加了一个 Box Collider。在每一个上,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 附加了一个网格渲染器。
Door_Left 和 Door_Right 有一个 Mesh Renderer 、 Audio Source 、一个脚本和一个 Box Collider ,其中 Trigger 未选中!
脚本附在左门和右门:
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/角色时,我找不到让角色与刚体一起正常行走,所以我决定在门上添加一个刚体。但是现在运行游戏时门会自动打开。
我用来检查门是否使用公共静态 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;
【问题讨论】:
我在下面提供了一个答案,但只是出于好奇:为什么是doorLockState
static?
@TehMightyPotato 它是静态的原因是我在其他脚本中使用它来检查门是否处于锁定状态或解锁并改变我添加到它们的飞机门上的灯这样我就知道它何时是绿色解锁和红色锁定。我将我正在使用 doorLockState 的脚本添加到我的问题中,这样你就可以看到我是如何使用它的。将其公开为静态是错误的吗?
static
关键字意味着此变量与您的对象无关,而是与类本身相关联。把它想象成一个无需创建该类型对象即可访问的变量。但这就是问题所在。只有一个 doorLockState
,它属于类本身,而不是特定的门。如果您更改此变量,它会为每扇门全局更改。
@TehMightyPotato 那么我将如何检查门是否在其他脚本中被锁定/解锁?如果我有时会从其他脚本更改此变量,那么您对静态的看法是正确的,它将影响整个门。
你可以像public HoriDoorManager doorManager
一样添加对你的脚本的引用并像这样访问它的变量:doorManager.doorLockState
。在检查器中设置它或通过GetComponent<HoriDoorManager>()
【参考方案1】:
我认为您的问题在于门的碰撞检测。门本身上的刚体应该没有效果。
首先:您的OnTriggerEnter
函数没有正确的工作模式,因为它缺少Collider collidername
参数。
private void OnTriggerEnter(Collider other)
您可以随意调用碰撞器(IntelliSense 默认为 other
),但您的方法必须具有这样的参数才能被 Unity 识别为 OnTriggerEnter
function。
第二:你永远不会检查触发你的对撞机的物体是否真的是你想要打开门的物体。
尝试使用 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
组件,所以你并没有完全错。
【讨论】:
好的,这可能有效。和工作。但是我将不得不将我的播放器标记为我的 FPSController,例如,也将其标记为 NPC。但是我控制他动作的玩家已经有一个刚体,当我将他移近一扇门时,门会触发并且可以很好地打开和关闭。其次,如果我的玩家控制器有一个刚体并且它在门上工作正常,那么也许我不需要每个门上的刚体?我有 20 扇门。 问题从 NPC 角色走进门开始。 NPC 是我从 Mixamo.com 下载的角色,也是动画。首先我尝试为 NPC 角色添加一个盒子对撞机和一个刚体,但它确实出现了问题。主要问题是当 NPC 角色有刚体时,我必须检查并启用 Is Kinematic 如果没有,角色漂浮在空中并失去旋转。但是如果启用 Is Kinematic,它会很好地穿过门,但是当没有门并且他继续走路时,他会有点口吃/颤抖。口吃/颤抖是问题所在。 我试图在这里描述问题:***.com/questions/54503799/… 和这里:answers.unity.com/questions/1598724/… 我的第一个想法是为 NPC 角色而不是所有的门添加刚体。但是当他使用 Is Kinematic 走路时的这种口吃/颤抖让我想到在每扇门上添加一个刚体。我认为将一个刚体添加到角色 NPC 然后添加到每扇门更符合逻辑。 来自 Mixamo.com 的 NPC 角色我正在使用它和 HumanoidWalk 动画来移动它。而且我必须更改检查器中动画选项卡上的一些属性以使其正常工作。但是在将刚体添加到 NPC 后,他走路时会有些口吃/颤抖。以上是关于为啥将刚体添加到门并且在运行游戏时自动打开门时是不是启用了运动学?的主要内容,如果未能解决你的问题,请参考以下文章