1

Unity3D の ThirdPersonCamera.js スクリプトに基づいて、カスタムのトップダウン カメラ ロジック スクリプトを作成しました。すべてが適切に機能しているように見えます。カメラは XZ 平面上でターゲット プレーヤーを追跡し、プレーヤーがジャンプすると、必要に応じて Y 軸に沿って移動します。

カメラだけがプレイヤーを見ていません。そこで、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 =====

問題コード セクションをPROBLEM CODEコメントでマークしました。問題のコードが削除されると、WASD の動きが再び機能するようになりますが、カメラはターゲットを見ていません。

この問題についての洞察は非常に高く評価されています。

4

1 に答える 1

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;

問題を修正しました。

于 2013-04-19T00:49:30.897 に答える