2017-10-10 3 views
3

ユニティにドアを開け閉めました。私はInteract()と呼んでそのドアを開くことができます。ユニティの両方向にドアを回す

今、私は常にプレーヤーから離れて開くドアを作りたいと思います。サルーンのドアのように。プレーヤーが部屋の前にいる場合、ドアは部屋に回転し、プレーヤーが部屋にいれば、ドアはそこから回転します。

現在、私はブール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度回転しました。

+0

NITを呼び出すことによって、それをテストすることができます。 – Foggzie

答えて

3

これは最終的なスクリプトである必要があります。 `tranform.forward`が` `transform.TransformDirection(Vector3.forward)と同じものを返します:あなたはゲームオブジェクトにスクリプトをドラッグし、方法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()); 
    } 
関連する問題