2016-04-08 9 views
4

Unityを使って簡単な反復アプリケーションを作成するように求められました。このアプリケーションには、カメラに関する2つの主要機能があります。Unityのタッチコントロールとカメラのパンを組み合わせる

  1. 対象物に焦点を合わせるためにカメラを照合する。
  2. コントロールをユーザーに放棄して、ユーザーがオブジェクトを回ったりズームしたりできるようにします。

私はこれが初めてですが、これらの目標を孤立して達成する2つのスクリプトを作成しました。今私はそれらを合わせるのに苦労しています。

ユーザーの操作に関連するコードから始めます。

まず、TouchKitを使用して、各フレームのデルタ値を設定します(Start)。

// set the delta on each frame for horizontal and vertical rotation 
var oneTouch = new TKPanRecognizer(); 
oneTouch.gestureRecognizedEvent += (r) => 
{ 
    HorizontalDelta += r.deltaTranslation.x * rotateSpeed * Time.deltaTime; 
    VerticalDelta -= r.deltaTranslation.y * rotateSpeed * Time.deltaTime; 
}; 

// do the same for pinch 
var pinch = new TKPinchRecognizer(); 
pinch.gestureRecognizedEvent += (r) => 
{ 
    rotateDistance -= r.deltaScale * 200.0f * Time.deltaTime; 
}; 

TouchKit.addGestureRecognizer(oneTouch); 
TouchKit.addGestureRecognizer(pinch); 

そしてUpdate上:

VerticalDelta = Mathf.Clamp(VerticalDelta, verticalPivotMin, verticalPivotMax); 

var direction = GetDirection(HorizontalDelta, VerticalDelta); 

var currentTarget = targetsSwitched ? target2 : target; 

transform.position = currentTarget.position - direction * rotateDistance; 
transform.LookAt(currentTarget.position); 

// ... 

private Vector3 GetDirection(float x, float y) 
{ 
    Quaternion q = Quaternion.Euler(y, x, 0); 
    return q * Vector3.forward; 
} 

これは美しく動作し、私が欲しいまさにありません。問題は、カメラの移動スクリプトとこのコードを統合しようとするときに発生します。 (私はこれについて間違っている可能性があります)

void SetMoveToTarget(GameObject target) 
{ 
    if (currentlyMoving == false) 
    { 
     currentlyMoving = true; 
     fromRotation = currentTarget.transform.rotation; 
     currentTarget = target; 
     toRotation = currentTarget.transform.rotation; 

     timeStartedLerping = Time.time; 
    } 
} 

void FocusTarget(GameObject target) 
{ 

    float timeSinceStarted = Time.time - timeStartedLerping; 
    float percentageComplete = timeSinceStarted/(lerpSpeed); 

    transform.position = Vector3.MoveTowards(transform.position, target.transform.position, moveSpeed * Time.deltaTime); 
    transform.rotation = Quaternion.Lerp(fromRotation, toRotation, Mathf.Pow(percentageComplete, (float)1.2)); 

    if (Vector3.Distance(transform.position, target.transform.position) < 0.1 && percentageComplete > 0.99) 
    { 
     transform.position = target.transform.position; 
     transform.rotation = target.transform.rotation; 
     currentlyMoving = false; 
    } 
} 

私は何をする必要があるかと思う:これは私がこれらは実際にカメラを移動する機能があるUpdateコード

void Update() 
{ 
    if (currentlyMoving) 
    { 
     FocusTarget(currentTarget); 
    } 
    else 
    { 
     // accept user input if not moving 
     if (Input.GetKeyDown(KeyCode.Space)) 
     { 
      SetMoveToTarget(mainTargetObject); 
     } 

     if (Input.GetKeyDown(KeyCode.Q)) 
     { 
      SetMoveToTarget(subTargetObject1); 
     } 

     if (Input.GetKeyDown(KeyCode.E)) 
     { 
      SetMoveToTarget(subTargetObject2); 
     } 
    } 
} 

を追加する場所を示しrotateDistanceは、2番目のスクリプトのcurrentTargetと1番目のスクリプトのcurrentTargetの差に設定されています。

ありがとうございます、私にとっては非常に難しいものです。

答えて

2

最終的に私は最初にカメラを動かす方法を変更しなければなりませんでした。問題は、設定されたゲームオブジェクトへの移動が機能し、セットアップが簡単だったことです。実際にカメラの次の位置を計算して移動する必要がある場合は、lookスクリプトと統合する方がはるかに簡単です。

私は後作のためにここに作業用の製品を貼り付けていますが、最終的なゲームの中には欠けていますが、カメラは機能しています。

using UnityEngine; 
using UnityEngine.UI; 

public class NewCamera : MonoBehaviour { 

    // targets 
    public GameObject target; 
    public GameObject target2; 

    // settings 
    public float RotateSpeed = 50.0f; 
    public float RotateDistance = 3; 
    public float CameraMoveSpeed = 20f; 

    public float VerticalPivotMin = 5; 
    public float VerticalPivotMax = 65; 

    public float MinZoomIn = 1.7f; 
    public float MaxZoomIn = 4f; 

    // private 
    private GameObject lookTarget; 

    private bool currentlyMoving = false; 
    private Vector3 targetVector; 
    private float timeStartedLerping; 

    private float HorizontalDelta; 
    private float VerticalDelta; 

    void Start() 
    { 
     lookTarget = target; 

     var oneTouch = new TKPanRecognizer(); 
     oneTouch.gestureRecognizedEvent += (r) => 
     { 
      if (currentlyMoving == false) 
      { 
       HorizontalDelta += r.deltaTranslation.x * RotateSpeed * Time.deltaTime; 
       VerticalDelta -= r.deltaTranslation.y * RotateSpeed * Time.deltaTime; 

       VerticalDelta = Mathf.Clamp(VerticalDelta, VerticalPivotMin, VerticalPivotMax); 
      } 
     }; 

     var pinch = new TKPinchRecognizer(); 
     pinch.gestureRecognizedEvent += (r) => 
     { 
      if (currentlyMoving == false) 
      { 
       RotateDistance -= r.deltaScale * 200.0f * Time.deltaTime; 
       RotateDistance = Mathf.Clamp(RotateDistance, MinZoomIn, MaxZoomIn); 
      } 
     }; 

     TouchKit.addGestureRecognizer(oneTouch); 
     TouchKit.addGestureRecognizer(pinch); 
    } 

    void Update() 
    { 
     if (currentlyMoving) 
     { 
      FocusTarget(); 
     } 
     else 
     { 
      var direction = GetDirection(HorizontalDelta, VerticalDelta); 

      transform.position = lookTarget.transform.position - direction * RotateDistance; 
      transform.LookAt(lookTarget.transform.position); 
     } 
    } 

    public void OnButtonClick() 
    { 
     var currentTarget = target.GetInstanceID() == lookTarget.GetInstanceID() ? target : target2; 
     var nextTarget = currentTarget.GetInstanceID() == target.GetInstanceID() ? target2 : target; 

     var cameraPosition = transform.position; 
     var targetPosition = currentTarget.transform.position; 

     SetMoveToTarget(nextTarget, cameraPosition - targetPosition); 
    } 

    void SetMoveToTarget(GameObject moveTo, Vector3 offset) 
    { 
     currentlyMoving = true; 
     targetVector = moveTo.transform.position + offset; 
     lookTarget = moveTo; 
    } 

    void FocusTarget() 
    { 
     transform.position = Vector3.Lerp(transform.position, targetVector, CameraMoveSpeed * Time.deltaTime); 

     if (Vector3.Distance(transform.position, targetVector) < 0.01) 
     { 
      transform.position = targetVector; 
      currentlyMoving = false; 
     } 
    } 

    private Vector3 GetDirection(float x, float y) 
    { 
     Quaternion q = Quaternion.Euler(y, x, 0); 
     return q * Vector3.forward; 
    } 
} 

何らかの理由でこのスクリプトを使用する場合は、このスクリプトをカメラに追加して2つのターゲットを設定するだけです。新しいターゲットを簡単に追加できる、より堅牢なバージョンを作成する必要がありますが、これは今のところ行います。

ハッピーハッキング!

関連する問題