1. 程式人生 > >unity手遊(1)使用CharacterController控制人物移動

unity手遊(1)使用CharacterController控制人物移動

前言




之前在網上找到一個完整的rpg的遊戲demo,斷斷續續自個琢磨了2個月,
學習NGUI的時候,就用NGUI外掛把遊戲本身基於GUI的部分UI介面改編了一下,
一直在看裡面的遊戲邏輯,剛開始一頭霧水,之後慢慢的理解一部分東西了,藉此寫部落格的機會,
決定重新開始學習其程式碼,參考下,做一個手遊RPGdemo,自己對於RPG的美好記憶應該是源於小學時候玩的98版仙劍奇俠傳。恩,真的是人生中美好的記憶~


CharacterController


開始正題,對於人物的移動,一般可以給人物新增collider和rigidbody元件,也可以新增CharacterController人物控制組件來進行控制

CharacterController包含Rigidbody元件的一些屬性,個人理解,有了CharacterController,就不用再新增Rigidbody元件了,

控制器不會對加在它自身上的力做出反應,也不會自動推開其他剛體。

如果想讓角色控制器推開其他剛體或者物件,你可以在物件附加的指令碼中新增OnControllerColliderHit()函式,這樣對它們施加力就能夠產生碰撞。


長得像一個膠囊體,對於其屬性的一些調整,有一些需要注意的

Slope Limit 坡度限制,不能設的太小,一般使用90度會比較合適。由於是膠囊體,角色控制器不會爬上牆。

Step Offset 角色可以邁上的最高臺階高度,確保對於一個兩米大小的人來說該值介於0.1到0.4之間。

Skin width 面板厚度,面板厚度決定了兩個碰撞器可以互相滲入的深度。較大的面板厚值度會導致顫抖。小的面板厚度值會導致角色被卡住。

實踐中比較好的值是至少要大於0.01並且大於Radius的10%。如果發現你的角色頻繁被卡住,嘗試調整Skin Width值。

Min Move Distance 角色移動距離小於該值,角色就不會移動,避免顫抖現象,建議為0就行

center 調整膠囊體的位置

Radius 膠囊體半徑,

Height 高度

下面來了解下,如何使用CharacterController來控制人物移動,上程式碼!

	void Move(){
		//控制移動
		float h = Input.GetAxis("Horizontal");
		float v = Input.GetAxis("Vertical");
		if(h != 0 || v != 0){
			//angle為人物 繞y軸旋轉的角度
			float angle = Mathf.Atan2(h,v) * Mathf.Rad2Deg;
			targetRotation = Quaternion.Euler(new Vector3(0, angle, 0));
			//旋轉人物方向
			this.transform.rotation = Quaternion.Lerp(this.transform.rotation,targetRotation,Time.deltaTime *25);

			moveSpeed = 3.5f;
			ctrlAnimState = ControlAnimationState.Move;	
		}else{
			moveSpeed = 0;
			ctrlAnimState = ControlAnimationState.Idle;	
		}
//		if(target!=null){
//			this.transform.LookAt(target.transform.position);
//			destinationDistance = Vector3.Distance(target.transform.position,this.transform.position);
//			if(destinationDistance < 1f){
//				moveSpeed = 0f;
//				ctrlAnimState = ControlAnimationState.Idle;	
//				target = null;
//			}else{
//				moveSpeed = 3.5f;
//				ctrlAnimState = ControlAnimationState.Move;	
//			}
//		}

		if(ctrlAnimState == ControlAnimationState.Move){
			if(controller.isGrounded){
				movedir = Vector3.zero;
				movedir = transform.TransformDirection(Vector3.forward*moveSpeed);
			}
		}else
		{		
			movedir = Vector3.Lerp(movedir,Vector3.zero,Time.deltaTime * 10);	
		}
		//應用重力
		movedir.y -= 20 * Time.deltaTime;
		//move
		controller.Move(movedir * Time.deltaTime);	
	}