在漫游游戏中常用的功能就是人物在场景中行走,必要的功能就是鼠标点击地面人物就朝着那个方向行走,键盘方向键前后左右也能控制人物的行走和跳跃,在官方自带的第三人称视角中做了一点修改,官方自带的ThirdPersonController中的摄像机自动指向人物的背面,这样不能看到人物的正面或者侧面,对ThirdPersonController脚本做了修改之后,可以旋转摄像机的视角,可以摄像机跟随,类似smoothfollow的功能。
值得注意提醒的一个,就是动画系统,选择老版本的动画系统,不然会提示找不到模型,因为脚本中用的是老版本的动画系统的代码。
一、效果图
1.鼠标点击地面人物朝着点击的点前进
2.按住wasd和space键也能控制人物的动作
二、大概步骤
1.创建一个plane,设置层为Terrain,因为后面要判断是否点击的是这个层
void Update () { MouseDownMover(); } public void MouseDownMover() { if(Input.GetMouseButtonDown(0)) { //如果左击 LayerMask layerMaskPlayers = 1 << LayerMask.NameToLayer("Terrain"); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit,600,layerMaskPlayers.value)) { point = hit.point; Instantiate(clickPont, point, transform.rotation); TimeRealtimeSinceStartup(); } } }
2.准备好人物模型,并且将三个脚本拖放到人物上,并且将动画文件也拖放好,记得看前面提醒哦!
1.ThirdPersonCamera(相当于smoothflow)
/* Perfect Camera Control Script By zhoy; Which can be toggled between First-Person Look And Third-Person Look And it also realised freely Look-around the world with mouse move */ var cameraTransform : Transform; var distance = 7.0; var xSpeed = 100; var ySpeed = 100; var mSpeed = 10; var angularSmoothLag = 0.3; var angularMaxSpeed = 15.0; var snapSmoothLag = 0.2; var snapMaxSpeed = 720.0; var clampHeadPositionScreenSpace = 0.75; private var _target : Transform; //var secondCamera : Camera; private var mainCamera : Camera; private var controller : ThirdPersonController; private var headOffset = Vector3.zero; private var centerOffset = Vector3.zero; private var dosnap = false; private var snapped = false; private var firstPersonLook = false; private var angleVelocity = 0.0; private var minAngleY = -45; private var yTopLimit = -20.0; private var yMinLimit = -45; private var yMaxLimit = 45; private var minDistance = 1.2; private var maxDistance = 3.5; private var current_ver_angle = 0.0; private var current_hor_angle = 0.0; private var look_height = 0.0; private var bSeePicture = false; private var curPicturePos:Vector3; private var curPictureRotation:Quaternion; private var curPictureTran: Transform; function Awake () { //secondCamera.enabled = false; mainCamera = Camera.main; cameraTransform = GameObject.Find("Main Camera").transform; if(!cameraTransform && mainCamera) { cameraTransform = mainCamera.transform; } if(!cameraTransform) { Debug.Log("Please assign a camera to the ThirdPersonCamera script."); enabled = false; } _target = transform; if (_target) { controller = _target.GetComponent(ThirdPersonController); } if (controller) { var characterController : CharacterController = _target.collider; centerOffset = characterController.bounds.center - _target.position; headOffset = centerOffset; var look_target = _target.Find("LookTarget"); //Debug.Log(look_target); var head_back_pos = characterController.bounds.max; if(look_target) { head_back_pos = look_target.transform.position; } var hit_test : RaycastHit; var head_top = characterController.bounds.center; head_top.y = characterController.bounds.min.y; if(Physics.Raycast(head_top,Vector3.down,hit_test,50)) { look_height = head_back_pos.y - hit_test.point.y; } //Debug.Log("look_height : " + look_height); headOffset.y = head_back_pos.y - _target.position.y; /*下面计算、保存 相机稳定后 的初始位置与方位*/ var hor_angle = _target.eulerAngles.y; var rotation_h = Quaternion.Euler (0, hor_angle, 0); var camera_pos = head_back_pos; camera_pos += rotation_h * Vector3.back * distance; /*计算相机位置是用 头部为球中心计算的*/ var offsetToCenter = head_back_pos - camera_pos; var rotation = Quaternion.LookRotation(Vector3(offsetToCenter.x, offsetToCenter.y, offsetToCenter.z)); current_hor_angle = 360 - rotation.eulerAngles.y; current_ver_angle = rotation.eulerAngles.x; } else { Debug.Log("Please assign a target to the camera that has a ThirdPersonController script attached."); } Cut(_target, centerOffset); } function SetVisible(visible) { var renderers = gameObject.GetComponentsInChildren(Renderer); if(visible) { for(var rend:Renderer in renderers){ rend.enabled = true; } firstPersonLook = false; } else { for(var rend:Renderer in renderers) { rend.enabled = false; } firstPersonLook = true; } } function Cut (dummyTarget : Transform, dummyCenter : Vector3) { var oldSnapMaxSpeed = snapMaxSpeed; var oldSnapSmooth = snapSmoothLag; snapMaxSpeed = 10000; snapSmoothLag = 0.001; dosnap = true; Apply (transform, Vector3.zero); snapMaxSpeed = oldSnapMaxSpeed; snapSmoothLag = oldSnapSmooth; } function DebugDrawStuff () { Debug.DrawLine(_target.position, _target.position + headOffset); } function AngleDistance (a : float, b : float) { a = Mathf.Repeat(a, 360); b = Mathf.Repeat(b, 360); return Mathf.Abs(b - a); } function Apply (dummyTarget : Transform, dummyCenter : Vector3) { // Early out if we don't have a target if (!controller) { return; } var needGoOn = false; var targetCenter = _target.position + centerOffset; var targetHead = _target.position + headOffset; var strength = Input.GetAxis("Mouse ScrollWheel"); if(strength != 0) { distance -= strength*mSpeed; distance = Mathf.Clamp(distance, minDistance, maxDistance); /* if(distance <= 1) { SetVisible(false); minAngleY = -80; } else if(firstPersonLook) { SetVisible(true); } else if(distance < look_height) { minAngleY = (distance - 2) * (yTopLimit - yMinLimit)/(look_height - 2) - yTopLimit; minAngleY = - minAngleY; } else { minAngleY = yMinLimit; } */ needGoOn = true; } var originalTargetAngle = 360 - _target.eulerAngles.y; current_hor_angle = 360 - cameraTransform.eulerAngles.y; if(!snapped) { var targetAngle = originalTargetAngle; var dis_angle = 0; if (dosnap) { dis_angle = AngleDistance (360 - current_hor_angle, originalTargetAngle); current_hor_angle = Mathf.SmoothDampAngle(current_hor_angle, targetAngle, angleVelocity, snapSmoothLag, snapMaxSpeed); } // We are close to the target, so we can stop snapping now! dis_angle= 0; if (dis_angle <= 13) { snapped = true; dosnap = false; } else if(dis_angle < 3) { dosnap = false; } if(!snapped && !dosnap) { current_hor_angle = Mathf.SmoothDampAngle(current_hor_angle, targetAngle, angleVelocity, angularSmoothLag, angularMaxSpeed); } needGoOn = true; } else { var rotation_h =0; var rotation_v =0; if (Input.GetMouseButton(1)) { rotation_h = -Input.GetAxis("Mouse X") * xSpeed *0.02; rotation_v = -Input.GetAxis("Mouse Y") * ySpeed *0.02; } needGoOn = needGoOn || (rotation_h != 0 || rotation_v != 0); current_hor_angle += rotation_h; current_hor_angle = Mathf.Repeat(current_hor_angle, 360); current_ver_angle += rotation_v; current_ver_angle = Mathf.Clamp (current_ver_angle, minAngleY, yMaxLimit); } needGoOn = needGoOn || controller.IsMoving(); needGoOn = needGoOn || controller.IsJumping(); if(!needGoOn)/*没有鼠标键盘事件,返回即可,相机一般不会自动更新。除非未来有其他情形,那时候再添加*/ { var mousecl = GetComponent("mouseMoveContr"); var mouseMoveFlag = mousecl.getmousemoveFlag(); if (!mouseMoveFlag) { return; } } var rad_angle_h = (current_hor_angle - 90.0)*Mathf.Deg2Rad; var rad_angle_v = current_ver_angle*Mathf.Deg2Rad; var camera_pos = Vector3.zero; var radius_hor = distance*Mathf.Cos(rad_angle_v); var slope = -Mathf.Sin(rad_angle_v); camera_pos.x = radius_hor*Mathf.Cos(rad_angle_h) + targetHead.x;/*计算相机位置是用 头部为球中心计算的*/ camera_pos.z = radius_hor*Mathf.Sin(rad_angle_h) + targetHead.z; camera_pos.y = -distance*slope + targetHead.y; if(camera_pos.y < targetHead.y - look_height) { camera_pos.y = targetHead.y - look_height; } var hit : RaycastHit; var modified = false; var hor_dis = 0.0; if(camera_pos.y < targetCenter.y) { var testPt = camera_pos; testPt.y = targetCenter.y; if(Physics.Raycast(testPt,Vector3.down,hit,50))/*这个检测必须进行,不能完全指望后面的检测,否则会有微小的显示问题。一般发生在摄像机贴近地面跑动时*/ { if(camera_pos.y < hit.point.y + 0.5)/*偏移0.5.防止过于接近地面,并且在地面上面的情况,会因为摄像机近截面问题。导致显示地下的内容*/ { modified = true; } } } if(modified) { hor_dis = Vector3.Distance(targetCenter,Vector3(camera_pos.x,targetCenter.y,camera_pos.z)); camera_pos = hit.point; camera_pos.y = (slope > 0.95)?hit.point.y:(camera_pos.y + hor_dis/maxDistance); //摄像头在脚下的时候,hor_dis几乎为0 modified = false; //Debug.Log("hit down.....camera_pos : " +camera_pos); } var real_dis = Vector3.Distance(targetCenter,camera_pos); var direction = camera_pos - targetCenter; if(Physics.Raycast(targetCenter,direction,hit,real_dis) && hit.collider.gameObject != gameObject) { // modified = false; // if(hit.collider.bounds.size.magnitude <= 15) { // modified = false; // } else if (hit.collider.gameObject.tag == "bridge") { // camera_pos.y = camera_pos.y + 2.5; // } else if (hit.collider.gameObject.tag == "through"){ // modified = false; // } else { // modified = true; // } // Debug.LogError(hit.point.y < targetHead.y); camera_pos = hit.point; if(hit.point.y < targetHead.y){ camera_pos.y = targetHead.y; // Debug.LogError(camera_pos); } } // // if(modified) // { // hor_dis = Vector3.Distance(targetCenter,Vector3(camera_pos.x,targetCenter.y,camera_pos.z)); // camera_pos = hit.point; // camera_pos.y = (slope > 0.95)?hit.point.y:(camera_pos.y + hor_dis/maxDistance);/*摄像头在脚下的时候,hor_dis几乎为0*/ // } cameraTransform.position = camera_pos; var offsetToCenter = targetHead - cameraTransform.position; cameraTransform.rotation = Quaternion.LookRotation(Vector3(offsetToCenter.x, offsetToCenter.y, offsetToCenter.z)); Debug.DrawLine(targetCenter, camera_pos, Color.red); } function EventMouseClicked(){ // Debug.LogError(Input.mousePosition); var mousePos:Vector3 = Input.mousePosition; var ray:Ray; ray = Camera.main.ScreenPointToRay(mousePos); var hitInfo:RaycastHit; var cameraTran:Transform; cameraTran = Camera.main.transform; if(Input.GetMouseButtonDown(0)){ if(Physics.Raycast(ray, hitInfo, 50f, (1<<9))){ Debug.LogError(hitInfo.transform.gameObject.layer); // curPicturePos = hitInfo.point; // curPicturePos = hitInfo.transform.Find("CameraPos").position; // curPictureRotation = hitInfo.transform.Find("CameraPos").rotation; curPictureTran = hitInfo.transform.Find("CameraPos"); bSeePicture = !bSeePicture; if(bSeePicture){ GetComponent(ThirdPersonController).enabled = false; }else{ GetComponent(ThirdPersonController).enabled = true; } } } } function LateUpdate () { if (Input.GetKeyUp (KeyCode.Tab)) { var hit2 : RaycastHit; Debug.Log("Camera Pos.y : " + cameraTransform.position.y); var testPt = cameraTransform.position; testPt.y = 50; if(Physics.Raycast(testPt,Vector3.down,hit2,50)) { Debug.Log("hit2.point.y : " + hit2.point.y); } } EventMouseClicked(); if(!bSeePicture){ Apply (transform, Vector3.zero); }else{ // Camera.main.transform.position = transform.position; // Camera.main.transform.position.y = curPicturePos.y; //// Camera.main.transform.rotation = Quaternion.LookRotation(curPicturePos - Camera.main.transform.position); // Camera.main.transform.rotation = transform.rotation; // Camera.main.transform.position = curPicturePos; // Camera.main.transform.rotation = curPictureRotation; Camera.main.transform.rotation = curPictureTran.rotation; Camera.main.transform.position = curPictureTran.position; } } function GetCenterOffset () { return centerOffset; } /* function UpdateSecondCamPos(lookat,campos) { var ccnter = Vector3.Lerp(campos,lookat,0.5); var forward = ccnter - campos; forward = forward.normalized; forward.y = 0; var right = Vector3.Cross (Vector3.up, forward); var setpos = ccnter + right*30; secondCamera.transform.position = setpos; var offset = ccnter - setpos; //Debug.DrawRay(campos,lookat - campos,Color.red,100000); var t1 = Time.time; GameObject.Find("TestObject").transform.position = campos; var t2= Time.time; secondCamera.transform.rotation = Quaternion.LookRotation(Vector3(offset.x, offset.y, offset.z)); } */ /* if (Input.GetKeyUp (KeyCode.Tab)) { var hit2 : RaycastHit; Debug.Log("Camera Pos.y : " + cameraTransform.position.y); var testPt = cameraTransform.position; testPt.y = 50; if(Physics.Raycast(testPt,Vector3.down,hit2,50)) { Debug.Log("hit2.point.y : " + hit2.point.y); } if(mainCamera.enabled) { controller.SwitchCamera(secondCamera); } else { controller.SwitchCamera(mainCamera); } } */
2.ThirdPersonController(修改版)
// Require a character controller to be attached to the same game object @script RequireComponent(CharacterController) public var idleAnimation : AnimationClip; public var walkAnimation : AnimationClip; public var runAnimation : AnimationClip; public var jumpPoseAnimation : AnimationClip; public var kneeAnimation : AnimationClip; public var walkMaxAnimationSpeed : float = 0.75; public var trotMaxAnimationSpeed : float = 1.0; public var runMaxAnimationSpeed : float = 1.0; public var jumpAnimationSpeed : float = 1.15; public var landAnimationSpeed : float = 1.0; private var _animation : Animation; enum CharacterState { Idle = 0, Walking = 1, Trotting = 2, Running = 3, Jumping = 4, } private var _characterState : CharacterState; // The speed when walking var walkSpeed = 2.0; // after trotAfterSeconds of walking we trot with trotSpeed var trotSpeed = 4.0; // when pressing "Fire3" button (cmd) we start running var runSpeed = 6.0; var inAirControlAcceleration = 3.0; // How high do we jump when pressing jump and letting go immediately var jumpHeight = 0.5; // The gravity for the character var gravity = 20.0; // The gravity in controlled descent mode var speedSmoothing = 10.0; var rotateSpeed = 500.0; var trotAfterSeconds = 3.0; var canJump = true; private var jumpRepeatTime = 0.05; private var jumpTimeout = 0.15; private var groundedTimeout = 0.25; // The camera doesnt start following the target immediately but waits for a split second to avoid too much waving around. private var lockCameraTimer = 0.0; // The current move direction in x-z private var moveDirection = Vector3.zero; // The current vertical speed private var verticalSpeed = 0.0; // The current x-z move speed private var moveSpeed = 0.0; // The last collision flags returned from controller.Move private var collisionFlags : CollisionFlags; // Are we jumping? (Initiated with jump button and not grounded yet) private var jumping = false; private var jumpingReachedApex = false; // Are we moving backwards (This locks the camera to not do a 180 degree spin) private var movingBack = false; // Is the user pressing any keys? private var isMoving = false; // When did the user start walking (Used for going into trot after a while) private var walkTimeStart = 0.0; // Last time the jump button was clicked down private var lastJumpButtonTime = -10.0; // Last time we performed a jump private var lastJumpTime = -1.0; // the height we jumped from (Used to determine for how long to apply extra jump power after jumping.) private var lastJumpStartHeight = 0.0; private var inAirVelocity = Vector3.zero; private var lastGroundedTime = 0.0; private var isControllable = true; private var activeCamera : Camera; //private var scenesCode = "S"; function Start() { //scenesCode = GameObject.Find("Main Camera").GetComponent("createusers").getScenesCode(); } function LateUpdate() { } function 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 : AnimationClip; public var walkAnimation : AnimationClip; public var runAnimation : AnimationClip; public var jumpPoseAnimation : AnimationClip; */ if(!idleAnimation) { _animation = null; Debug.Log("No idle animation found. Turning off animations."); } if(!walkAnimation) { _animation = null; Debug.Log("No walk animation found. Turning off animations."); } if(!runAnimation) { _animation = null; Debug.Log("No run animation found. Turning off animations."); } if(!jumpPoseAnimation && canJump) { _animation = null; Debug.Log("No jump animation found and the character has canJump enabled. Turning off animations."); } activeCamera = Camera.main; Screen.lockCursor = false; } /* function SwitchCamera(camera:Camera) { activeCamera.enabled = false; activeCamera = camera; activeCamera.enabled = true; } */ function UpdateSmoothedMovementDirection () { var cameraTransform = activeCamera.transform; var grounded = IsGrounded(); // Forward vector relative to the camera along the x-z plane var forward = cameraTransform.TransformDirection(Vector3.forward); forward.y = 0; forward = forward.normalized; // Right vector relative to the camera // Always orthogonal to the forward vector var right = Vector3(forward.z, 0, -forward.x); var v = Input.GetAxisRaw("Vertical"); var h = Input.GetAxisRaw("Horizontal"); // Are we moving backwards or looking backwards if (v < -0.2) movingBack = true; else movingBack = false; var wasMoving = isMoving; isMoving = Mathf.Abs (h) > 0.1 || Mathf.Abs (v) > 0.1; // Target direction relative to the camera var targetDirection = h * right + v * forward; // Grounded controls if (grounded) { // Lock camera for short period when transitioning moving & standing still lockCameraTimer += Time.deltaTime; if (isMoving != wasMoving) lockCameraTimer = 0.0; // 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.9 && grounded) { moveDirection = targetDirection.normalized; } // Otherwise smoothly turn towards it else { moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000); moveDirection = moveDirection.normalized; } } // Smooth the speed based on the current target direction var curSmooth = speedSmoothing * Time.deltaTime; // Choose target speed //* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways var targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0); _characterState = CharacterState.Idle; // Pick speed modifier if (Input.GetKey (KeyCode.LeftShift) || Input.GetKey (KeyCode.RightShift)) { targetSpeed *= runSpeed; _characterState = CharacterState.Running; } else if (Time.time - trotAfterSeconds > walkTimeStart) { targetSpeed *= trotSpeed; _characterState = CharacterState.Trotting; } else { targetSpeed *= walkSpeed; _characterState = CharacterState.Walking; } moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth); // Reset walk time start when we slow down if (moveSpeed < walkSpeed * 0.3) walkTimeStart = Time.time; } // In air controls else { // Lock camera while in air if (jumping) lockCameraTimer = 0.0; if (isMoving) inAirVelocity += targetDirection.normalized * Time.deltaTime * inAirControlAcceleration; } } function ApplyJumping () { // Prevent jumping too fast after each other if (lastJumpTime + jumpRepeatTime > Time.time) return; 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); } } } function ApplyGravity () { if (isControllable) // don't move player at all if not controllable. { // Apply gravity var jumpButton = Input.GetButton("Jump"); // When we reach the apex of the jump we send out a message if (jumping && !jumpingReachedApex && verticalSpeed <= 0.0) { jumpingReachedApex = true; SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver); } if (IsGrounded ()) verticalSpeed = 0.0; else verticalSpeed -= gravity * Time.deltaTime; } } function CalculateJumpVerticalSpeed (targetJumpHeight : float) { // 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); } function DidJump () { jumping = true; jumpingReachedApex = false; lastJumpTime = Time.time; lastJumpStartHeight = transform.position.y; lastJumpButtonTime = -10; _characterState = CharacterState.Jumping; } function Update() { if (_animation.IsPlaying("kneel")) { return; } if (!isControllable) { // kill all inputs if not controllable. Input.ResetInputAxes(); } if (Input.GetButtonDown ("Jump") && !jumping) { lastJumpButtonTime = Time.time; } if (Input.GetKeyUp (KeyCode.Escape)) { Screen.lockCursor = !Screen.lockCursor; } UpdateSmoothedMovementDirection(); // Apply gravity // - extra power jump modifies gravity // - controlledDescent mode modifies gravity ApplyGravity (); // Apply jumping logic ApplyJumping (); //鼠标移动 var mousecl = GetComponent("mouseMoveContr"); var mouseMoveFlag = mousecl.getmousemoveFlag(); if (mouseMoveFlag){ if (checkKeyDown()) { mousecl.setMouseMoveFlag(); } else { moveDirection = mousecl.getMovement(); moveSpeed = mousecl.getMoveSpeed(); if (moveSpeed == 4.2) { _characterState = CharacterState.Running; } } } // Calculate actual motion var movement = moveDirection * moveSpeed + Vector3 (0, verticalSpeed, 0) + inAirVelocity; movement *= Time.deltaTime; // Move the controller var controller : CharacterController = GetComponent(CharacterController); collisionFlags = controller.Move(movement); if (_characterState == CharacterState.Running) { if (mouseMoveFlag){ if(controller.velocity.sqrMagnitude < 100) { _characterState = CharacterState.Walking; } } } // ANIMATION sector if(_animation) { if(_characterState == CharacterState.Jumping) { if(!jumpingReachedApex) { _animation[jumpPoseAnimation.name].speed = jumpAnimationSpeed; _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever; _animation.CrossFade(jumpPoseAnimation.name); } else { _animation[jumpPoseAnimation.name].speed = -landAnimationSpeed; _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever; _animation.CrossFade(jumpPoseAnimation.name); } } else { if(controller.velocity.sqrMagnitude < 0.1) { _animation.CrossFade(idleAnimation.name); } else { if(_characterState == CharacterState.Running) { _animation[runAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, runMaxAnimationSpeed); _animation.CrossFade(runAnimation.name); } else if(_characterState == CharacterState.Trotting) { _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, trotMaxAnimationSpeed); _animation.CrossFade(walkAnimation.name); } else if(_characterState == CharacterState.Walking) { _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, walkMaxAnimationSpeed); _animation.CrossFade(walkAnimation.name); } } } } // ANIMATION sector // Set rotation to the move direction if (IsGrounded()) { transform.rotation = Quaternion.LookRotation(moveDirection); } else { var xzMove = movement; xzMove.y = 0; if (xzMove.sqrMagnitude > 0.001) { transform.rotation = Quaternion.LookRotation(xzMove); } } // We are in jump mode but just became grounded if (IsGrounded()) { lastGroundedTime = Time.time; inAirVelocity = Vector3.zero; if (jumping) { jumping = false; SendMessage("DidLand", SendMessageOptions.DontRequireReceiver); } } } function OnControllerColliderHit (hit : ControllerColliderHit ) { // Debug.DrawRay(hit.point, hit.normal); if (hit.moveDirection.y > 0.01) return; } function GetSpeed () { return moveSpeed; } function IsJumping () { return jumping; } function IsGrounded () { return (collisionFlags & CollisionFlags.CollidedBelow) != 0; } function GetDirection () { return moveDirection; } function IsMovingBackwards () { return movingBack; } function GetLockCameraTimer () { return lockCameraTimer; } function GetCharacterState() :CharacterState { return _characterState; } function IsMoving () : boolean { return Mathf.Abs(Input.GetAxisRaw("Vertical")) + Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.5; } function HasJumpReachedApex () { return jumpingReachedApex; } function IsGroundedWithTimeout () { return lastGroundedTime + groundedTimeout > Time.time; } function Reset () { gameObject.tag = "Player"; } function checkKeyDown():boolean { if (Input.GetKey(KeyCode.W)) { return true; } if (Input.GetKey(KeyCode.A)) { return true; } if (Input.GetKey(KeyCode.S)) { return true; } if (Input.GetKey(KeyCode.D)) { return true; } if (Input.GetKey(KeyCode.UpArrow)) { return true; } if (Input.GetKey(KeyCode.DownArrow)) { return true; } if (Input.GetKey(KeyCode.RightArrow)) { return true; } if (Input.GetKey(KeyCode.LeftArrow)) { return true; } return false; }
3.mouseMoveContr(鼠标点击人物走动)
using UnityEngine; using System.Collections; public class mouseMoveContr : MonoBehaviour { public const int PLAY_IDLE = 0; public const int PLAY_WALK = 1; public const int PLAY_RUN = 2; public const int PLAY_KNEE = 3; //public GameObject clickPont; public float walkSpeed = 2; public float runSpeed = 4.5f; private bool moveflag = false; private int gameState = 0; private Vector3 point; private float time; private Vector3 v; private Vector3 lotav; private float moveSpeed = 0.0f; void Start () { SetGameState(PLAY_IDLE); } void Update () { MouseDownMover(); } public void MouseDownMover() { if(Input.GetMouseButtonDown(0)) { LayerMask layerMaskPlayers = 1 << LayerMask.NameToLayer("Terrain"); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit,600,layerMaskPlayers.value)) { point = hit.point; //Instantiate(clickPont, point, transform.rotation); TimeRealtimeSinceStartup(); } } } public void TimeRealtimeSinceStartup() { if(Time.realtimeSinceStartup - time <=0.2f) { SetGameState(PLAY_RUN); } else { SetGameState(PLAY_WALK); } time = Time.realtimeSinceStartup; } public void FixedUpdate() { switch(gameState) { case PLAY_IDLE: break; case PLAY_WALK: SetGameState(PLAY_WALK); Move(walkSpeed); break; case PLAY_RUN: SetGameState(PLAY_RUN); Move(runSpeed); break; } } public void SetGameState(int state) { switch(state) { case PLAY_IDLE: point = transform.position; //animation.Play("idle"); break; case PLAY_WALK: //animation.Play("walk"); break; case PLAY_RUN: //animation.Play("run"); break; } gameState = state; } public void Move(float speed) { if(Mathf.Abs(Vector3.Distance(point, transform.position))>=0.2f) { moveflag = true; CharacterController controller = GetComponent<CharacterController>(); v = Vector3.ClampMagnitude(point - transform.position,speed); v.y = 0; } else { moveflag = false; SetGameState(PLAY_IDLE); } moveSpeed = speed; } public bool getmousemoveFlag() { return moveflag; } public void setMouseMoveFlag() { moveflag = false; point = transform.position; } public Vector3 getMovement() { return v; } public float getMoveSpeed() { return moveSpeed; } }
工程文件: