gpt4 book ai didi

c# - 在 Unity 中双向旋转门

转载 作者:行者123 更新时间:2023-11-30 15:56:30 24 4
gpt4 key购买 nike

我在 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 < duration)
{
counter += Time.deltaTime;
LerpDoor(defaultAngles, openRotation, counter); // open the door
yield return null;
}

if (!closeAgain)
Destroy(this);

yield return new WaitForSeconds(waitInterval); // wait some seconds

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());
}

关于c# - 在 Unity 中双向旋转门,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46662998/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com