[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;
	}
}

工程文件:

时间: 2024-07-28 12:44:34

[unity3d]鼠标点击地面人物自动走动(也包含按键wasd&amp;space控制)的相关文章

js实现鼠标点击文本框自动选中内容的方法_javascript技巧

本文实例讲述了js实现鼠标点击文本框自动选中内容的方法.分享给大家供大家参考.具体如下: 这里使用JS实现鼠标点击时自动选中文本框文本的效果,相信许多朋友都遇到这种功能的,就是当我们点击文本框的时候,文本框中默认的文字会被全部选中,这样当你输入的时候不用再去选择,省去了一些麻烦,提高了输入效率,用户肯定会喜欢这功能,那么实现的方法是怎么样呢?通过本代码你就搞明白了. 先来看看运行效果截图: 在线演示地址如下: http://demo.jb51.net/js/2015/js-mouse-click

js监听鼠标点击和键盘点击事件并自动跳转页面_javascript技巧

js监听鼠标点击(onmousedown)和键盘点击(onkeydown)事件并自动跳转页面,在学习的朋友可以参考下 $(function(){ var i = 0; document.onmousedown=function(event){ if(i==1){ window.open('http://www.njxblog.com'); } //setTimeout(function (){window.open('http://www.jb51.net')},2000); //定时不太好使,

js鼠标点击按钮切换图片-图片自动切换-点击左右按钮切换特效代码_javascript技巧

今天来分享一下鼠标点击按钮,图片进行切换+图片自动切换+点击左右按钮图片进行切换的三种效果的组合代码. 最后的效果如下:     Html代码部分: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus"> <

控件-Qt鼠标点击两个点并自动连接这两个点

问题描述 Qt鼠标点击两个点并自动连接这两个点 在工作区添加两个控件(视为两个点),实现点击鼠标连接两个点,要求:鼠标点击第一个点存储坐标作为线段的起点,此时不画线,再点击第二个点,获取线段的终点,如果起点和终点有一个坐标相同直接相连,如果不同找两个调节点连成平行或垂直的线段.不清楚怎么用代码实现,添加按钮触发事件怎么添加? 解决方案 即然是增加了两个控件,那么就应该查这两个控件是如何响应鼠标点击的. 因为你没有说是什么控件,无法分析. 解决方案二: 我也在想办法实现这个功能,目前的想法是,下根

qt-Qt鼠标点击两个点并自动连接这两个点

问题描述 Qt鼠标点击两个点并自动连接这两个点 在QGraphicsScene中添加Item,在Item中实现点击鼠标连接两个点,要求:鼠标点击第一个点存储坐标作为线段的起点,此时不画线,再点击第二个点,获取线段的终点,如果起点和终点有一个坐标相同直接相连,如果不同找两个调节点连成平行或垂直的线段.不清楚怎么用代码实现,添加按钮触发事件怎么添加? 解决方案 http://zhidao.baidu.com/link?url=gWCeRxi0djrj9bJD3oLMPmjlMUXu8ccS4KA3g

在C#中实现对ListView点击列标题自动排序功能

先定义一个ListViewHelper类,代码如下: using System; using System.Collections; using System.Windows.Forms; namespace Common { /// <summary> /// 对ListView点击列标题自动排序功能 /// </summary> public class ListViewHelper { /// <summary> /// 构造函数 /// </summary

Python实现windows下模拟按键和鼠标点击的方法_python

本文实例讲述了Python实现windows下模拟按键和鼠标点击的方法.分享给大家供大家参考.具体如下: 这段代码可以模拟在窗口上按下按键.鼠标左键点击.鼠标右键点击.鼠标双击等等 # # _*_ coding:UTF-8 _*_ import win32api import win32con import win32gui from ctypes import * import time VK_CODE = { 'backspace':0x08, 'tab':0x09, 'clear':0x0

jquery-关于JQuery easyui中numberbox鼠标点击事件问题?

问题描述 关于JQuery easyui中numberbox鼠标点击事件问题? 如标题 当我修改是鼠标点击文本框时 里面的数据就清空了 jsp <td class="form_label" id="setlable">总剧集数:</td> <td> <input type="text" id="collectionNumber" name="collectionNumber&

基于jQuery实现鼠标点击导航菜单水波动画效果附源码下载_jquery

基于jQuery鼠标点击水波动画竖直导航代码.这是一款基于jQuery+CSS3实现的带动画效果的竖直导航栏特效.效果图如下: 效果展示    源码下载 html代码: <div class="nav"> <ul> <li><a>网站首页</a></li> <li><a>关于我们</a></li> <li><a>产品中心</a>&l