重要:
我在这里发了一篇文章 Rotate a door in both directions in Unity 我在与它交互时创造了一个全自动门。
现在我想要一个门,由玩家开放并由玩家关闭。您可以设置一个bool,使门始终远离播放器。
调用方法Interact()
时,门旋转将开始。我从另一个脚本调用此方法。所以在这个时刻,这个方法只被称为一次。
[SerializeField]
Vector3 openRotation; // door rotation when opened
[SerializeField]
float duration; // opening speed (duration)
[SerializeField]
bool isClosable; // door can be closed again?
[SerializeField]
Vector3 pivotPosition; // position of the pivot point
[SerializeField]
bool opensAwayFromPlayer; // always open away from the player
bool isActive = false; // door is "busy" ?
Transform doorPivot;
Transform playerTransform;
bool isOpen = false;
private void Start()
{
playerTransform = Globals.GetPlayerObject().transform;
doorPivot = new GameObject().transform;
doorPivot.position = pivotPosition;
transform.SetParent(doorPivot);
}
public void Interact() // Interact with the door and start opening / closing it
{
StartCoroutine(DoorRotation());
}
void IEnumerator DoorRotation()
{
if (isActive) // return if already active
yield break;
isActive = true;
float counter; // current rotation counter
Vector3 defaultAngles = doorPivot.eulerAngles;
Vector3 desiredRotation = this.openRotation; // the target rotation
if (opensAwayFromPlayer && PlayerIsBehindDoor(transform, playerTransform)) // if behind door -> change direction
desiredRotation = -desiredRotation;
Vector3 openRotation = transform.eulerAngles + desiredRotation; // the final rotation
if (!isOpen) // open if closed
{
counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
LerpDoorRotation(doorPivot, defaultAngles, openRotation, counter, duration); // open the door
yield return null;
}
if (!isClosable) // if not closing again, destroy the script
Destroy(this);
}
else // close the door
{
counter = duration;
while (counter > 0)
{
counter -= Time.deltaTime;
LerpDoorRotation(doorPivot, defaultAngles, openRotation, counter, duration); // close the door
yield return null;
}
}
isOpen = !isOpen; // Toggle door state
isActive = false; // Door is not "busy"
}
bool PlayerIsBehindDoor(Transform door, Transform player) // Check if the player is in front or behind the door
{
Vector3 doorTransformDirection = door.forward.normalized;
Vector3 playerTransformDirection = (player.position - door.position).normalized;
return Vector3.Dot(doorTransformDirection, playerTransformDirection) < 0;
}
void LerpDoorRotation(Transform doorPivot, Vector3 defaultAngles, Vector3 targetRotation, float counter, float duration) // Door Rotation
{
doorPivot.eulerAngles = Vector3.Lerp(defaultAngles, targetRotation, counter / duration);
}
所以这扇门有一种非常奇怪的行为。它没有正确打开和关闭。我创建了一个显示与门进行交互时的行为的gif。
https://cdn.discordapp.com/attachments/165027329981153280/369749092638916608/doors.gif
门打开两次然后改变目标角度。