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

工程文件:
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页