rejump这些三个字母组成的单词能组成什么词

当前位置: &
求翻译:accelerate before the jump, then hold the jump button and release all other buttons.是什么意思?
accelerate before the jump, then hold the jump button and release all other buttons.
问题补充:
加快前跳,然后按住跳跃键,并释放所有其他的按钮。
加速在跳,然后举行的跳按钮和释放所有其他按钮。
加速,在跃迁,然后拿着跃迁按钮并且发布其他按钮之前。
加快前跳转,然后按住跳转按钮并释放所有其他按钮。
加快前跳转,然后按住跳转按钮并释放所有其他按钮。
我来回答:
参考资料:
* 验证码:
登录后回答可以获得积分奖励,并可以查看和管理所有的回答。 |
我要翻译和提问
请输入您需要翻译的文本!影视剧本高瞻远瞩放眼全球
每天学英语
想进步,请坚持参与每天学英语活动!
每天一词:
最新社区精华帖子
走遍美国教学版
哈利学前班[英语儿歌]
海绵宝宝 英文版
风中的女王第1季
经典学习方法
文章资料目录导航
      
免责声明:本站只提供资源播放平台,如果站内部分资源侵犯您的权益,请您告知,我们会立即处理。
Copyright &
大耳朵英语 & |您所在的位置: &
Unity3D研究之第一人称第三人称角色控制组件修改
Unity3D研究之第一人称第三人称角色控制组件修改
可是我们还是喜欢用C#来编写脚本,本篇文章MOMO将把角色控制器的所有脚本全部改成C#语言。方便自己也方便大家学习.
之前作者在前文中向大家介绍了角色控制器组件。默认系统提供了JavaScript脚本的支持,可是我们还是喜欢用C#来编写脚本,本篇文章作者将把角色控制器的所有脚本全部改成C#语言。方便自己也方便大家学习。首先,我们将角色控制器包引入工程中。如下图所示,默认提供的脚本除了MouseLook以外其它的都是JS脚本,本篇文章作者将把它们全部修改成C#。刚好也是答应Unity圣典的站长录制游戏开发视频,视频中我说下一节我将教大家怎么把角色控制器组件的脚本全部改成C#。
498)this.width=498;' onmousewheel = 'javascript:return big(this)' title="屏幕快照
下午11.39.40" alt="" src="/files/uploadimg/2510.png" />
首先把CharacterMotor.js修改成C# 它主要设置角色控制的系数,如运动、跳跃、移动、滑动等。第一人称与第三人称主角模型的移动与旋转的角度都最后都是在这里计算的,请大家好好看看这个类, 尤其是UpdateFunction()方法。
CharacterMotor.cs &
[代码]c#/cpp/oc代码:
using UnityE
using System.C
[RequireComponent(typeof(CharacterController))]
[AddComponentMenu(&Character/Character Motor&)]
public class CharacterMotor : MonoBehaviour {
// Does this script currently respond to input?
public bool canControl
public bool useFixedUpdate =
// For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!
// The current global direction we want the character to move in.
[System.NonSerialized]
public Vector3 inputMoveDirection = Vector3.
// Is the jump button held down? We use this interface instead of checking
// for the jump button directly so this script can also be used by AIs.
[System.NonSerialized]
public bool inputJump
[System.Serializable]
public class CharacterMotorMovement
// The maximum horizontal speed when moving
public float maxForwardSpeed = 10.0f;
public float maxSidewaysSpeed = 10.0f;
public float maxBackwardsSpeed = 10.0f;
// Curve for multiplying speed based on slope (negative = downwards)
public AnimationCurve slopeSpeedMultiplier = new AnimationCurve(new Keyframe(-90, 1), new Keyframe(0, 1), new Keyframe(90, 0));
// How fast does the character change speeds?
Higher is faster.
public float maxGroundAcceleration = 30.0f;
public float maxAirAcceleration = 20.0f;
// The gravity for the character
public float gravity = 10.0f;
public float maxFallSpeed = 20.0f;
// For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!
// The last collision flags returned from controller.Move
[System.NonSerialized]
public CollisionFlags collisionF
// We will keep track of the character's current velocity,
[System.NonSerialized]
public Vector3
// This keeps track of our current velocity while we're not grounded
[System.NonSerialized]
public Vector3 frameVelocity = Vector3.
[System.NonSerialized]
public Vector3 hitPoint = Vector3.
[System.NonSerialized]
public Vector3 lastHitPoint = new Vector3(Mathf.Infinity, 0, 0);
public CharacterMotorMovement movement = new CharacterMotorMovement();
public enum MovementTransferOnJump {
None, // The jump is not affected by velocity of floor at all.
InitTransfer, // Jump gets its initial velocity from the floor, then gradualy comes to a stop.
PermaTransfer, // Jump gets its initial velocity from the floor, and keeps that velocity until landing.
PermaLocked // Jump is relative to the movement of the last touched floor and will move together with that floor.
// We will contain all the jumping related variables in one helper class for clarity.
[System.Serializable]
public class CharacterMotorJumping {
// Can the character jump?
public bool enabled =
// How high do we jump when pressing jump and letting go immediately
public float baseHeight = 1.0f;
// We add extraHeight units (meters) on top when holding the button down longer while jumping
public float extraHeight = 4.1f;
// How much does the character jump out perpendicular to the surface on walkable surfaces?
// 0 means a fully vertical jump and 1 means fully perpendicular.
public float perpAmount
// How much does the character jump out perpendicular to the surface on too steep surfaces?
// 0 means a fully vertical jump and 1 means fully perpendicular.
public float steepPerpAmount = 0.5f;
// For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!
// Are we jumping? (Initiated with jump button and not grounded yet)
// To see if we are just in the air (initiated by jumping OR falling) see the grounded variable.
[System.NonSerialized]
public bool jumping =
[System.NonSerialized]
public bool holdingJumpButton =
// the time we jumped at (Used to determine for how long to apply extra jump power after jumping.)
[System.NonSerialized]
public float lastStartTime = 0.0f;
[System.NonSerialized]
public float lastButtonDownTime = -100f;
[System.NonSerialized]
public Vector3 jumpDir = Vector3.
public CharacterMotorJumping
jumping = new CharacterMotorJumping();
[System.Serializable]
public class CharacterMotorMovingPlatform {
public bool enabled =
public MovementTransferOnJump movementTransfer = MovementTransferOnJump.PermaT
[System.NonSerialized]
public Transform hitP
[System.NonSerialized]
public Transform activeP
[System.NonSerialized]
public Vector3 activeLocalP
[System.NonSerialized]
public Vector3 activeGlobalP
[System.NonSerialized]
public Quaternion activeLocalR
[System.NonSerialized]
public Quaternion activeGlobalR
[System.NonSerialized]
public Matrix4x4 lastM
[System.NonSerialized]
public Vector3 platformV
[System.NonSerialized]
public bool newP
public CharacterMotorMovingPlatform movingPlatform
= new CharacterMotorMovingPlatform();
[System.Serializable]
public class CharacterMotorSliding {
// Does the character slide on too steep surfaces?
public bool enabled =
// How fast does the character slide on steep surfaces?
public float slidingSpeed
// How much can the player control the sliding direction?
// If the value is 0.5 the player can slide sideways with half the speed of the downwards sliding speed.
public float sidewaysControl = 1.0f;
// How much can the player influence the sliding speed?
// If the value is 0.5 the player can speed the sliding up to 150% or slow it down to 50%.
public float speedControl
public CharacterMotorSliding sliding
= new CharacterMotorSliding();
[System.NonSerialized]
public bool grounded =
[System.NonSerialized]
public Vector3 groundNormal = Vector3.
private Vector3
lastGroundNormal = Vector3.
private CharacterCon
void Awake () {
controller = GetComponent (); tr = }
private void UpdateFunction () { // We copy the actual velocity into a temporary variable that we can manipulate. Vector3 velocity
= movement.
// Update velocity based on input velocity = ApplyInputVelocityChange(velocity);
// Apply gravity and jumping force velocity = ApplyGravityAndJumping (velocity);
// Moving platform support Vector3 moveDistance
= Vector3. if (MoveWithPlatform()) { Vector3 newGlobalPoint
= movingPlatform.activePlatform.TransformPoint(movingPlatform.activeLocalPoint); moveDistance = (newGlobalPoint - movingPlatform.activeGlobalPoint); if (moveDistance != Vector3.zero) controller.Move(moveDistance);
// Support moving platform rotation as well:
Quaternion newGlobalRotation
= movingPlatform.activePlatform.rotation * movingPlatform.activeLocalR
Quaternion rotationDiff
= newGlobalRotation * Quaternion.Inverse(movingPlatform.activeGlobalRotation);
var yRotation = rotationDiff.eulerAngles.y;
if (yRotation != 0) {
// Prevent rotation of the local up vector
tr.Rotate(0, yRotation, 0);
// Save lastPosition for velocity calculation. Vector3 lastPosition
// We always want the movement to be framerate independent.
Multiplying by Time.deltaTime does this. Vector3 currentMovementOffset = velocity * Time.deltaT
// Find out how much we need to push towards the ground to avoid loosing grouning // when walking down a step or over a sharp change in slope. float pushDownOffset
= Mathf.Max(controller.stepOffset, new Vector3(currentMovementOffset.x, 0, currentMovementOffset.z).magnitude); if (grounded) currentMovementOffset -= pushDownOffset * Vector3.
// Reset variables that will be set by collision function movingPlatform.hitPlatform = groundNormal = Vector3.
// Move our character! movement.collisionFlags = controller.Move (currentMovementOffset);
movement.lastHitPoint = movement.hitP lastGroundNormal = groundN
if (movingPlatform.enabled && movingPlatform.activePlatform != movingPlatform.hitPlatform) { if (movingPlatform.hitPlatform != null) { movingPlatform.activePlatform = movingPlatform.hitP movingPlatform.lastMatrix = movingPlatform.hitPlatform.localToWorldM movingPlatform.newPlatform = } }
// Calculate the velocity based on the current and previous position. // This means our velocity will only be the amount the character actually moved as a result of collisions. Vector3 oldHVelocity
= new Vector3(velocity.x, 0, velocity.z); movement.velocity = (tr.position - lastPosition) / Time.deltaT Vector3 newHVelocity
= new Vector3(movement.velocity.x, 0, movement.velocity.z);
// The CharacterController can be moved in unwanted directions when colliding with things. // We want to prevent this from influencing the recorded velocity. if (oldHVelocity == Vector3.zero) { movement.velocity = new Vector3(0, movement.velocity.y, 0); } else { float projectedNewVelocity
= Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrM movement.velocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + movement.velocity.y * Vector3. }
if (movement.velocity.y & velocity.y - 0.001) { if (movement.velocity.y & 0) { // Something is forcing the CharacterController down faster than it should. // Ignore this movement.velocity.y = velocity.y; } else { // The upwards movement of the CharacterController has been blocked. // This is treated like a ceiling collision - stop further jumping here. jumping.holdingJumpButton = } }
// We were grounded but just loosed grounding if (grounded && !IsGroundedTest()) { grounded =
// Apply inertia from platform if (movingPlatform.enabled && (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer || movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer) ) { movement.frameVelocity = movingPlatform.platformV movement.velocity += movingPlatform.platformV }
SendMessage(&OnFall&, SendMessageOptions.DontRequireReceiver); // We pushed the character down to ensure it would stay on the ground if there was any. // But there wasn't so now we cancel the downwards offset to make the fall smoother. tr.position += pushDownOffset * Vector3. } // We were not grounded but just landed on something else if (!grounded && IsGroundedTest()) { grounded = jumping.jumping = SubtractNewPlatformVelocity();
SendMessage(&OnLand&, SendMessageOptions.DontRequireReceiver); }
// Moving platforms support if (MoveWithPlatform()) { // Use the center of the lower half sphere of the capsule as reference point. // This works best when the character is standing on moving tilting platforms. movingPlatform.activeGlobalPoint = tr.position + Vector3.up * (controller.center.y - controller.height*0.5f + controller.radius); movingPlatform.activeLocalPoint = movingPlatform.activePlatform.InverseTransformPoint(movingPlatform.activeGlobalPoint);
// Support moving platform rotation as well:
movingPlatform.activeGlobalRotation = tr.
movingPlatform.activeLocalRotation = Quaternion.Inverse(movingPlatform.activePlatform.rotation) * movingPlatform.activeGlobalR } }
void FixedUpdate () { if (movingPlatform.enabled) { if (movingPlatform.activePlatform != null) { if (!movingPlatform.newPlatform) { Vector3 lastVelocity
= movingPlatform.platformV
movingPlatform.platformVelocity = ( movingPlatform.activePlatform.localToWorldMatrix.MultiplyPoint3x4(movingPlatform.activeLocalPoint) - movingPlatform.lastMatrix.MultiplyPoint3x4(movingPlatform.activeLocalPoint) ) / Time.deltaT } movingPlatform.lastMatrix = movingPlatform.activePlatform.localToWorldM movingPlatform.newPlatform = } else { movingPlatform.platformVelocity = Vector3. } }
if (useFixedUpdate) UpdateFunction(); }
void Update () { if (!useFixedUpdate) UpdateFunction(); }
private Vector3 ApplyInputVelocityChange (Vector3 velocity) { if (!canControl) inputMoveDirection = Vector3.
// Find desired velocity Vector3 desiredV if (grounded && TooSteep()) { // The direction we're sliding in desiredVelocity = new Vector3(groundNormal.x, 0, groundNormal.z). // Find the input movement direction projected onto the sliding direction var projectedMoveDir = Vector3.Project(inputMoveDirection, desiredVelocity); // Add the sliding direction, the spped control, and the sideways control vectors desiredVelocity = desiredVelocity + projectedMoveDir * sliding.speedControl + (inputMoveDirection - projectedMoveDir) * sliding.sidewaysC // Multiply with the sliding speed desiredVelocity *= sliding.slidingS } else desiredVelocity = GetDesiredHorizontalVelocity();
if (movingPlatform.enabled && movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer) { desiredVelocity += movement.frameV desiredVelocity.y = 0; }
if (grounded) desiredVelocity = AdjustGroundVelocityToNormal(desiredVelocity, groundNormal); else velocity.y = 0;
// Enforce max velocity change float maxVelocityChange
= GetMaxAcceleration(grounded) * Time.deltaT Vector3 velocityChangeVector
= (desiredVelocity - velocity); if (velocityChangeVector.sqrMagnitude & maxVelocityChange * maxVelocityChange) { velocityChangeVector = velocityChangeVector.normalized * maxVelocityC } // If we're in the air and don't have control, don't apply any velocity change at all. // If we're on the ground and don't have control we do apply it - it will correspond to friction. if (grounded || canControl) velocity += velocityChangeV
if (grounded) { // When going uphill, the CharacterController will automatically move up by the needed amount. // Not moving it upwards manually prevent risk of lifting off from the ground. // When going downhill, DO move down manually, as gravity is not enough on steep hills. velocity.y = Mathf.Min(velocity.y, 0); } }
private Vector3 ApplyGravityAndJumping (Vector3 velocity) {
if (!inputJump || !canControl) { jumping.holdingJumpButton = jumping.lastButtonDownTime = -100; }
if (inputJump && jumping.lastButtonDownTime & 0 && canControl) jumping.lastButtonDownTime = Time.
if (grounded) velocity.y = Mathf.Min(0, velocity.y) - movement.gravity * Time.deltaT else { velocity.y = movement.velocity.y - movement.gravity * Time.deltaT
// When jumping up we don't apply gravity for some time when the user is holding the jump button. // This gives more control over jump height by pressing the button longer. if (jumping.jumping && jumping.holdingJumpButton) { // Calculate the duration that the extra jump force should have effect. // If we're still less than that duration after the jumping time, apply the force. if (Time.time & jumping.lastStartTime + jumping.extraHeight / CalculateJumpVerticalSpeed(jumping.baseHeight)) { // Negate the gravity we just applied, except we push in jumpDir rather than jump upwards. velocity += jumping.jumpDir * movement.gravity * Time.deltaT } }
// Make sure we don't fall any faster than maxFallSpeed. This gives our character a terminal velocity. velocity.y = Mathf.Max (velocity.y, -movement.maxFallSpeed); }
if (grounded) { // Jump only if the jump button was pressed down in the last 0.2 seconds. // We use this check instead of checking if it's pressed down right now // because players will often try to jump in the exact moment when hitting the ground after a jump // and if they hit the button a fraction of a second too soon and no new jump happens as a consequence, // it's confusing and it feels like the game is buggy. if (jumping.enabled && canControl && (Time.time - jumping.lastButtonDownTime & 0.2)) { grounded = jumping.jumping = jumping.lastStartTime = Time. jumping.lastButtonDownTime = -100; jumping.holdingJumpButton =
// Calculate the jumping direction if (TooSteep()) jumping.jumpDir = Vector3.Slerp(Vector3.up, groundNormal, jumping.steepPerpAmount); else jumping.jumpDir = Vector3.Slerp(Vector3.up, groundNormal, jumping.perpAmount);
// Apply the jumping force to the velocity. Cancel any vertical velocity first. velocity.y = 0; velocity += jumping.jumpDir * CalculateJumpVerticalSpeed (jumping.baseHeight);
// Apply inertia from platform if (movingPlatform.enabled && (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer || movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer) ) { movement.frameVelocity = movingPlatform.platformV velocity += movingPlatform.platformV }
SendMessage(&OnJump&, SendMessageOptions.DontRequireReceiver); } else { jumping.holdingJumpButton = } } }
void OnControllerColliderHit (ControllerColliderHit hit) { if (hit.normal.y & 0 && hit.normal.y & groundNormal.y && hit.moveDirection.y & 0) { if ((hit.point - movement.lastHitPoint).sqrMagnitude & 0.001 || lastGroundNormal == Vector3.zero) groundNormal = hit. else groundNormal = lastGroundN
movingPlatform.hitPlatform = hit.collider. movement.hitPoint = hit. movement.frameVelocity = Vector3. } }
private IEnumerator SubtractNewPlatformVelocity () { // When landing, subtract the velocity of the new ground from the character's velocity // since movement in ground is relative to the movement of the ground. if (movingPlatform.enabled && (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer || movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer) ) { // If we landed on a new platform, we have to wait for two FixedUpdates // before we know the velocity of the platform under the character if (movingPlatform.newPlatform) { Transform platform
= movingPlatform.activeP yield return new WaitForFixedUpdate(); yield return new WaitForFixedUpdate(); if (grounded && platform == movingPlatform.activePlatform) yield return 1; } movement.velocity -= movingPlatform.platformV } }
private bool MoveWithPlatform () { return ( movingPlatform.enabled && (grounded || movingPlatform.movementTransfer == MovementTransferOnJump.PermaLocked) && movingPlatform.activePlatform != null ); }
private Vector3 GetDesiredHorizontalVelocity () { // Find desired velocity Vector3 desiredLocalDirection
= tr.InverseTransformDirection(inputMoveDirection); float maxSpeed
= MaxSpeedInDirection(desiredLocalDirection); if (grounded) { // Modify max speed on slopes based on slope speed multiplier curve var movementSlopeAngle = Mathf.Asin(movement.velocity.normalized.y)
* Mathf.Rad2D maxSpeed *= movement.slopeSpeedMultiplier.Evaluate(movementSlopeAngle); } return tr.TransformDirection(desiredLocalDirection * maxSpeed); }
private Vector3 AdjustGroundVelocityToNormal (Vector3 hVelocity, Vector3 groundNormal) { Vector3 sideways
= Vector3.Cross(Vector3.up, hVelocity); return Vector3.Cross(sideways, groundNormal).normalized * hVelocity. }
private bool IsGroundedTest () { return (groundNormal.y & 0.01); }
float GetMaxAcceleration (bool grounded) { // Maximum acceleration on ground and in air if (grounded) return movement.maxGroundA else return movement.maxAirA }
float CalculateJumpVerticalSpeed (float targetJumpHeight) { // From the jump height and gravity we deduce the upwards speed // for the character to reach at the apex. return Mathf.Sqrt (2 * targetJumpHeight * movement.gravity); }
bool IsJumping () { return jumping. }
bool IsSliding () { return (grounded && sliding.enabled && TooSteep()); }
bool IsTouchingCeiling () { return (movement.collisionFlags & CollisionFlags.CollidedAbove) != 0; }
bool IsGrounded () { }
bool TooSteep () { return (groundNormal.y &= Mathf.Cos(controller.slopeLimit * Mathf.Deg2Rad)); }
Vector3 GetDirection () { return inputMoveD }
SetControllable (bool controllable) { canControl = }
// Project a direction onto elliptical quater segments based on forward, sideways, and backwards speed. // The function returns the length of the resulting vector. float MaxSpeedInDirection (Vector3 desiredMovementDirection) { if (desiredMovementDirection == Vector3.zero) return 0; else { float zAxisEllipseMultiplier = (desiredMovementDirection.z & 0 ? movement.maxForwardSpeed : movement.maxBackwardsSpeed) / movement.maxSidewaysS Vector3 temp = new Vector3(desiredMovementDirection.x, 0, desiredMovementDirection.z / zAxisEllipseMultiplier). float length = new Vector3(temp.x, 0, temp.z * zAxisEllipseMultiplier).magnitude * movement.maxSidewaysS } }
void SetVelocity (Vector3 velocity) { grounded = movement.velocity = movement.frameVelocity = Vector3. SendMessage(&OnExternalVelocity&); }
// Require a character controller to be attached to the same game object
//@script RequireComponent (CharacterController) //@script AddComponentMenu (&Character/Character Motor&)
接着把FPSInputControoler.js修改成C#语言。它用于第一人称控制角色移动,这里会监听主角按下的方向键最后传给CharacterMotor去计算模型的位置与旋转的角度。
FPSInputController.cs
[代码]c#/cpp/oc代码:
using UnityE
using System.C
[RequireComponent(typeof(CharacterMotor))]
[AddComponentMenu(&Character/FPS Input Controller&)]
public class FPSInputController : MonoBehaviour {
private CharacterM
// Use this for initialization
void Awake () {
motor = GetComponent(); }
// Update is called once per frame void Update () { // Get the input vector from kayboard or analog stick Vector3 directionVector = new Vector3(Input.GetAxis(&Horizontal&), 0, Input.GetAxis(&Vertical&));
if (directionVector != Vector3.zero) { // Get the length of the directon vector and then normalize it // Dividing by the length is cheaper than normalizing when we already have the length anyway var directionLength = directionVector. directionVector = directionVector / directionL
// Make sure the length is no bigger than 1 directionLength = Mathf.Min(1, directionLength);
// Make the input vector more sensitive towards the extremes and less sensitive in the middle // This makes it easier to control slow speeds when using analog sticks directionLength = directionLength * directionL
// Multiply the normalized direction vector by the modified length directionVector = directionVector * directionL }
// Apply the direction to the CharacterMotor motor.inputMoveDirection = transform.rotation * directionV motor.inputJump = Input.GetButton(&Jump&); }
MouseLook.cs因为已经是C#语言所以就不翻译了,然后是PlatFormInputController.cs 把它转成C#语言。它和FPSInputController一样会控制主角,但是它会更加精细的计算模型旋转的插值系数。
PlatformInputController.cs
[代码]c#/cpp/oc代码:
using UnityE
using System.C
[RequireComponent(typeof(CharacterController))]
[AddComponentMenu(&Character/Platform Input Controller&)]
public class PlatformInputController : MonoBehaviour {
public bool autoRotate =
public float
maxRotationSpeed = 360;
private CharacterM
// Use this for initialization
void Awake () {
motor = GetComponent(); }
// Update is called once per frame void Update () { // Get the input vector from kayboard or analog stick Vector3 directionVector = new Vector3(Input.GetAxis(&Horizontal&), Input.GetAxis(&Vertical&), 0);
if (directionVector != Vector3.zero) { // Get the length of the directon vector and then normalize it // Dividing by the length is cheaper than normalizing when we already have the length anyway var directionLength = directionVector. directionVector = directionVector / directionL
// Make sure the length is no bigger than 1 directionLength = Mathf.Min(1, directionLength);
// Make the input vector more sensitive towards the extremes and less sensitive in the middle // This makes it easier to control slow speeds when using analog sticks directionLength = directionLength * directionL
// Multiply the normalized direction vector by the modified length directionVector = directionVector * directionL }
// Rotate the input vector into camera space so up is camera's up and right is camera's right directionVector = Camera.main.transform.rotation * directionV
// Rotate input vector to be perpendicular to character's up vector var camToCharacterSpace = Quaternion.FromToRotation(-Camera.main.transform.forward, transform.up); directionVector = (camToCharacterSpace * directionVector);
// Apply the direction to the CharacterMotor motor.inputMoveDirection = directionV motor.inputJump = Input.GetButton(&Jump&);
// Set rotation to the move direction if (autoRotate && directionVector.sqrMagnitude & 0.01) { Vector3 newForward
= ConstantSlerp( transform.forward, directionVector, maxRotationSpeed * Time.deltaTime ); newForward = ProjectOntoPlane(newForward, transform.up); transform.rotation = Quaternion.LookRotation(newForward, transform.up); } }
Vector3 ProjectOntoPlane (Vector3 v, Vector3 normal) { return v - Vector3.Project(v, normal); }
Vector3 ConstantSlerp (Vector3 from, Vector3 to, float angle) { float value = Mathf.Min(1, angle / Vector3.Angle(from, to)); return Vector3.Slerp(from, to, value); }
接着是ThirdPersonCamera 我们把它改成C#语言。它主要控制第三人称视角时摄像机的控制。
ThirdPersonCamera.cs
[代码]c#/cpp/oc代码:
using UnityE
using System.C
public class ThirdPersonCamera : MonoBehaviour {
public Transform cameraT
private Transform _
public float distance = 7.0f;
public float height = 3.0f;
public float angularSmoothLag = 0.3f;
public float angularMaxSpeed = 15.0f;
public float heightSmoothLag = 0.3f;
public float snapSmoothLag = 0.2f;
public float snapMaxSpeed = 720.0f;
public float clampHeadPositionScreenSpace = 0.75f;
public float lockCameraTimeout = 0.2f;
private Vector3 headOffset = Vector3.
private Vector3 centerOffset = Vector3.
private float heightVelocity = 0.0f;
private float
angleVelocity = 0.0f;
private bool snap =
private ThirdPersonC
private float targetHeight = f;
void Awake ()
if(!cameraTransform && Camera.main)
cameraTransform = Camera.main.
if(!cameraTransform) {
Debug.Log(&Please assign a camera to the ThirdPersonCamera script.&);
if (_target)
controller = _target.GetComponent(); }
if (controller) { CharacterController characterController
= (CharacterController)_target. centerOffset = characterController.bounds.center - _target. headOffset = centerO headOffset.y = characterController.bounds.max.y - _target.position.y; } else Debug.Log(&Please assign a target to the camera that has a ThirdPersonController script attached.&);
Cut(_target, centerOffset); }
void DebugDrawStuff () { Debug.DrawLine(_target.position, _target.position + headOffset);
AngleDistance (float a , float b ) { a = Mathf.Repeat(a, 360); b = Mathf.Repeat(b, 360);
return Mathf.Abs(b - a); }
Apply (Transform dummyTarget, Vector3 dummyCenter) { // Early out if we don't have a target if (!controller)
Vector3 targetCenter = _target.position + centerO Vector3 targetHead = _target.position + headO
//DebugDrawStuff();
// Calculate the current & target rotation angles float originalTargetAngle = _target.eulerAngles.y; float currentAngle = cameraTransform.eulerAngles.y;
// Adjust real target angle when camera is locked float targetAngle = originalTargetA
// When pressing Fire2 (alt) the camera will snap to the target direction real quick. // It will stop snapping when it reaches the target if (Input.GetButton(&Fire2&)) snap =
if (snap) { // We are close to the target, so we can stop snapping now! if (AngleDistance (currentAngle, originalTargetAngle) & 3.0) snap =
currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, snapSmoothLag, snapMaxSpeed); } // Normal camera motion else {
if (controller.GetLockCameraTimer () & lockCameraTimeout) { targetAngle = currentA }
// Lock the camera when moving backwards! // * It is really confusing to do 180 degree spins when turning around. if (AngleDistance (currentAngle, targetAngle) & 160 && controller.IsMovingBackwards ()) targetAngle += 180;
currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, angularSmoothLag, angularMaxSpeed); }
// When jumping don't move camera upwards but only down! if (controller.IsJumping ()) { // We'd be moving the camera upwards, do that only if it's really high float newTargetHeight = targetCenter.y + if (newTargetHeight & targetHeight || newTargetHeight - targetHeight & 5) targetHeight = targetCenter.y + } // When walking always update the target height else { targetHeight = targetCenter.y + }
// Damp the height float currentHeight = cameraTransform.position.y; currentHeight = Mathf.SmoothDamp (currentHeight, targetHeight, ref heightVelocity, heightSmoothLag);
// Convert the angle into a rotation, by which we then reposition the camera Quaternion currentRotation = Quaternion.Euler (0, currentAngle, 0);
// Set the position of the camera on the x-z plane to: // distance meters behind the target cameraTransform.position = targetC cameraTransform.position += currentRotation * Vector3.back *
// Set the height of the camera
cameraTransform.position = new Vector3(cameraTransform.position.x,currentHeight,cameraTransform.position.z);
// Always look at the target SetUpRotation(targetCenter, targetHead); }
void LateUpdate () { Apply (transform, Vector3.zero); }
Cut (Transform dummyTarget , Vector3 dummyCenter) { float oldHeightSmooth = heightSmoothL float oldSnapMaxSpeed = snapMaxS float oldSnapSmooth = snapSmoothL
snapMaxSpeed = 10000; snapSmoothLag = 0.001f; heightSmoothLag = 0.001f;
snap = Apply (transform, Vector3.zero);
heightSmoothLag = oldHeightS snapMaxSpeed = oldSnapMaxS snapSmoothLag = oldSnapS }
void SetUpRotation (Vector3 centerPos,Vector3
headPos) { // Now it's getting hairy. The devil is in the details here, the big issue is jumping of course. // * When jumping up and down we don't want to center the guy in screen space. //
This is important to give a feel for how high you jump and avoiding large camera movements. // // * At the same time we dont want him to ever go out of screen and we want all rotations to be totally smooth. // // So here is what we will do: // // 1. We first find the rotation around the y axis. Thus he is always centered on the y-axis // 2. When grounded we make him be centered // 3. When jumping we keep the camera rotation but rotate the camera to get him back into view if his head is above some threshold // 4. When landing we smoothly interpolate towards centering him on screen Vector3 cameraPos = cameraTransform. Vector3 offsetToCenter = centerPos - cameraP
// Generate base rotation only around y-axis Quaternion yRotation = Quaternion.LookRotation(new Vector3(offsetToCenter.x, 0, offsetToCenter.z));
Vector3 relativeOffset = Vector3.forward * distance + Vector3.down * cameraTransform.rotation = yRotation * Quaternion.LookRotation(relativeOffset);
// Calculate the projected center position and top position in world space Ray centerRay = cameraTransform.camera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 1f)); Ray topRay = cameraTransform.camera.ViewportPointToRay(new Vector3(0.5f, clampHeadPositionScreenSpace, 1f));
Vector3 centerRayPos = centerRay.GetPoint(distance); Vector3 topRayPos = topRay.GetPoint(distance);
float centerToTopAngle = Vector3.Angle(centerRay.direction, topRay.direction);
float heightToAngle = centerToTopAngle / (centerRayPos.y - topRayPos.y);
float extraLookAngle = heightToAngle * (centerRayPos.y - centerPos.y); if (extraLookAngle & centerToTopAngle) { extraLookAngle = 0; } else { extraLookAngle = extraLookAngle - centerToTopA cameraTransform.rotation *= Quaternion.Euler(-extraLookAngle, 0, 0); } }
Vector3 GetCenterOffset () { return centerO }
最后一个是ThirdPersonController我们同样把它修改成C#语言,它主要更新第三人称视角控制主角时播放的各种动画,主角移动,等等。
ThirdPersonController.cs
[代码]c#/cpp/oc代码:
using UnityE
using System.C
[RequireComponent(typeof(CharacterController))]
public class ThirdPersonController : MonoBehaviour {
public AnimationClip idleA
public AnimationClip walkA
public AnimationClip runA
public AnimationClip jumpPoseA
public float walkMaxAnimationSpeed
public float trotMaxAnimationSpeed
public float runMaxAnimationSpeed
public float jumpAnimationSpeed
public float landAnimationSpeed
private Animation _
enum CharacterState
Walking = 1,
Trotting = 2,
Running = 3,
Jumping = 4,
private CharacterState _characterS
// The speed when walking
float walkSpeed = 2.0f;
// after trotAfterSeconds of walking we trot with trotSpeed
float trotSpeed = 4.0f;
// when pressing &Fire3& button (cmd) we start running
float runSpeed = 6.0f;
float inAirControlAcceleration = 3.0f;
// How high do we jump when pressing jump and letting go immediately
float jumpHeight = 0.5f;
// The gravity for the character
float gravity = 20.0f;
// The gravity in controlled descent mode
float speedSmoothing = 10.0f;
float rotateSpeed = 500.0f;
float trotAfterSeconds = 3.0f;
bool canJump =
private float jumpRepeatTime = 0.05f;
private float jumpTimeout = 0.15f;
private float groundedTimeout = 0.25f;
// The camera doesnt start following the target immediately but waits for a split second to avoid too much waving around.
private float lockCameraTimer = 0.0f;
// The current move direction in x-z
private Vector3 moveDirection = Vector3.
// The current vertical speed
private float verticalSpeed = 0.0f;
// The current x-z move speed
private float moveSpeed = 0.0f;
// The last collision flags returned from controller.Move
private CollisionFlags collisionF
// Are we jumping? (Initiated with jump button and not grounded yet)
private bool jumping =
private bool jumpingReachedApex =
// Are we moving backwards (This locks the camera to not do a 180 degree spin)
private bool movingBack =
// Is the user pressing any keys?
private bool isMoving =
// When did the user start walking (Used for going into trot after a while)
private float walkTimeStart = 0.0f;
// Last time the jump button was clicked down
private float lastJumpButtonTime = -10.0f;
// Last time we performed a jump
private float lastJumpTime = -1.0f;
// the height we jumped from (Used to determine for how long to apply extra jump power after jumping.)
private float lastJumpStartHeight = 0.0f;
private Vector3 inAirVelocity = Vector3.
private float lastGroundedTime = 0.0f;
private bool isControllable =
void Awake ()
moveDirection = transform.TransformDirection(Vector3.forward);
_animation = GetComponent(); if(!_animation) Debug.Log(&The character you would like to control doesn't have animations. Moving her might look weird.&);
/* public var idleAnimation : AnimationC public var walkAnimation : AnimationC public var runAnimation : AnimationC public var jumpPoseAnimation : AnimationC */ if(!idleAnimation) { _animation = Debug.Log(&No idle animation found. Turning off animations.&); } if(!walkAnimation) { _animation = Debug.Log(&No walk animation found. Turning off animations.&); } if(!runAnimation) { _animation = Debug.Log(&No run animation found. Turning off animations.&); } if(!jumpPoseAnimation && canJump) { _animation = Debug.Log(&No jump animation found and the character has canJump enabled. Turning off animations.&); }
void UpdateSmoothedMovementDirection () { Transform cameraTransform = Camera.main. bool grounded = IsGrounded();
// Forward vector relative to the camera along the x-z plane Vector3 forward = cameraTransform.TransformDirection(Vector3.forward); forward.y = 0; forward = forward.
// Right vector relative to the camera // Always orthogonal to the forward vector Vector3 right = new Vector3(forward.z, 0, -forward.x);
float v = Input.GetAxisRaw(&Vertical&); float h = Input.GetAxisRaw(&Horizontal&);
// Are we moving backwards or looking backwards if (v & -0.2f) movingBack = else movingBack =
bool wasMoving = isM isMoving = Mathf.Abs (h) & 0.1f || Mathf.Abs (v) & 0.1f;
// Target direction relative to the camera Vector3 targetDirection = h * right + v *
// Grounded controls if (grounded) { // Lock camera for short period when transitioning moving & standing still lockCameraTimer += Time.deltaT if (isMoving != wasMoving) lockCameraTimer = 0.0f;
// We store speed and direction seperately, // so that when the character stands still we still have a valid forward direction // moveDirection is always normalized, and we only update it if there is user input. if (targetDirection != Vector3.zero) { // If we are really slow, just snap to the target direction if (moveSpeed & walkSpeed * 0.9f && grounded) { moveDirection = targetDirection. } // Otherwise smoothly turn towards it else { moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000);
moveDirection = moveDirection. } }
// Smooth the speed based on the current target direction float curSmooth = speedSmoothing * Time.deltaT
// Choose target speed //* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways float targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0f);
_characterState = CharacterState.I
// Pick speed modifier if (Input.GetKey (KeyCode.LeftShift) | Input.GetKey (KeyCode.RightShift)) { targetSpeed *= runS _characterState = CharacterState.R } else if (Time.time - trotAfterSeconds & walkTimeStart) { targetSpeed *= trotS _characterState = CharacterState.T } else { targetSpeed *= walkS _characterState = CharacterState.W }
moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth);
// Reset walk time start when we slow down if (moveSpeed & walkSpeed * 0.3f) walkTimeStart = Time. } // In air controls else { // Lock camera while in air if (jumping) lockCameraTimer = 0.0f;
if (isMoving) inAirVelocity += targetDirection.normalized * Time.deltaTime * inAirControlA }
void ApplyJumping () { // Prevent jumping too fast after each other if (lastJumpTime + jumpRepeatTime & Time.time)
if (IsGrounded()) { // Jump // - Only when pressing the button down // - With a timeout so you can press the button slightly before landing if (canJump && Time.time & lastJumpButtonTime + jumpTimeout) { verticalSpeed = CalculateJumpVerticalSpeed (jumpHeight); SendMessage(&DidJump&, SendMessageOptions.DontRequireReceiver); } } }
void ApplyGravity () { if (isControllable)// don't move player at all if not controllable. { // Apply gravity bool jumpButton = Input.GetButton(&Jump&);
// When we reach the apex of the jump we send out a message if (jumping && !jumpingReachedApex && verticalSpeed &= 0.0f) { jumpingReachedApex = SendMessage(&DidJumpReachApex&, SendMessageOptions.DontRequireReceiver); }
if (IsGrounded ()) verticalSpeed = 0.0f; else verticalSpeed -= gravity * Time.deltaT } }
float CalculateJumpVerticalSpeed (float targetJumpHeight) { // From the jump height and gravity we deduce the upwards speed // for the character to reach at the apex. return Mathf.Sqrt(2 * targetJumpHeight * gravity); }
DidJump () { jumping = jumpingReachedApex = lastJumpTime = Time. lastJumpStartHeight = transform.position.y; lastJumpButtonTime = -10;
_characterState = CharacterState.J }
Update() {
if (!isControllable) { // kill all inputs if not controllable. Input.ResetInputAxes(); }
if (Input.GetButtonDown (&Jump&)) { lastJumpButtonTime = Time. }
UpdateSmoothedMovementDirection();
// Apply gravity // - extra power jump modifies gravity // - controlledDescent mode modifies gravity ApplyGravity ();
// Apply jumping logic ApplyJumping ();
// Calculate actual motion Vector3 movement = moveDirection * moveSpeed + new Vector3 (0, verticalSpeed, 0) + inAirV movement *= Time.deltaT
// Move the controller CharacterController controller = GetComponent(); collisionFlags = controller.Move(movement);
// ANIMATION sector if(_animation) { if(_characterState == CharacterState.Jumping) { if(!jumpingReachedApex) { _animation[jumpPoseAnimation.name].speed = jumpAnimationS _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampF _animation.CrossFade(jumpPoseAnimation.name); } else { _animation[jumpPoseAnimation.name].speed = -landAnimationS _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampF _animation.CrossFade(jumpPoseAnimation.name); } } else { if(controller.velocity.sqrMagnitude & 0.1f) { _animation.CrossFade(idleAnimation.name); } else { if(_characterState == CharacterState.Running) { _animation[runAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, runMaxAnimationSpeed); _animation.CrossFade(runAnimation.name); } else if(_characterState == CharacterState.Trotting) { _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, trotMaxAnimationSpeed); _animation.CrossFade(walkAnimation.name); } else if(_characterState == CharacterState.Walking) { _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, walkMaxAnimationSpeed); _animation.CrossFade(walkAnimation.name); }
} } } // ANIMATION sector
// Set rotation to the move direction if (IsGrounded()) {
transform.rotation = Quaternion.LookRotation(moveDirection);
} else { Vector3 xzMove = xzMove.y = 0; if (xzMove.sqrMagnitude & 0.001f) { transform.rotation = Quaternion.LookRotation(xzMove); } }
// We are in jump mode but just became grounded if (IsGrounded()) { lastGroundedTime = Time. inAirVelocity = Vector3. if (jumping) { jumping = SendMessage(&DidLand&, SendMessageOptions.DontRequireReceiver); } } }
OnControllerColliderHit (ControllerColliderHit hit ) { //Debug.DrawRay(hit.point, hit.normal); if (hit.moveDirection.y & 0.01f) }
float GetSpeed () { return moveS }
public bool IsJumping () { }
bool IsGrounded () { return (collisionFlags & CollisionFlags.CollidedBelow) != 0; }
Vector3 GetDirection () { return moveD }
public bool IsMovingBackwards () { return movingB }
public float GetLockCameraTimer () { return lockCameraT }
bool IsMoving () { return Mathf.Abs(Input.GetAxisRaw(&Vertical&)) + Mathf.Abs(Input.GetAxisRaw(&Horizontal&)) & 0.5f; }
bool HasJumpReachedApex () { return jumpingReachedA }
bool IsGroundedWithTimeout () { return lastGroundedTime + groundedTimeout & Time. }
void Reset () { gameObject.tag = &Player&; }
最后我们用修改的脚本来控制第三人称视角主角的移动,直接上图大家仔细看看监测面板视图中的脚本绑定,这里问题不大,图片如果看不清点击即可查看大图。
498)this.width=498;' onmousewheel = 'javascript:return big(this)' width="451" height="252" src="/files/uploadimg/2511.png" alt="" />
脚本终于全部翻译完毕,其实在开发中大家可以去丰富这些脚本,灵活的运用它们。感谢Unity圣典的站长专门花钱买模型让我来写教程与录制视频教程。
下回写点游戏AI的东西,让游戏中的怪物在更加聪明点吧。
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&的更多文章
本书是一部应运而生的实用指南,讲述了如何构建出能在Apple Stor
网友评论TOP5
既然强大的Android Studio来了,有什么理由不去用呢?
本系列视频教程由正益无线与51CTO共同推出,目的是让
本系列视频教程由正益无线与51CTO共同推出,目的是让
本系列视频教程由正益无线与51CTO共同推出,目的是让
随着互联网的迅速发展,几乎所有工具软件和程序语言都支持的正则表达式也变得越来越强大和易于使用。本书是讲解正则表达式的经典
Windows Phone专家
Android开发专家
51CTO旗下网站}

我要回帖

更多关于 输入字母组成单词 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信