2013-04-18 38 views
1

我已經放在一起基於Unity3D的ThirdPersonCamera.js腳本自定義自上而下的相機邏輯腳本。一切似乎都在正常工作,相機在XZ平面上跟隨目標玩家,甚至在玩家跳躍時適當地沿着Y軸移動。Unity3D - 自頂向下相機邏輯使用Transform.LookAt時鎖定

只有相機沒有看着播放器。所以我試着在cameraTransform上使用Transform.LookAt()讓攝像機直接看着玩家。這確實會導致相機正確地直視播放器,但通過WASD移動不再有效。玩家就坐在那裏。儘管使用空格鍵跳躍仍然有效。

這對我來說沒有意義,相機變換的方向應該如何影響玩家對象的移動?

我的腳本代碼如下:

// The transform of the camera that we're manipulating 
var cameraTransform : Transform; 

// The postion that the camera is currently focused on 
var focusPosition = Vector3.zero; 

// The idle height we are aiming to be above the target when the target isn't moving 
var idleHeight = 7.0; 

// How long should it take the camera to focus on the target on the XZ plane 
var xzSmoothLag = 0.3; 

// How long should it take the camera to focus on the target vertically 
var heightSmoothLag = 0.3; 


private var _target : Transform; 
private var _controller : ThirdPersonController; 

private var _centerOffset = Vector3.zero; 
private var _headOffset = Vector3.zero; 
private var _footOffset = Vector3.zero; 

private var _xzVelocity = 0.0; 
private var _yVelocity = 0.0; 
private var _cameraHeightVelocity = 0.0; 


// ===== UTILITY FUNCTIONS ===== 

// Apply the camera logic to the camera with respect for the target 
function process() 
{ 
    // Early out if we don't have a target 
    if (!_controller) 
     return; 

    var targetCenter = _target.position + _centerOffset; 
    var targetHead = _target.position + _headOffset; 
    var targetFoot = _target.position + _footOffset; 

    // Determine the XZ offset of the focus position from the target foot 
    var xzOffset = Vector2(focusPosition.x, focusPosition.z) - Vector2(targetFoot.x, targetFoot.z); 

    // Determine the distance of the XZ offset 
    var xzDistance = xzOffset.magnitude; 

    // Determine the Y distance of the focus position from the target foot 
    var yDistance = focusPosition.y - targetFoot.y; 

    // Damp the XZ distance 
    xzDistance = Mathf.SmoothDamp(xzDistance, 0.0, _xzVelocity, xzSmoothLag); 

    // Damp the XZ offset 
    xzOffset *= xzDistance; 

    // Damp the Y distance 
    yDistance = Mathf.SmoothDamp(yDistance, 0.0, _yVelocity, heightSmoothLag); 

    // Reposition the focus position by the dampened distances 
    focusPosition.x = targetFoot.x + xzOffset.x; 
    focusPosition.y = targetFoot.y + yDistance; 
    focusPosition.z = targetFoot.z + xzOffset.y; 

    var minCameraHeight = targetHead.y; 
    var targetCameraHeight = minCameraHeight + idleHeight; 

    // Determine the current camera height with respect to the minimum camera height 
    var currentCameraHeight = Mathf.Max(cameraTransform.position.y, minCameraHeight); 

    // Damp the camera height 
    currentCameraHeight = Mathf.SmoothDamp(currentCameraHeight, targetCameraHeight, _cameraHeightVelocity, heightSmoothLag); 

    // Position the camera over the focus position 
    cameraTransform.position = focusPosition; 
    cameraTransform.position.y = currentCameraHeight; 

// PROBLEM CODE - BEGIN 

    // Have the camera look at the focus position 
    cameraTransform.LookAt(focusPosition, Vector3.forward); 

// PROBLEM CODE - END 

    Debug.Log("Camera Focus Position: " + focusPosition); 
    Debug.Log("Camera Transform Position: " + cameraTransform.position); 
} 

// ===== END UTILITY FUNCTIONS ===== 


// ===== UNITY FUNCTIONS ===== 

// Initialize the script 
function Awake() 
{ 
    // If the camera transform is unassigned and we have a main camera, 
    // set the camera transform to the main camera's transform 
    if (!cameraTransform && Camera.main) 
     cameraTransform = Camera.main.transform; 

    // If we don't have a camera transform, report an error 
    if (!cameraTransform) 
    { 
     Debug.Log("Please assign a camera to the TopDownThirdPersonCamera script."); 
     enabled = false;  
    } 

    // Set the target to the game object transform 
    _target = transform; 

    // If we have a target set the controller to the target's third person controller 
    if (_target) 
    { 
     _controller = _target.GetComponent(ThirdPersonController); 
    } 

    // If we have a controller, calculate the center offset and head offset 
    if (_controller) 
    { 
     var characterController : CharacterController = _target.collider; 
     _centerOffset = characterController.bounds.center - _target.position; 
     _headOffset = _centerOffset; 
     _headOffset.y = characterController.bounds.max.y - _target.position.y; 
     _footOffset = _centerOffset; 
     _footOffset.y = characterController.bounds.min.y - _target.position.y; 
    } 
    // If we don't have a controller, report an error 
    else 
     Debug.Log("Please assign a target to the camera that has a ThirdPersonController script attached."); 

    // Apply the camera logic to the camera 
    process(); 
} 

function LateUpdate() 
{ 
    // Apply the camera logic to the camera 
    process(); 
} 

// ===== END UNITY FUNCTIONS ===== 

我打上問題代碼意見的問題代碼段。如果問題代碼被刪除,它將允許WASD移動再次運行,但是攝像機不再看目標。

對此問題的任何深入瞭解都非常感謝。

回答

1

我想通了,問題出在我用的ThirdPersonController.js腳本。在函數UpdateSmoothedMovementDirection()中,ThirdPersonController使用cameraTransform根據相機所在的位置確定沿着XZ平面的前進方向。在這樣做的時候,它將Y軸清零並規範剩下的部分。

我在我的自定義TopDownCamera.js腳本中執行的cameraTransform.LookAt()調用使攝像機直接沿着Y軸看。所以當ThirdPersonController得到它的持有並且從Y軸消失時,我最終得到零向前的方向,這導致XZ移動無處可去。

複製ThirdPersonController.js和改變代碼,以便:

var forward = cameraTransform.TransformDirection(Vector3.forward); 
forward.y = 0; 
forward = forward.normalized; 

變爲:

forward = Vector3.forward; 

固定的問題。