我已经建立了一个自定义自上而下的相机逻辑脚本,基于Unity3D的ThirdPersonCamera.js脚本。一切看起来都正常工作,相机跟随目标玩家在XZ平面上,甚至在玩家跳跃时沿着Y轴移动。
只是摄像机没在盯着玩家看。因此,我尝试在cameraTransform上使用cameraTransform()让摄像机直接向下看播放机。这确实会导致相机在播放器上正确地向下看,但是通过WASD的移动不再有效。玩家就坐在那里。不过,使用Spacebar进行跳跃仍然有效。
这对我来说是没有意义的,相机变换的方向如何影响玩家物体的运动呢?
我的脚本的代码如下:
// 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移动再次工作,但是相机不再盯着目标。
对这个问题的任何见解都是非常感谢的。
发布于 2013-04-19 00:49:30
我想出了问题,问题在于我正在使用的ThirdPersonController.js脚本。在函数UpdateSmoothedMovementDirection()中,ThirdPersonController使用cameraTransform根据摄像机所观察的位置确定XZ平面的前进方向。在此过程中,它将Y轴归零,并将剩下的归零。
我在自定义的cameraTransform.LookAt脚本中执行的TopDownCamera.js ()调用让摄像机直接向下看Y轴。因此,当ThirdPersonController抓住它并将Y轴归零时,我最终得到的方向为零,这导致XZ运动无处可去。
复制ThirdPersonController.js并修改代码,以便:
var forward = cameraTransform.TransformDirection(Vector3.forward);
forward.y = 0;
forward = forward.normalized;变成:
forward = Vector3.forward;解决了这个问题。
https://stackoverflow.com/questions/16095025
复制相似问题