sketchupunityy 5.5 sketchupunityy 5.6 到底支持 c#什么版本

收藏成功,可进入
查看所有收藏列表
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
{{itemRight.playCount}}
终于把我夏天制作的这个系列视频,"女神带你入门Unity", 公开发布了。与其说是一个讲座,不如说是我学习Unity的笔记。希望这个讲座能帮助零基础的Unity初学者用最快的速度掌握Unity游戏引擎的基本概念,并能用Unity开发一些简单的小游戏,为以后进一步的深度学习打下基础。
第十七讲:Unity 入门之C#编程基础 - C#语句unity 5.5 unity 5.6 到底支持 c#什么版本_百度知道
unity 5.5 unity 5.6 到底支持 c#什么版本
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
你这几个错误并非new一个类的问题,从上面的代码看有两个错误,前面俩错误是因为你用js直接创建了二维数组,而unity的js并不知道创建二维数组,需要从C写个方法来返回数组,再直接调用,具体的请百度。。。后面的两个错误就明显了,在varcar
采纳数:888
获赞数:7831
unity 5.5 的 Mono 编辑器 支持 c#4.0,但是 unity5.5 运行框架 是 .net 2.0 ,加上 .net 3.0 和 .net 3.5 的各一部分的集合。。unity5.6的情况和5.5相同。。
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。之前MOMO在 文章中向大家介绍了角色控制器组件。默认系统提供了JavaScript脚本的支持,可是我们还是喜欢用C#来编写脚本,本篇文章MOMO将把角色控制器的所有脚本全部改成C#语言。方便自己也方便大家学习,哇咔咔。首先,我们将角色控制器包引入工程中。如下图所示,默认提供的脚本除了MouseLook以外其它的都是JS脚本,本篇文章MOMO将把它们全部修改成C#。刚好也是答应Unity圣典的站长录制游戏开发视频,视频中我说下一节我将教大家怎么把角色控制器组件的脚本全部改成C#。
首先把CharacterMotor.js修改成C# 它主要设置角色控制的系数,如运动、跳跃、移动、滑动等。第一人称与第三人称主角模型的移动与旋转的角度都最后都是在这里计算的,请大家好好看看这个类, 尤其是UpdateFunction()方法。
CharacterMotor.cs
using UnityE
using System.C
@Author : www.xuanyusong.com
[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 &CharacterController&();
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);
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;
// 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 =
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
desiredVelocity = GetDesiredHorizontalVelocity();
if (movingPlatform.enabled && movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer) {
desiredVelocity += movement.frameV
desiredVelocity.y = 0;
if (grounded)
desiredVelocity = AdjustGroundVelocityToNormal(desiredVelocity, groundNormal);
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
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);
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);
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.
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 () {
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
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)
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
using UnityE
using System.C
@Author : www.xuanyusong.com
[RequireComponent(typeof(CharacterMotor))]
[AddComponentMenu("Character/FPS Input Controller")]
public class FPSInputController : MonoBehaviour {
private CharacterM
// Use this for initialization
void Awake () {
motor = GetComponent&CharacterMotor&();
// 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
using UnityE
using System.C
@Author : www.xuanyusong.com
[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&CharacterMotor&();
// 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
using UnityE
using System.C
@Author : www.xuanyusong.com
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&ThirdPersonController&();
if (controller)
CharacterController characterController
= (CharacterController)_target.
centerOffset = characterController.bounds.center - _target.
headOffset = centerO
headOffset.y = characterController.bounds.max.y - _target.position.y;
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"))
// We are close to the target, so we can stop snapping now!
if (AngleDistance (currentAngle, originalTargetAngle) & 3.0)
currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, snapSmoothLag, snapMaxSpeed);
// Normal camera motion
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
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;
Apply (transform, Vector3.zero);
heightSmoothLag = oldHeightS
snapMaxSpeed = oldSnapMaxS
snapSmoothLag = oldSnapS
void SetUpRotation (Vector3 centerPos,Vector3
// 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;
extraLookAngle = extraLookAngle - centerToTopA
cameraTransform.rotation *= Quaternion.Euler(-extraLookAngle, 0, 0);
Vector3 GetCenterOffset ()
return centerO
最后一个是ThirdPersonController我们同样把它修改成C#语言,它主要更新第三人称视角控制主角时播放的各种动画,主角移动,等等。
ThirdPersonController.cs
using UnityE
using System.C
@Author : www.xuanyusong.com
[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&Animation&();
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 =
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
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
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
// 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()) {
// - 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;
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 ()
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&CharacterController&();
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);
_animation[jumpPoseAnimation.name].speed = -landAnimationS
_animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampF
_animation.CrossFade(jumpPoseAnimation.name);
if(controller.velocity.sqrMagnitude & 0.1f) {
_animation.CrossFade(idleAnimation.name);
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);
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)
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";
Unity3D 第一人称控制器 C#脚本
欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学院,致力于打造业内u...
Unity3D教学 开发简单版第一人称射击游戏 可以多人联机(附源码)
这一篇文章主要是和大家分享如何制作一个属于自己的“第一人称射击游戏”,而且是要可以多人联机的。这个游戏属于比简单的,大神可以直接无视,如果有做错的地方请大家多多指点,我也是刚学如何做游戏。代码是用C#...
Unity3d--第三人称角色移动控制
第三人称的角色移动控制方案有很多种:
rigidbody.velocity() : 通过控制刚体的速度 来实现对角色的移动控制
2. rigidbody.MovePosition() : 通...
利用unity3D自带的第三人称控制自己的模型(模型不带动画只带骨架的情况,角色控制)
1.首先,导入unity3D自带的Characters包,里面有很实用的第一人称和第三人称控制的Prefabs,自己开发小游戏的时候,可以用这些模型来调试效果。2.在数据包里寻找自己适用的Prefab...
Unity3D研究之第一人称第三人称角色控制组件修改
之前作者在前文中向大家介绍了角色控制器组件。默认系统提供了JavaScript脚本的支持,可是我们还是喜欢用C#来编写脚本,本篇文章作者将把角色控制器的所有脚本全部改成C#语言。方便自己也方便大家学习...
Unity3d 官方自带人物控制器研究
官方自带的资源包首先是下载地址5.0.0f4版本的官方自带资源包
http://pan.baidu.com/s/1o8Ujrxo
2017斑斑的官方自带资源包
http://pan.baidu....
unity3d学习笔记(三)--不用一句代码快速加载并控制第三人称主角
我们的世界不能只有水流山川,花草树木,让我们的主角正式登场吧。这篇文章将介绍怎样加载人物,并赋予第三人称视角,第三人称控制,很简单哦。
制作模型是美术童鞋的事,俺是个程序,偷下懒,到网上找资源吧,于...
使用unity3d搭建简单的场景以及第一人称角色的控制
一、搭建简单的游戏场景
1、打开unity3d编辑器,新建一个空工程。
2、创建若干个cube对象,通过伸缩变换形成地板,墙壁以及障碍物等。
3、创建平行灯,照亮场景
4、创建一个胶囊对象,作为角色
unity3d-代码控制游戏角色控制器移动
先上一个gif看看效果。因为图片大小限制。所以录制的比较小。个人认为效果比较牵强。特别是里面的逻辑代码。 不过我还是认为一切是为了先实现,因为我是刚接触的新手。
工程结构图
没有更多推荐了,}

我要回帖

更多关于 sketchupunity 的文章

更多推荐

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

点击添加站长微信