一旦我进入触发区域,门就会打开。
如果几秒钟后门打开后我仍留在触发区域内,则门会关上我。但是按照我的逻辑,只要我在触发区域内,门就应该保持打开状态。关门应该只有在离开触发区域时才开始关闭。
另一个问题是,如果我在门的触发区域内外移动得太快。一旦我进入门,当我打开门时,如果我将快速移出触发区域并再次非常快地移回,即使门仍然打开,我也会开始播放打开的门动画。我不确定如何解决这个过快的进/出问题。
我认为逻辑应该很简单。
进入触发区域打开门。
如果我在门完全打开时仍停留在触发区域内,请不要离开门,直到我退出触发区域,然后花几秒钟的时间开始关闭门。
如果门开始关闭,然后我进入触发区域,则即使门正在关闭,也要在门现在的位置再次打开门。
如果我很快就快速进入/退出门触发器区域,请像前两个规则一样处理它。如果门已经完全打开并且已经打开,则不要播放打开的门动画。如果剧本进行了怎么办?
Doors Manager脚本附加到一个空的GameObject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DoorsManager : MonoBehaviour
{
public List<HoriDoorManager> _doors = new List<HoriDoorManager>();
private void Start()
{
var doors = GameObject.FindGameObjectsWithTag("Door");
foreach(var door in doors)
{
_doors.Add(door.GetComponent<HoriDoorManager>());
}
}
public void LockDoor(int doorIndex)
{
_doors[doorIndex].ChangeLockState(true);
}
public void UnlockDoor(int doorIndex)
{
_doors[doorIndex].ChangeLockState(false);
}
}
脚本Hori Door Manager附加在门子级名称Horizontal_Doors_Kit上:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class HoriDoorManager : MonoBehaviour
{
private bool doorLockState;
private List<DoorHori> doors = new List<DoorHori>();
private void Start()
{
if (transform.parent != null)
{
Transform parent = transform.parent;
var children = parent.GetComponentsInChildren<Transform>();
if(children != null)
{
foreach (Transform door in children)
{
if (door.name == "Door_Left" || door.name == "Door_Right")
doors.Add(door.GetComponent<DoorHori>());
}
}
}
}
void OnTriggerEnter()
{
if (doorLockState == false)
{
if (doors != null)
{
for(int i =0; i < doors.Count; i++)
{
doors[i].OpenDoor();
}
}
}
}
public void ChangeLockState(bool lockState)
{
doorLockState = lockState;
}
}
最后一个脚本Door Hori附加到门的每个门子上。 门童的名字分别为Door_Keft和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();
}
}
第一个屏幕截图显示了门结构的示例。 还有Horizontal_Doors_Kit检查器:
第二张也是最后一张屏幕截图显示了Door_Left儿童检查器之一。 脚本和设置值在Door_Left和Door_Right上相同:
我的角色FPSController的刚体附有一个盒子对撞机来触发门。
答案 0 :(得分:1)
但是按照我的逻辑,只要我在触发区域内,门就应该保持打开状态。
但是在您的代码逻辑中却没有,您的代码逻辑是在门完成打开之后关闭门。
private void EndOpen(){
....
StartCoroutine( WaitToClose());
}
您需要添加OnTriggerLeave
事件以关闭门。
第二个问题与第一个问题有关,因此请先解决。