2017-05-19 4 views
-1

最初のスクリプトは、このスクリプトで地形を移動するだけです。私は何も変更していません。 2番目のスクリプトはPatrolDataで、私は最初のスクリプトにデータを送ります。最後のスクリプトは、次のターゲット(ウェイポイント)に移動する前にちょっとだけカメラを回転させるべきLookAtです。カメラを次のターゲットを見て回転させ、次のターゲットに移動するにはどうすればいいですか?

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class FlyToOverTerrain : MonoBehaviour 
{ 
    public Transform target; 
    public float desiredHeight = 10f; 

    public float flightSmoothTime = 10f; 
    public float maxFlightspeed = 10f; 
    public float flightAcceleration = 1f; 

    public float levelingSmoothTime = 0.5f; 
    public float maxLevelingSpeed = 10000f; 
    public float levelingAcceleration = 2f; 

    private Vector3 flightVelocity = Vector3.zero; 
    private float heightVelocity = 0f; 

    private void LateUpdate() 
    { 
     Vector3 position = transform.position; 
     float currentHeight = position.y; 
     if ((bool)target && flightAcceleration > float.Epsilon) 
     { 
      position = Vector3.SmoothDamp(position, target.position, ref flightVelocity, flightSmoothTime/flightAcceleration, maxFlightspeed, flightAcceleration * Time.deltaTime); 
     } 

     if (levelingAcceleration > float.Epsilon) 
     { 
      float targetHeight = Terrain.activeTerrain.SampleHeight(position) + desiredHeight; 

      position.y = Mathf.SmoothDamp(currentHeight, targetHeight, ref heightVelocity, levelingSmoothTime/levelingAcceleration, maxLevelingSpeed, levelingAcceleration * Time.deltaTime); 
     } 

     transform.position = position; 
    } 
} 

そして、データスクリプト:

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

[System.Serializable] 
public class PatrolData 
{ 
    public Transform target = null; 
    public float minDistance = 5f; 
    public float lingerDuration = 5f; 

    public float desiredHeight = 10f; 

    public float flightSmoothTime = 10f; 
    public float maxFlightspeed = 10f; 
    public float flightAcceleration = 1f; 

    public float levelingSmoothTime = 0.5f; 
    public float maxLevelingSpeed = 10000f; 
    public float levelingAcceleration = 2f; 
} 

public class PatrolOverTerrain : MonoBehaviour 
{ 
    public FlyToOverTerrain flyOverTerrain; 
    public enum PatrolMode { Clamp, Wrap, PingPong }; 
    public PatrolData[] patrolPoints; 
    public PatrolMode mode = PatrolMode.Wrap; 

    private int iterator = 0; 
    private int index = 0; 
    private float lingerDuration = 0f; 

    public Vector3 distanceFromTarget; 

    private void OnEnable() 
    { 
     if (patrolPoints.Length > 0) 
     { 
      lingerDuration = patrolPoints[index].lingerDuration; 
     } 
    } 

    private void Update() 
    { 
     int length = patrolPoints.Length; 
     if (!flyOverTerrain) return; 
     if (patrolPoints.Length < 1) return; 
     if (index < 0) return; 

     var patrol = patrolPoints[index]; 
     if (lingerDuration <= 0) 
     { 
      iterator++; 
      switch (mode) 
      { 
       case PatrolMode.Clamp: 
        index = (iterator >= length) ? -1 : iterator; 
        break; 
       case PatrolMode.Wrap: 
        iterator = Modulus(iterator, length); 
        index = iterator; 
        break; 
       case PatrolMode.PingPong: 
        iterator = Modulus(iterator, length * 2); 
        index = length - Mathf.Abs(length - iterator); 
        break; 
      } 
      if (index < 0) return; 

      patrol = patrolPoints[index]; 

      flyOverTerrain.target = patrol.target; 
      flyOverTerrain.desiredHeight = patrol.desiredHeight; 
      flyOverTerrain.flightSmoothTime = patrol.flightSmoothTime; 
      flyOverTerrain.maxFlightspeed = patrol.maxFlightspeed; 
      flyOverTerrain.flightAcceleration = patrol.flightAcceleration; 
      flyOverTerrain.levelingSmoothTime = patrol.levelingSmoothTime; 
      flyOverTerrain.maxLevelingSpeed = patrol.maxLevelingSpeed; 
      flyOverTerrain.levelingAcceleration = patrol.levelingAcceleration; 

      lingerDuration = patrolPoints[index].lingerDuration; 
     } 


     Vector3 targetOffset = Vector3.zero; 
     if ((bool)patrol.target) 
     { 
      targetOffset = transform.position - patrol.target.position; 
     } 

     float sqrDistance = patrol.minDistance * patrol.minDistance; 
     if (targetOffset.sqrMagnitude <= sqrDistance) 
     { 
      flyOverTerrain.target = null; 
      lingerDuration -= Time.deltaTime; 
     } 
     else 
     { 
      flyOverTerrain.target = patrol.target; 
     } 

     distanceFromTarget = transform.position - patrol.target.position; 
    } 


    private int Modulus(int baseNumber, int modulus) 
    { 
     return (modulus == 0) ? baseNumber : baseNumber - modulus * (int)Mathf.Floor(baseNumber/(float)modulus); 
    } 
} 

そして、ルックアットスクリプト

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class LookAtCamera : MonoBehaviour { 

    //values that will be set in the Inspector 
    public Transform target; 
    public float RotationSpeed; 

    //values for internal use 
    private Quaternion _lookRotation; 
    private Vector3 _direction; 

    // Update is called once per frame 
    void Update() 
    { 
     //find the vector pointing from our position to the target 
     _direction = (target.position - transform.position).normalized; 

     //create the rotation we need to be in to look at the target 
     _lookRotation = Quaternion.LookRotation(_direction); 

     //rotate us over time according to speed until we are in the required rotation 
     transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime * RotationSpeed); 
    } 
} 

は、すべてのスクリプトは、メインカメラに取り付けられています。今まではカメラがターゲット間を移動しても問題なく動作していました。今私がしたいのは、カメラが次のターゲットに移動する前に、各ターゲットの近くでカメラが停止したときに、移動先のターゲットに向かって回転させるときです。

問題は、私がそれを待たせる方法と、LookAtCameraスクリプトで回転を開始するタイミングとをいつも分かりません。

ゲームを実行するとすぐに次のターゲットに向かって回転し始めます(インスペクタで2番目のターゲットをテストするためにドラッグしました)。

私の問題は、LookAtCameraスクリプトを使用する方法です。

答えて

-1

これを行う方法が見つかりました。 iもアップデート機能では、既存のターゲットがあることを確認し、メインカメラにそれを取り付けたLookAtCameraスクリプトの最初:

場合(ターゲット)

ので、アップデート機能:

void Update() 
    { 
     //find the vector pointing from our position to the target 
     if (target) 
      _direction = (target.position - transform.position).normalized; 

     //create the rotation we need to be in to look at the target 
     _lookRotation = Quaternion.LookRotation(_direction); 

     //rotate us over time according to speed until we are in the required rotation 
     transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime * RotationSpeed); 
    } 

その後、スクリプトPatrolData: スクリプトPatrolDataは、この場合、メインカメラにも添付されたゲームオブジェクトにアタッチすることができます。

を次に更新機能で:私は追加FlyToVerTerrainの上部において

lookAtCamera.target = patrol.target; 
lookAtCamera.RotationSpeed = 3; 

そしてこの部分で:最後に

if (targetOffset.sqrMagnitude <= sqrDistance) 
     { 
      flyOverTerrain.target = null; 
      lookAtCamera.target = null; 
      lingerDuration -= Time.deltaTime; 
     } 
     else 
     { 
      flyOverTerrain.target = patrol.target; 
      lookAtCamera.target = patrol.target; 
     } 

すべての3スクリプトは、カメラが各ウェイポイント(ターゲット)に移動するようにします。カメラは回転し、次のウェイポイントに向かいます次のウェイポイントに移動する前に。

作業には最適です。

関連する問題