Ruota una porta in entrambe le direzioni in Unity

Ho creato una porta di apertura e chiusura in Unity. Posso aprire quella porta chiamando Interact() .

Ora voglio creare una porta che si apre sempre lontano dal giocatore. Come una porta di un saloon. Se il giocatore è di fronte a una stanza, la porta ruota nella stanza, se il giocatore è nella stanza, la porta ruota fuori da essa.

Attualmente ho creato un bool opensAwayFromPlayer . Se questo è vero, le rotazioni target dovrebbero essere fisse, quando si apre la porta.

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

Come puoi vedere qui

 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 } } 

Non so come calcolare la diversa rotazione per questo. L’impostazione delle rotazioni sui valori negativi non ha funzionato.

E quando ho ruotato la porta verso l’altra direzione a 90 gradi, non ha ruotato indietro, ha ruotato di 270 gradi indietro rimanendo con l’altra direzione.

Questo dovrebbe essere il copione finale. Puoi testarlo trascinando lo script su un object di gioco e chiamando il metodo 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()); }