本文共 6369 字,大约阅读时间需要 21 分钟。
在Unity游戏开发中,角色控制器与视角的实现是实现游戏逻辑的重要环节。本文将详细介绍如何通过Unity的Character Controller组件来控制角色移动,并结合摄像机控制器实现第一人称和第三人称视角的效果。
Character Controller组件是Unity中用于控制角色移动的核心组件。它能够在受制于碰撞的情况下自动处理角色运动,而无需手动处理刚体或受力情况。主要特点包括:
以下是使用SimpleMove和Move函数的示例代码:
CharacterController controller = GetComponent();Vector3 forward = transform.TransformDirection(Vector3.forward);float curSpeed = speed * Input.GetAxis("Vertical");controller.SimpleMove(forward * curSpeed);
在游戏中,视角的控制是玩家体验感的重要因素。Unity提供了两种常见的视角控制器:第一人称和第三人称。
第一人称视角是许多经典游戏(如CS:GO)使用的视角类型。摄像机的位置与玩家角色保持一致,视角随着角色移动而移动。
实现步骤:
第三人称视角常用于角色扮演游戏(如Dota)。摄像机距离角色有一定距离,能够清晰观察角色动作。
实现步骤:
function Update() { // 获取键盘方向 var directionVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); // 处理方向向量 if (directionVector != Vector3.zero) { var directionLength = directionVector.magnitude; directionVector = directionVector / directionLength; directionLength = Mathf.Min(1, directionLength); directionLength = directionLength * directionLength; directionVector = directionVector * directionLength; } // 设置移动方向 motor.inputMoveDirection = transform.rotation * directionVector; // 处理跳跃 motor.inputJump = Input.GetButton("Jump");} function Update() { // 处理跳跃逻辑 if (Input.GetButtonDown("Jump")) { lastJumpButtonTime = Time.time; } // 更新角色方向 UpdateSmoothedMovementDirection(); // 处理重力和跳跃 ApplyGravity(); ApplyJumping(); // 计算实际动作 var movement = moveDirection * moveSpeed + Vector3(0, verticalSpeed, 0) + inAirVelocity; movement *= Time.deltaTime; // 移动角色 var controller : CharacterController = GetComponent(CharacterController); collisionFlags = controller.Move(movement); // 处理动画 if(_animation) { // 根据角色状态处理动画 if(_characterState == CharacterState.Jumping) { // 处理跳跃动画 if(!jumpingReachedApex) { _animation[jumpPoseAnimation.name].speed = jumpAnimationSpeed; _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever; _animation.CrossFade(jumpPoseAnimation.name); } else { _animation[jumpPoseAnimation.name].speed = -landAnimationSpeed; _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever; _animation.CrossFade(jumpPoseAnimation.name); } } else { // 处理站立、奔跑、疾走等状态动画 if(controller.velocity.sqrMagnitude < 0.1) { _animation.CrossFade(idleAnimation.name); } else { if(_characterState == CharacterState.Running) { _animation[runAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, runMaxAnimationSpeed); _animation.CrossFade(runAnimation.name); } else if(_characterState == CharacterState.Trotting) { _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, trotMaxAnimationSpeed); _animation.CrossFade(walkAnimation.name); } else if(_characterState == CharacterState.Walking) { _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, walkMaxAnimationSpeed); _animation.CrossFade(walkAnimation.name); } } } } // 处理旋转 if (IsGrounded()) { transform.rotation = Quaternion.LookRotation(moveDirection); } else { var xzMove = movement; xzMove.y = 0; if (xzMove.sqrMagnitude > 0.001) { transform.rotation = Quaternion.LookRotation(xzMove); } } // 处理跳跃状态 if (IsGrounded()) { lastGroundedTime = Time.time; inAirVelocity = Vector3.zero; if (jumping) { jumping = false; SendMessage("DidLand", SendMessageOptions.DontRequireReceiver); } }} function Apply(dummyTarget : Transform, dummyCenter : Vector3) { // 处理摄像机旋转 if (!controller) { return; } // 计算目标中心和顶点 var targetCenter = _target.position + centerOffset; var targetHead = _target.position + headOffset; // 计算当前角度 var originalTargetAngle = _target.eulerAngles.y; var currentAngle = cameraTransform.eulerAngles.y; // 处理快速旋转 if (Input.GetButton("Fire2")) { snap = true; } if (snap) { // 检查是否接近目标角度 if (AngleDistance(currentAngle, originalTargetAngle) < 3.0) { snap = false; } // 平滑旋转 currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, angleVelocity, snapSmoothLag, snapMaxSpeed); } // 处理普通视角 else { // 延迟处理 if (controller.GetLockCameraTimer() < lockCameraTimeout) { targetAngle = currentAngle; } // 后退时锁定视角 if (AngleDistance(currentAngle, targetAngle) > 160 && controller.IsMovingBackwards()) { targetAngle += 180; // 平滑旋转 currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, angleVelocity, angularSmoothLag, angularMaxSpeed); } } // 处理跳跃时的视角 if (controller.IsJumping()) { // 调整摄像机高度 var newTargetHeight = targetCenter.y + height; if (newTargetHeight < targetHeight || newTargetHeight - targetHeight > 5) { targetHeight = targetCenter.y + height; } } // 调整摄像机位置和高度 var currentHeight = cameraTransform.position.y; currentHeight = Mathf.SmoothDamp(currentHeight, targetHeight, heightVelocity, heightSmoothLag); // 更新摄像机位置 cameraTransform.position = targetCenter; cameraTransform.position += currentRotation * Vector3.back * distance; cameraTransform.position.y = currentHeight; // 保持摄像机朝向目标 SetUpRotation(targetCenter, targetHead);} 通过使用Unity的Character Controller组件和自定义脚本,我们可以轻松实现角色和摄像机的移动控制。Character Controller能够自动处理碰撞和重力,简化了游戏逻辑开发。无论是第一人称还是第三人称视角,通过合理配置摄像机控制器组件,都能实现理想的视角效果。
转载地址:http://othfk.baihongyu.com/