在Unity中向两个方向旋转门

我在Unity创建了一个开门和关门。 我可以通过调用Interact()打开那扇门。

现在我想创建一个始终远离玩家的门。 就像一个沙龙的门。 如果玩家在房间前面,门会旋转到房间,如果玩家在房间内,则门会旋转出来。

目前我创建了一个bool opensAwayFromPlayer 。 如果这是真的,打开门时应该固定目标旋转。

 [SerializeField] private Vector3 targetRotation; // rotation angles [SerializeField] private float duration; // rotation speed [SerializeField] private bool closeAgain; // close the door again? [SerializeField] private float waitInterval; // close the door after x seconds [SerializeField] private Vector3 pivotPosition; // Vector3 of the pivot [SerializeField] private bool opensAwayFromPlayer; // door can open both directions [SerializeField] private Transform playerTransform; // Player Object private Vector3 defaultRotation; // store the rotation when starting the game private bool isActive = false; Transform doorPivot; // the pivot point to rotate around private void Start() { doorPivot = new GameObject().transform; // create pivot doorPivot.position = pivotPosition; // place the pivot before parenting! transform.SetParent(doorPivot); // make the door being a child of the pivot defaultRotation = doorPivot.eulerAngles; } private IEnumerator DoorRotation() { if (isActive) yield break; isActive = true; float counter = 0; Vector3 defaultAngles = doorPivot.eulerAngles; Vector3 openRotation = transform.eulerAngles + targetRotation; while (counter  0) { counter -= Time.deltaTime; LerpDoor(defaultAngles, openRotation, counter); // close the door yield return null; } isActive = false; } private void LerpDoor(Vector3 defaultAngles, Vector3 targetRotation, float counter) { doorPivot.eulerAngles = Vector3.Lerp(defaultAngles, targetRotation, counter / duration); } private bool PlayerIsBehindDoor() // is the player in front of or behind the door? { Vector3 doorTransformDirection = transform.TransformDirection(Vector3.forward); // door direction Vector3 playerTransformDirection = playerTransform.position - transform.position; // player direction return Vector3.Dot(doorTransformDirection, playerTransformDirection) < 0; // return player is in front or behind the door } public void Interact() // start the rotation { StartCoroutine(DoorRotation()); } 

正如你在这里看到的那样

 if (opensAwayFromPlayer) // door can open both directions? { if (PlayerIsBehindDoor()) // Player is behind the door? (in the room) { // openRotation = ; // open to the other direction // closeRotation = ; // close / back to the default rotation } } 

我不知道如何计算它的不同旋转。 只是将旋转设置为负值不起作用。

当我将门向另一个方向旋转90度时,它没有向后旋转,它向后旋转270度,同时保持另一个方向。

这应该是最终的脚本。 您可以通过在游戏对象上拖动脚本并调用方法Interact()来测试它

  [SerializeField] private Vector3 targetRotation; [SerializeField] private float duration; [SerializeField] private bool closeAgain; [SerializeField] private float waitInterval; [SerializeField] private Vector3 pivotPosition; [SerializeField] private bool opensAwayFromPlayer; private Vector3 defaultRotation; private bool isActive = false; private Transform doorPivot; private Transform playerTransform; private void Start() { playerTransform = Globals.GetPlayerObject().transform; doorPivot = new GameObject().transform; doorPivot.position = pivotPosition; transform.SetParent(doorPivot); defaultRotation = doorPivot.eulerAngles; } private IEnumerator DoorRotation() { if (isActive) yield break; isActive = true; float counter = 0; Vector3 defaultAngles = doorPivot.eulerAngles; if (PlayerIsBehindDoor()) targetRotation = -targetRotation; Vector3 openRotation = transform.eulerAngles + targetRotation; while (counter < duration) { counter += Time.deltaTime; LerpDoor(defaultAngles, openRotation, counter); yield return null; } if (!closeAgain) Destroy(this); yield return new WaitForSeconds(waitInterval); while (counter > 0) { counter -= Time.deltaTime; LerpDoor(defaultAngles, openRotation, counter); yield return null; } isActive = false; } private void LerpDoor(Vector3 defaultAngles, Vector3 targetRotation, float counter) { doorPivot.eulerAngles = Vector3.Lerp(defaultAngles, targetRotation, counter / duration); } private bool PlayerIsBehindDoor() { Vector3 doorTransformDirection = transform.TransformDirection(Vector3.forward); Vector3 playerTransformDirection = playerTransform.position - transform.position; return Vector3.Dot(doorTransformDirection, playerTransformDirection) < 0; } public void Interact() { StartCoroutine(DoorRotation()); }