1. using System;
  2. using System.Collections;
  3. using UnityEngine;
  4.  
  5. // This class just convert from CharacterMotor.js to C#
  6.  
  7. [RequireComponent(typeof(CharacterController))]
  8. [AddComponentMenu("Character/Character Motor")]
  9. public class CharacterMotor : MonoBehaviour
  10. {
  11. bool canControl = true;
  12. bool useFixedUpdate = true;
  13.  
  14. // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
  15. // Very handy for organization!
  16.  
  17. // The current global direction we want the character to move in.
  18. [NonSerialized]
  19. public Vector3 inputMoveDirection = Vector3.zero;
  20.  
  21. // Is the jump button held down? We use this interface instead of checking
  22. // for the jump button directly so this script can also be used by AIs.
  23. [NonSerialized]
  24. public bool inputJump = false;
  25.  
  26. class CharacterMotorMovement
  27. {
  28. // The maximum horizontal speed when moving
  29. public float maxForwardSpeed = 10.0f;
  30. public float maxSidewaysSpeed = 10.0f;
  31. public float maxBackwardsSpeed = 10.0f;
  32.  
  33. // Curve for multiplying speed based on slope (negative = downwards)
  34. public AnimationCurve slopeSpeedMultiplier = new AnimationCurve(new Keyframe(-, ), new Keyframe(, ), new Keyframe(, ));
  35.  
  36. // How fast does the character change speeds? Higher is faster.
  37. public float maxGroundAcceleration = 30.0f;
  38. public float maxAirAcceleration = 20.0f;
  39.  
  40. // The gravity for the character
  41. public float gravity = 10.0f;
  42. public float maxFallSpeed = 20.0f;
  43.  
  44. // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
  45. // Very handy for organization!
  46.  
  47. // The last collision flags returned from controller.Move
  48. [NonSerialized]
  49. public CollisionFlags collisionFlags;
  50.  
  51. // We will keep track of the character's current velocity,
  52. [NonSerialized]
  53. public Vector3 velocity;
  54.  
  55. // This keeps track of our current velocity while we're not grounded
  56. [NonSerialized]
  57. public Vector3 frameVelocity = Vector3.zero;
  58.  
  59. [NonSerialized]
  60. public Vector3 hitPoint = Vector3.zero;
  61.  
  62. [NonSerialized]
  63. public Vector3 lastHitPoint = new Vector3(Mathf.Infinity, , );
  64. }
  65.  
  66. CharacterMotorMovement movement = new CharacterMotorMovement();
  67. enum MovementTransferOnJump
  68. {
  69. None, // The jump is not affected by velocity of floor at all.
  70. InitTransfer, // Jump gets its initial velocity from the floor, then gradualy comes to a stop.
  71. PermaTransfer, // Jump gets its initial velocity from the floor, and keeps that velocity until landing.
  72. PermaLocked // Jump is relative to the movement of the last touched floor and will move together with that floor.
  73. }
  74.  
  75. // We will contain all the jumping related variables in one helper class for clarity.
  76. class CharacterMotorJumping
  77. {
  78. // Can the character jump?
  79. public bool enabled = true;
  80.  
  81. // How high do we jump when pressing jump and letting go immediately
  82. public float baseHeight = 1.6f;
  83.  
  84. // We add extraHeight units (meters) on top when holding the button down longer while jumping
  85. public float extraHeight = 1.6f;
  86.  
  87. // How much does the character jump out perpendicular to the surface on walkable surfaces?
  88. // 0 means a fully vertical jump and 1 means fully perpendicular.
  89. public float perpAmount = 2.0f;
  90.  
  91. // How much does the character jump out perpendicular to the surface on too steep surfaces?
  92. // 0 means a fully vertical jump and 1 means fully perpendicular.
  93. public float steepPerpAmount = 1.5f;
  94.  
  95. // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
  96. // Very handy for organization!
  97.  
  98. // Are we jumping? (Initiated with jump button and not grounded yet)
  99. // To see if we are just in the air (initiated by jumping OR falling) see the grounded variable.
  100. [NonSerialized]
  101. public bool jumping = false;
  102.  
  103. [NonSerialized]
  104. public bool holdingJumpButton = false;
  105.  
  106. // the time we jumped at (Used to determine for how long to apply extra jump power after jumping.)
  107. [NonSerialized]
  108. public float lastStartTime = 0.0f;
  109.  
  110. [NonSerialized]
  111. public float lastButtonDownTime = -100f;
  112.  
  113. [NonSerialized]
  114. public Vector3 jumpDir = Vector3.up;
  115. }
  116.  
  117. CharacterMotorJumping jumping = new CharacterMotorJumping();
  118. class CharacterMotorMovingPlatform
  119. {
  120. public bool enabled = true;
  121.  
  122. public MovementTransferOnJump movementTransfer = MovementTransferOnJump.PermaTransfer;
  123.  
  124. [NonSerialized]
  125. public Transform hitPlatform;
  126.  
  127. [NonSerialized]
  128. public Transform activePlatform;
  129.  
  130. [NonSerialized]
  131. public Vector3 activeLocalPoint;
  132.  
  133. [NonSerialized]
  134. public Vector3 activeGlobalPoint;
  135.  
  136. [NonSerialized]
  137. public Quaternion activeLocalRotation;
  138.  
  139. [NonSerialized]
  140. public Quaternion activeGlobalRotation;
  141.  
  142. [NonSerialized]
  143. public Matrix4x4 lastMatrix;
  144.  
  145. [NonSerialized]
  146. public Vector3 platformVelocity;
  147.  
  148. [NonSerialized]
  149. public bool newPlatform;
  150. }
  151.  
  152. CharacterMotorMovingPlatform movingPlatform = new CharacterMotorMovingPlatform();
  153.  
  154. class CharacterMotorSliding
  155. {
  156. // Does the character slide on too steep surfaces?
  157. public bool enabled = true;
  158.  
  159. // How fast does the character slide on steep surfaces?
  160. public float slidingSpeed = 15f;
  161.  
  162. // How much can the player control the sliding direction?
  163. // If the value is 0.5 the player can slide sideways with half the speed of the downwards sliding speed.
  164. public float sidewaysControl = 1.0f;
  165.  
  166. // How much can the player influence the sliding speed?
  167. // If the value is 0.5 the player can speed the sliding up to 150% or slow it down to 50%.
  168. public float speedControl = 0.4f;
  169. }
  170.  
  171. CharacterMotorSliding sliding = new CharacterMotorSliding();
  172.  
  173. [NonSerialized]
  174. public bool grounded = true;
  175.  
  176. [NonSerialized]
  177. public Vector3 groundNormal = Vector3.zero;
  178.  
  179. Vector3 lastGroundNormal = Vector3.zero;
  180.  
  181. Transform tr;
  182.  
  183. CharacterController controller;
  184.  
  185. void Awake()
  186. {
  187. controller = gameObject.GetComponent<CharacterController>();
  188. tr = transform;
  189. }
  190.  
  191. private void UpdateFunction()
  192. {
  193. // We copy the actual velocity into a temporary variable that we can manipulate.
  194. var velocity = movement.velocity;
  195.  
  196. // Update velocity based on input
  197. velocity = ApplyInputVelocityChange(velocity);
  198.  
  199. // Apply gravity and jumping force
  200. velocity = ApplyGravityAndJumping(velocity);
  201.  
  202. // Moving platform support
  203. var moveDistance = Vector3.zero;
  204. if (MoveWithPlatform())
  205. {
  206. var newGlobalPoint = movingPlatform.activePlatform.TransformPoint(movingPlatform.activeLocalPoint);
  207. moveDistance = (newGlobalPoint - movingPlatform.activeGlobalPoint);
  208. if (moveDistance != Vector3.zero)
  209. controller.Move(moveDistance);
  210.  
  211. // Support moving platform rotation as well:
  212. var newGlobalRotation = movingPlatform.activePlatform.rotation * movingPlatform.activeLocalRotation;
  213. var rotationDiff = newGlobalRotation * Quaternion.Inverse(movingPlatform.activeGlobalRotation);
  214.  
  215. var yRotation = rotationDiff.eulerAngles.y;
  216. if (yRotation != )
  217. {
  218. // Prevent rotation of the local up vector
  219. tr.Rotate(, yRotation, );
  220. }
  221. }
  222.  
  223. // Save lastPosition for velocity calculation.
  224. var lastPosition = tr.position;
  225.  
  226. // We always want the movement to be framerate independent. Multiplying by Time.deltaTime does this.
  227. var currentMovementOffset = velocity * Time.deltaTime;
  228.  
  229. // Find out how much we need to push towards the ground to avoid loosing grouning
  230. // when walking down a step or over a sharp change in slope.
  231. var pushDownOffset = Mathf.Max(controller.stepOffset, new Vector3(currentMovementOffset.x, , currentMovementOffset.z).magnitude);
  232. if (grounded)
  233. currentMovementOffset -= pushDownOffset * Vector3.up;
  234.  
  235. // Reset variables that will be set by collision function
  236. movingPlatform.hitPlatform = null;
  237. groundNormal = Vector3.zero;
  238.  
  239. // Move our character!
  240. movement.collisionFlags = controller.Move(currentMovementOffset);
  241.  
  242. movement.lastHitPoint = movement.hitPoint;
  243. lastGroundNormal = groundNormal;
  244.  
  245. if (movingPlatform.enabled && movingPlatform.activePlatform != movingPlatform.hitPlatform)
  246. {
  247. if (movingPlatform.hitPlatform != null)
  248. {
  249. movingPlatform.activePlatform = movingPlatform.hitPlatform;
  250. movingPlatform.lastMatrix = movingPlatform.hitPlatform.localToWorldMatrix;
  251. movingPlatform.newPlatform = true;
  252. }
  253. }
  254.  
  255. // Calculate the velocity based on the current and previous position.
  256. // This means our velocity will only be the amount the character actually moved as a result of collisions.
  257. var oldHVelocity = new Vector3(velocity.x, , velocity.z);
  258. movement.velocity = (tr.position - lastPosition) / Time.deltaTime;
  259. var newHVelocity = new Vector3(movement.velocity.x, , movement.velocity.z);
  260.  
  261. // The CharacterController can be moved in unwanted directions when colliding with things.
  262. // We want to prevent this from influencing the recorded velocity.
  263. if (oldHVelocity == Vector3.zero)
  264. {
  265. movement.velocity = new Vector3(, movement.velocity.y, );
  266. }
  267. else
  268. {
  269. var projectedNewVelocity = Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrMagnitude;
  270. movement.velocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + movement.velocity.y * Vector3.up;
  271. }
  272.  
  273. if (movement.velocity.y < velocity.y - 0.001)
  274. {
  275. if (movement.velocity.y < )
  276. {
  277. // Something is forcing the CharacterController down faster than it should.
  278. // Ignore this
  279. movement.velocity.y = velocity.y;
  280. }
  281. else
  282. {
  283. // The upwards movement of the CharacterController has been blocked.
  284. // This is treated like a ceiling collision - stop further jumping here.
  285. jumping.holdingJumpButton = false;
  286. }
  287. }
  288.  
  289. // We were grounded but just loosed grounding
  290. if (grounded && !IsGroundedTest())
  291. {
  292. grounded = false;
  293.  
  294. // Apply inertia from platform
  295. if (movingPlatform.enabled &&
  296. (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||
  297. movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)
  298. )
  299. {
  300. movement.frameVelocity = movingPlatform.platformVelocity;
  301. movement.velocity += movingPlatform.platformVelocity;
  302. }
  303.  
  304. SendMessage("OnFall", SendMessageOptions.DontRequireReceiver);
  305. // We pushed the character down to ensure it would stay on the ground if there was any.
  306. // But there wasn't so now we cancel the downwards offset to make the fall smoother.
  307. tr.position += pushDownOffset * Vector3.up;
  308. }
  309. // We were not grounded but just landed on something
  310. else if (!grounded && IsGroundedTest())
  311. {
  312. grounded = true;
  313. jumping.jumping = false;
  314. SubtractNewPlatformVelocity();
  315.  
  316. SendMessage("OnLand", SendMessageOptions.DontRequireReceiver);
  317. }
  318.  
  319. // Moving platforms support
  320. if (MoveWithPlatform())
  321. {
  322. // Use the center of the lower half sphere of the capsule as reference point.
  323. // This works best when the character is standing on moving tilting platforms.
  324. movingPlatform.activeGlobalPoint = tr.position + Vector3.up * (controller.center.y - (controller.height * 0.5f) + controller.radius);
  325. movingPlatform.activeLocalPoint = movingPlatform.activePlatform.InverseTransformPoint(movingPlatform.activeGlobalPoint);
  326.  
  327. // Support moving platform rotation as well:
  328. movingPlatform.activeGlobalRotation = tr.rotation;
  329. movingPlatform.activeLocalRotation = Quaternion.Inverse(movingPlatform.activePlatform.rotation) * movingPlatform.activeGlobalRotation;
  330. }
  331. }
  332.  
  333. void FixedUpdate()
  334. {
  335. if (movingPlatform.enabled)
  336. {
  337. if (movingPlatform.activePlatform != null)
  338. {
  339. if (!movingPlatform.newPlatform)
  340. {
  341. movingPlatform.platformVelocity = (
  342. movingPlatform.activePlatform.localToWorldMatrix.MultiplyPoint3x4(movingPlatform.activeLocalPoint)
  343. - movingPlatform.lastMatrix.MultiplyPoint3x4(movingPlatform.activeLocalPoint)
  344. ) / Time.deltaTime;
  345. }
  346. movingPlatform.lastMatrix = movingPlatform.activePlatform.localToWorldMatrix;
  347. movingPlatform.newPlatform = false;
  348. }
  349. else
  350. {
  351. movingPlatform.platformVelocity = Vector3.zero;
  352. }
  353. }
  354.  
  355. if (useFixedUpdate)
  356. UpdateFunction();
  357. }
  358.  
  359. void Update()
  360. {
  361. if (!useFixedUpdate)
  362. UpdateFunction();
  363. }
  364.  
  365. Vector3 ApplyInputVelocityChange(Vector3 velocity)
  366. {
  367. if (!canControl)
  368. inputMoveDirection = Vector3.zero;
  369.  
  370. // Find desired velocity
  371. Vector3 desiredVelocity;
  372. if (grounded && TooSteep())
  373. {
  374. // The direction we're sliding in
  375. desiredVelocity = new Vector3(groundNormal.x, , groundNormal.z).normalized;
  376. // Find the input movement direction projected onto the sliding direction
  377. var projectedMoveDir = Vector3.Project(inputMoveDirection, desiredVelocity);
  378. // Add the sliding direction, the spped control, and the sideways control vectors
  379. desiredVelocity = desiredVelocity + projectedMoveDir * sliding.speedControl + (inputMoveDirection - projectedMoveDir) * sliding.sidewaysControl;
  380. // Multiply with the sliding speed
  381. desiredVelocity *= sliding.slidingSpeed;
  382. }
  383. else
  384. desiredVelocity = GetDesiredHorizontalVelocity();
  385.  
  386. if (movingPlatform.enabled && movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)
  387. {
  388. desiredVelocity += movement.frameVelocity;
  389. desiredVelocity.y = ;
  390. }
  391.  
  392. if (grounded)
  393. desiredVelocity = AdjustGroundVelocityToNormal(desiredVelocity, groundNormal);
  394. else
  395. velocity.y = ;
  396.  
  397. // Enforce max velocity change
  398. var maxVelocityChange = GetMaxAcceleration(grounded) * Time.deltaTime;
  399. var velocityChangeVector = (desiredVelocity - velocity);
  400. if (velocityChangeVector.sqrMagnitude > maxVelocityChange * maxVelocityChange)
  401. {
  402. velocityChangeVector = velocityChangeVector.normalized * maxVelocityChange;
  403. }
  404. // If we're in the air and don't have control, don't apply any velocity change at all.
  405. // If we're on the ground and don't have control we do apply it - it will correspond to friction.
  406. if (grounded || canControl)
  407. velocity += velocityChangeVector;
  408.  
  409. if (grounded)
  410. {
  411. // When going uphill, the CharacterController will automatically move up by the needed amount.
  412. // Not moving it upwards manually prevent risk of lifting off from the ground.
  413. // When going downhill, DO move down manually, as gravity is not enough on steep hills.
  414. velocity.y = Mathf.Min(velocity.y, );
  415. }
  416.  
  417. return velocity;
  418. }
  419.  
  420. Vector3 ApplyGravityAndJumping(Vector3 velocity)
  421. {
  422. if (!inputJump || !canControl)
  423. {
  424. jumping.holdingJumpButton = false;
  425. jumping.lastButtonDownTime = -;
  426. }
  427.  
  428. if (inputJump && jumping.lastButtonDownTime < && canControl)
  429. jumping.lastButtonDownTime = Time.time;
  430.  
  431. if (grounded)
  432. velocity.y = Mathf.Min(, velocity.y) - movement.gravity * Time.deltaTime;
  433. else
  434. {
  435. velocity.y = movement.velocity.y - movement.gravity * Time.deltaTime * ;
  436.  
  437. // When jumping up we don't apply gravity for some time when the user is holding the jump button.
  438. // This gives more control over jump height by pressing the button longer.
  439. if (jumping.jumping && jumping.holdingJumpButton)
  440. {
  441. // Calculate the duration that the extra jump force should have effect.
  442. // If we're still less than that duration after the jumping time, apply the force.
  443. if (Time.time < jumping.lastStartTime + jumping.extraHeight / CalculateJumpVerticalSpeed(jumping.baseHeight))
  444. {
  445. // Negate the gravity we just applied, except we push in jumpDir rather than jump upwards.
  446. velocity += jumping.jumpDir * movement.gravity * Time.deltaTime;
  447. }
  448. }
  449.  
  450. // Make sure we don't fall any faster than maxFallSpeed. This gives our character a terminal velocity.
  451. velocity.y = Mathf.Max(velocity.y, -movement.maxFallSpeed);
  452. }
  453.  
  454. if (grounded)
  455. {
  456. // Jump only if the jump button was pressed down in the last 0.2 seconds.
  457. // We use this check instead of checking if it's pressed down right now
  458. // because players will often try to jump in the exact moment when hitting the ground after a jump
  459. // and if they hit the button a fraction of a second too soon and no new jump happens as a consequence,
  460. // it's confusing and it feels like the game is buggy.
  461. if (jumping.enabled && canControl && (Time.time - jumping.lastButtonDownTime < 0.2))
  462. {
  463. grounded = false;
  464. jumping.jumping = true;
  465. jumping.lastStartTime = Time.time;
  466. jumping.lastButtonDownTime = -;
  467. jumping.holdingJumpButton = true;
  468.  
  469. // Calculate the jumping direction
  470. if (TooSteep())
  471. jumping.jumpDir = Vector3.Slerp(Vector3.up, groundNormal, jumping.steepPerpAmount);
  472. else
  473. jumping.jumpDir = Vector3.Slerp(Vector3.up, groundNormal, jumping.perpAmount);
  474.  
  475. // Apply the jumping force to the velocity. Cancel any vertical velocity first.
  476. velocity.y = ;
  477. velocity += jumping.jumpDir * CalculateJumpVerticalSpeed(jumping.baseHeight);
  478.  
  479. // Apply inertia from platform
  480. if (movingPlatform.enabled &&
  481. (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||
  482. movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)
  483. )
  484. {
  485. movement.frameVelocity = movingPlatform.platformVelocity;
  486. velocity += movingPlatform.platformVelocity;
  487. }
  488.  
  489. SendMessage("OnJump", SendMessageOptions.DontRequireReceiver);
  490. }
  491. else
  492. {
  493. jumping.holdingJumpButton = false;
  494. }
  495. }
  496.  
  497. return velocity;
  498. }
  499.  
  500. void OnControllerColliderHit(ControllerColliderHit hit)
  501. {
  502. if (hit.normal.y > && hit.normal.y > groundNormal.y && hit.moveDirection.y < )
  503. {
  504. if ((hit.point - movement.lastHitPoint).sqrMagnitude > 0.001 || lastGroundNormal == Vector3.zero)
  505. groundNormal = hit.normal;
  506. else
  507. groundNormal = lastGroundNormal;
  508.  
  509. movingPlatform.hitPlatform = hit.collider.transform;
  510. movement.hitPoint = hit.point;
  511. movement.frameVelocity = Vector3.zero;
  512. }
  513. }
  514.  
  515. private IEnumerable SubtractNewPlatformVelocity()
  516. {
  517. // When landing, subtract the velocity of the new ground from the character's velocity
  518. // since movement in ground is relative to the movement of the ground.
  519. if (movingPlatform.enabled &&
  520. (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||
  521. movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)
  522. )
  523. {
  524. // If we landed on a new platform, we have to wait for two FixedUpdates
  525. // before we know the velocity of the platform under the character
  526. if (movingPlatform.newPlatform)
  527. {
  528. var platform = movingPlatform.activePlatform;
  529. yield return new WaitForFixedUpdate();
  530. yield return new WaitForFixedUpdate();
  531. if (grounded && platform == movingPlatform.activePlatform)
  532. yield return ;
  533. }
  534. movement.velocity -= movingPlatform.platformVelocity;
  535. }
  536. }
  537.  
  538. private bool MoveWithPlatform()
  539. {
  540. return movingPlatform.enabled
  541. && (grounded || movingPlatform.movementTransfer == MovementTransferOnJump.PermaLocked)
  542. && movingPlatform.activePlatform != null;
  543. }
  544.  
  545. private Vector3 GetDesiredHorizontalVelocity()
  546. {
  547. // Find desired velocity
  548. var desiredLocalDirection = tr.InverseTransformDirection(inputMoveDirection);
  549. var maxSpeed = MaxSpeedInDirection(desiredLocalDirection);
  550. if (grounded)
  551. {
  552. // Modify max speed on slopes based on slope speed multiplier curve
  553. var movementSlopeAngle = Mathf.Asin(movement.velocity.normalized.y) * Mathf.Rad2Deg;
  554. maxSpeed *= movement.slopeSpeedMultiplier.Evaluate(movementSlopeAngle);
  555. }
  556. return tr.TransformDirection(desiredLocalDirection * maxSpeed);
  557. }
  558.  
  559. private Vector3 AdjustGroundVelocityToNormal(Vector3 hVelocity, Vector3 groundNormal)
  560. {
  561. var sideways = Vector3.Cross(Vector3.up, hVelocity);
  562. return Vector3.Cross(sideways, groundNormal).normalized * hVelocity.magnitude;
  563. }
  564.  
  565. private bool IsGroundedTest()
  566. {
  567. return groundNormal.y > 0.01;
  568. }
  569.  
  570. float GetMaxAcceleration(bool grounded)
  571. {
  572. return grounded ? movement.maxGroundAcceleration : movement.maxAirAcceleration;
  573. }
  574.  
  575. float CalculateJumpVerticalSpeed(float targetJumpHeight)
  576. {
  577. // From the jump height and gravity we deduce the upwards speed
  578. // for the character to reach at the apex.
  579. return Mathf.Sqrt( * targetJumpHeight * movement.gravity);
  580. }
  581.  
  582. bool IsJumping()
  583. {
  584. return jumping.jumping;
  585. }
  586.  
  587. bool IsSliding()
  588. {
  589. return (grounded && sliding.enabled && TooSteep());
  590. }
  591.  
  592. bool IsTouchingCeiling()
  593. {
  594. return (movement.collisionFlags & CollisionFlags.CollidedAbove) != ;
  595. }
  596.  
  597. bool IsGrounded()
  598. {
  599. return grounded;
  600. }
  601.  
  602. bool TooSteep()
  603. {
  604. return (groundNormal.y <= Mathf.Cos(controller.slopeLimit * Mathf.Deg2Rad));
  605. }
  606.  
  607. Vector3 GetDirection()
  608. {
  609. return inputMoveDirection;
  610. }
  611.  
  612. void SetControllable(bool controllable)
  613. {
  614. canControl = controllable;
  615. }
  616.  
  617. // Project a direction onto elliptical quater segments based on forward, sideways, and backwards speed.
  618. // The function returns the length of the resulting vector.
  619. float MaxSpeedInDirection(Vector3 desiredMovementDirection)
  620. {
  621. if (desiredMovementDirection == Vector3.zero)
  622. return ;
  623. else
  624. {
  625. var zAxisEllipseMultiplier = (desiredMovementDirection.z > ? movement.maxForwardSpeed : movement.maxBackwardsSpeed) / movement.maxSidewaysSpeed;
  626. var temp = new Vector3(desiredMovementDirection.x, , desiredMovementDirection.z / zAxisEllipseMultiplier).normalized;
  627. var length = new Vector3(temp.x, , temp.z * zAxisEllipseMultiplier).magnitude * movement.maxSidewaysSpeed;
  628. return length;
  629. }
  630. }
  631.  
  632. void SetVelocity(Vector3 velocity)
  633. {
  634. grounded = false;
  635. movement.velocity = velocity;
  636. movement.frameVelocity = Vector3.zero;
  637. SendMessage("OnExternalVelocity");
  638. }
  639. }

Unity 之 c# 版的 CharacterMotor的更多相关文章

  1. [Unity+Android]横版扫描二维码

    原地址:http://blog.csdn.net/dingxiaowei2013/article/details/25086835 终于解决了一个忧伤好久的问题,严重拖了项目进度,深感惭愧!一直被一系 ...

  2. Unity 3D 文件导入出错误解决方法以及unity圣典离线版下载地址

    1.安装unity 时我选择了free版的,打开已有项目时出现如下错误提示. 解决方法:先把要导入的文件先拷贝到unity3d安装目录下对应的文件夹内,之后再返回unity3d软件,右键选择“导入”. ...

  3. 关于Unity中旧版动画系统的使用

    Unity在5.X以后,有一个旧版的动画系统和新版的动画系统. 新版的动画系统是使用Unity动画编辑器来调的,调动画和控制动画 旧版的动画系统是用其他的第三方软件调好后导出到一个FBX文件里面,就是 ...

  4. unity, 查看build版log文件

    http://blog.theknightsofunity.com/accessing-unity-game-logs/

  5. Unity 5 引擎收费版和免费版的区别(转)

    最新Unity 5的Professional Edition(收费版)具备全新而强大的功能,除了全局动态光照或是最新的基于物理的着色器之外,也把原本分开销售的Team License放入,并含有12个 ...

  6. 命令行构建Unity项目

    自动任务构建 通常可以在桌面双击 Unity 图标,启动程序,但是,也可以通过命令行(例如,MacOS 终端或 Windows Command 窗口)运行程序.若使用这种方式启动 Unity,它将可以 ...

  7. 通过Unity3D发布IOS版游戏

    https://developer.apple.com/ 打开上面的苹果开发者网站,选择上面的"Member Center"登录进入.前提是,你注册了开发者账号,并且付了年费. 选 ...

  8. Unity ECS 视频笔记

    视频摘要 本文视频资料:使用Entity Component System开发<快乐的Minecraft>游戏 使用Unity2018及以上版本才有ECS功能. 本文是看视频的一些摘要. ...

  9. 【Unity】1.1 安装Unity 5.3.4 开发环境

    分类:Unity.C#.VS2015 创建日期:2016-03-23 一.简介 Unity分个人版(Personal)和专业版(Pro).个人版是免费的(部分高级功能受限,但初学者也用不到它),Pro ...

随机推荐

  1. bjective-C 中核心处理字符串的类是 NSString 与 NSMutableString

    Objective-C 中核心处理字符串的类是 NSString 与 NSMutableString ,这两个类最大的区别就是NSString 创建赋值以后该字符串的内容与长度不能在动态的更改,除非重 ...

  2. linux 查看 cpu 和内存的命令 - top

    1.查看内存,cpu ,当前进程task数目, 每个进程的cpu, 内存使用率, 用top 命令: 在这个页面,按 P,下面的进程排序,以cpu使用率降序排列. 按M,按内存使用率降序排列: 按N, ...

  3. 由浅到深理解java反射

    1.基础概念 class类: 1.1java是面向对象的,但是在java中存在两种东西不是面向对象的 一种是普通的数据类型,这也是封装数据类存在的原因. 二种是静态静态成员. 1.2所以我们首先要理解 ...

  4. JS动态引入js、CSS动态创建script/link/style标签

    一.动态创建link方式 我们可以使用link的方式.如下代码所示. function addCssByLink(url){ var doc=document; var link=doc.create ...

  5. python注意事项

    以下基于python3.4.3 1.python3与python2不兼容 2.python语言正确的缩进很重要!事实上缩进是种语法 C中需要 { } 的的地方,python使用 : +缩进 实现 3. ...

  6. HUD 1541/BIT(数状数组)

    题目链接 /* 按从左到右,从下到上的顺序给出星星的坐标,计算出level为[0,n)的星星的个数. 星星的level为该星星左下边(包括自己正下方的星星,但是不包括自己)星星的个数. BIT模板题. ...

  7. HDU 1072/BFS

    题目链接 Nightmare Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...

  8. angular.js简介

    angularJS是一个javaScript框架.可通过<script>标签添加到HTML页面 angular通过指令扩展了HTML,且通过表达式绑定数据到html 当网页加载完毕,Ang ...

  9. FileReader和BufferedReader的区别

    1.FileReader不能一行行读 FileReader fr = null; try { fr = new FileReader(new File(path)); StringBuffer str ...

  10. docker rmi all

    docker stop $(docker ps -a -q) docker rm $(docker ps -a -q)