[unity3d]鼠标点击地面人物自动走动(也包含按键wasd&space控制)

简介:

在漫游游戏中常用的功能就是人物在场景中行走,必要的功能就是鼠标点击地面人物就朝着那个方向行走,键盘方向键前后左右也能控制人物的行走和跳跃,在官方自带的第三人称视角中做了一点修改,官方自带的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; 	} } 

工程文件:



















本文转蓬莱仙羽 51CTO博客,原文链接:http://blog.51cto.com/dingxiaowei/1366110 ,如需转载请自行联系原作者
相关文章
|
7月前
|
图形学
|
vr&ar 图形学
【Unity3D 灵巧小知识点】☀️ | Unity通过 射线 获取 鼠标的世界坐标 和 鼠标点击的物体信息
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。
【Unity3D 灵巧小知识点】☀️ | Unity通过 射线 获取 鼠标的世界坐标 和 鼠标点击的物体信息
|
图形学
Unity物体移动到点击位置
Camera 在正交模式下可以实现点击哪里就将物体移动到哪里。 public Vector3 tempPos; void Update() { if (Input.GetMouseButtonDown(0)) { tempPos = Input.mousePosition; tempPos = Camera.main.ScreenToWorldPoint(tempPos); tempPos.z = 0; transform.position = tempPos; } } Camera 在透视模式下可以实现点击哪里就将物体移动到哪里。
2034 0
|
测试技术 Android开发 iOS开发
Unity3D-实现连续点击两次返回键退出游戏(安卓/IOS)
Unity3D-连续点击两次返回键退出游戏 本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例...
2811 0
|
图形学
[Unity UGUI]点击和长按组件
需求 游戏项目中卡片经常需要按钮/卡片的点击或者长按事件,这里提供一个好用的组件。 组件 using UnityEngine; using UnityEngine.
2015 0
|
图形学
Unity3d鼠标点击位置实例化点击动画特效-RPG游戏常用
///注明:需要特效动画 using UnityEngine; /// /// 鼠标点击位置实例化点击特效-RPG游戏常用,位于player /// public class PlayerDir : MonoBehaviour { ...
2035 0
|
图形学
[unity3d]鼠标点击地面人物自动走动(也包含按键wasd&amp;space控制)
在漫游游戏中常用的功能就是人物在场景中行走,必要的功能就是鼠标点击地面人物就朝着那个方向行走,键盘方向键前后左右也能控制人物的行走和跳跃,在官方自带的第三人称视角中做了一点修改,官方自带的ThirdPersonController中的摄像机自动指向人物的背面,这样不能看到人物的正面或者侧面,对ThirdPersonController脚本做了修改之后,可以旋转摄像机的视角,可以摄像机跟随,类似smoothfollow的功能。
853 0
|
4月前
|
C# 图形学
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
48 0