300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 【原创】Unity3D 模仿《魔兽世界》的第三人称角色控制器

【原创】Unity3D 模仿《魔兽世界》的第三人称角色控制器

时间:2021-08-27 10:33:02

相关推荐

【原创】Unity3D 模仿《魔兽世界》的第三人称角色控制器

玩过《魔兽世界》的朋友都知道,《魔兽世界》中的角色控制器非常的出色,Unity3D 的标准包中自带了第三人称与第一人称角色控制器,但是感觉上面差了很多,下面这个第三人称角色控制器模仿的《魔兽世界》,希望大家喜欢。

与往常一样,我们先来看看最终效果,我们可以通过键盘以及鼠标控制角色旋转、移动,视野拉近拉远等等,如图:

新建一个测试场景,要保证场景中有一个角色对象,如图:

在角色对象中添加一个空对象,取名:HeadItem,主要用来挂载主摄像机,如图:

第三人称角色控制器主要的类有 UPlayerController.cs,代码如下:

usingUnityEngine;usingSystem.Collections;publicclassUPlayerController:MonoBehaviour{///<summary>///待机动画///</summary>publicAnimationClipidleClip;///<summary>///行走动画///</summary>publicAnimationClipwalkClip;///<summary>///跑步动画///</summary>publicAnimationCliprunClip;///<summary>///跳跃动画///</summary>publicAnimationClipjumpClip;///<summary>///后退动画///</summary>publicAnimationClipretreatClip;///<summary>///跑步移动速度///</summary>publicfloatrunSpeed=6.0f;///<summary>///行走移动速度///</summary>publicfloatwalkSpeed=3.0f;///<summary>///后退移动速度///</summary>publicfloatretreatSpeed=2.0f;///<summary>///移动速度///</summary>publicfloatspeed=0f;///<summary>///摄像机对象///</summary>publicTransformcameraTransform;///<summary>///角度头部对象///</summary>publicTransformheadTransform;///<summary>///摄像机偏离距离///</summary>publicfloatcameraDistance=5f;///<summary>///摄像机最近视角///</summary>publicfloatcameraZoomNear=0.01f;///<summary>///摄像机最远视角///</summary>publicfloatcameraZoomFar=30.0f;///<summary>///鼠标移动X坐标轴///</summary>publicfloatmouseXAxis=15.0f;///<summary>///鼠标移动Y坐标轴///</summary>publicfloatmouseYAxis=15.0f;///<summary>///鼠标滚轮速率///</summary>publicfloatmouseWheelVelocity=3.0f;///<summary>///跳起速率///</summary>publicfloatjumpVelocity=15f;///<summary>///下落速率///</summary>publicfloatdropVelocity=10f;///<summary>///摄像机位置修正///</summary>publicfloatcameraReviseDistance=1.0f;///<summary>///最小位置///</summary>publicfloatcameraClampMin=-70f;///<summary>///最大位置///</summary>publicfloatcameraClampMax=90f;///<summary>///偏移角度///</summary>publicfloatoffsetAngle=90f;///<summary>///移动向量,通过计算得来///</summary>protectedVector3moveDirection;///<summary>///垂直速率///</summary>protectedfloatverticalVelocity;///<summary>///屏幕鼠标X坐标///</summary>protectedfloatmouseX;///<summary>///屏幕鼠标Y坐标///</summary>protectedfloatmouseY;///<summary>///前一次鼠标X坐标///</summary>protectedfloatprevMouseX;///<summary>///前一次鼠标Y坐标///</summary>protectedfloatprevMouseY;///<summary>///前一次旋转///</summary>protectedQuaternionprevQuaternion;///<summary>///前一次朝向///</summary>protectedVector3prevForward;///<summary>///是否正在起跳///</summary>protectedboolisJumping;///<summary>///插值转向变量///</summary>protectedfloatmouseXVelocity;///<summary>///插值跳起变量///</summary>protectedfloatcurrentJumpVelocity;///<summary>///角色当前状态///</summary>protectedstringroleActionEnum;///<summary>///Q、E移动向量///</summary>protectedfloathorizontalQEDirection;///<summary>///水平方向向量///</summary>protectedfloathorizontalDirection;///<summary>///垂直方向向量///</summary>protectedfloatverticalDirection;///<summary>///鼠标X属性///</summary>protectedfloatmouseXDirection;///<summary>///鼠标Y属性///</summary>protectedfloatmouseYDirection;///<summary>///鼠标滚轮属性///</summary>protectedfloatmouseScrollWheelDirection;///<summary>///水平移动数据///</summary>protectedfloathorizontalValue;///<summary>///垂直移动数据///</summary>protectedfloatverticalValue;///<summary>///跳起状态///</summary>protectedbooljumpStatus;///<summary>///鼠标左键按下状态///</summary>protectedboolbuttonDownLeftStatus;///<summary>///鼠标左键弹起状态///</summary>protectedboolbuttonUpLeftStatus;///<summary>///鼠标左键状态///</summary>protectedboolbuttonLeftStatus;///<summary>///鼠标右键状态///</summary>protectedboolbuttonRightStatus;///<summary>///左边Shift状态///</summary>protectedboolshiftLeftStatus;///<summary>///右边Shift状态///</summary>protectedboolshiftRightStatus;///<summary>///角色控制器///</summary>privateCharacterControllercharacterController;///<summary>///动画///</summary>privateAnimationanimation;voidAwake(){if(this.cameraTransform==null&&Camera.main!=null)this.cameraTransform=Camera.main.transform;if(this.cameraTransform==null)return;this.characterController=this.GetComponentInChildren<CharacterController>();this.animation=this.GetComponentInChildren<Animation>();this.cameraTransform.parent=this.headTransform;this.cameraTransform.localPosition=Vector3.zero;this.cameraTransform.position=this.transform.position;this.verticalVelocity=0f;this.animation.CrossFade(this.idleClip.name);}///<summary>///初始化输入数据///</summary>protectedvirtualvoidInitInputData(){if(this.cameraTransform==null)return;this.horizontalQEDirection=0f;this.horizontalDirection=Input.GetAxisRaw("Horizontal");this.verticalDirection=Input.GetAxisRaw("Vertical");this.mouseXDirection=Input.GetAxis("MouseX")*this.mouseXAxis;this.mouseYDirection=Input.GetAxis("MouseY")*this.mouseYAxis;this.mouseScrollWheelDirection=Input.GetAxis("MouseScrollWheel");this.buttonDownLeftStatus=Input.GetMouseButtonDown((int)UMouseTypeEnum.LEFT);this.buttonLeftStatus=Input.GetMouseButton((int)UMouseTypeEnum.LEFT);this.buttonRightStatus=Input.GetMouseButton((int)UMouseTypeEnum.RIGHT);this.buttonUpLeftStatus=Input.GetMouseButtonUp((int)UMouseTypeEnum.LEFT);if(!buttonLeftStatus&&Input.GetKey(KeyCode.Q))this.horizontalQEDirection=-1f;if(!buttonLeftStatus&&Input.GetKey(KeyCode.E))this.horizontalQEDirection=1f;this.jumpStatus=Input.GetKey(KeyCode.Space);this.shiftLeftStatus=Input.GetKey(KeyCode.LeftShift);this.shiftRightStatus=Input.GetKey(KeyCode.RightShift);}voidUpdate(){if(this.cameraTransform==null)return;this.InitInputData();//获取地面状态boolgroundStatus=this.IsGrounded();if(groundStatus&&this.jumpStatus&&!this.isJumping){this.isJumping=true;this.verticalVelocity=this.jumpVelocity;}if(this.isJumping&&this.verticalVelocity>=0f){this.verticalVelocity=Mathf.SmoothDamp(this.verticalVelocity,-this.dropVelocity,refthis.currentJumpVelocity,0.15f);}else{this.isJumping=false;this.verticalVelocity=-this.dropVelocity;}//如果按住滚轮if(this.mouseScrollWheelDirection!=0){if(this.cameraDistance>=this.cameraZoomNear&&this.cameraDistance<=this.cameraZoomFar){this.cameraDistance-=this.mouseScrollWheelDirection*this.mouseWheelVelocity;}if(this.cameraDistance<this.cameraZoomNear){this.cameraDistance=this.cameraZoomNear;}if(this.cameraDistance>this.cameraZoomFar){this.cameraDistance=this.cameraZoomFar;}this.cameraDistance=Mathf.Max(0.01f,this.cameraDistance);}//如果鼠标左键按下状态if(this.buttonDownLeftStatus){this.prevMouseX=mouseX;this.prevMouseY=mouseY;this.prevForward=this.cameraTransform.TransformDirection(Vector3.forward);}//如果按下鼠标左键或者按下鼠标右键if(this.buttonLeftStatus||this.buttonRightStatus){this.mouseX+=this.mouseXDirection;this.mouseY+=this.mouseYDirection;}else{this.mouseX+=0f;this.mouseY+=0f;}//如果鼠标左键松开if(this.buttonUpLeftStatus){this.mouseX=this.prevMouseX;this.mouseY=this.prevMouseY;}//如果按下了水平方向键,并且鼠标未按下,左右转换视角if(this.horizontalDirection!=0f&&(!this.buttonLeftStatus&&!this.buttonRightStatus)){if(this.horizontalDirection>0){this.mouseX=Mathf.SmoothDamp(this.mouseX,this.mouseX+90f,refthis.mouseXVelocity,0.2f);}else{this.mouseX=Mathf.SmoothDamp(this.mouseX,this.mouseX-90f,refthis.mouseXVelocity,0.2f);}}//如果按下了水平方向键,并且鼠标右键,左右移动elseif(this.horizontalDirection!=0f&&this.buttonRightStatus){this.horizontalQEDirection=this.horizontalDirection;}this.mouseY=Mathf.Clamp(this.mouseY,this.cameraClampMin,this.cameraClampMax);QuaternionxQuaternion=Quaternion.AngleAxis(this.mouseX,Vector3.up);QuaternionyQuaternion=Quaternion.AngleAxis(this.mouseY,Vector3.left);//当前旋转角度this.prevQuaternion=xQuaternion*yQuaternion;//如果Q、E水平移动if(this.horizontalQEDirection!=0){if(this.verticalDirection!=0f){//如果水平轴大于零,比如按下了D键if(this.horizontalQEDirection>0){xQuaternion=Quaternion.AngleAxis(this.mouseX+this.offsetAngle*0.5f,Vector3.up);}else//如果水平轴小于零,比如按下了A键{xQuaternion=Quaternion.AngleAxis(this.mouseX-this.offsetAngle*0.5f,Vector3.up);}}else{//如果水平轴大于零,比如按下了D键if(this.horizontalQEDirection>0){xQuaternion=Quaternion.AngleAxis(this.mouseX+this.offsetAngle,Vector3.up);}else//如果水平轴小于零,比如按下了A键{xQuaternion=Quaternion.AngleAxis(this.mouseX-this.offsetAngle,Vector3.up);}}}if(!this.buttonLeftStatus){this.transform.rotation=xQuaternion;}//摄像机对象的偏离位置,相对于角色头部位置this.cameraTransform.localPosition=newVector3(0f,0f,this.headTransform.transform.localPosition.z-this.cameraDistance);//如果按住了Shift键if(this.shiftLeftStatus||this.shiftRightStatus){this.speed=this.walkSpeed;this.roleActionEnum=URoleActionEnum.WALK;}else{this.speed=this.runSpeed;this.roleActionEnum=URoleActionEnum.RUN;}if(verticalDirection<0f){this.speed=this.retreatSpeed;this.roleActionEnum=URoleActionEnum.RETREAT;}this.horizontalValue=this.horizontalQEDirection*this.speed*Time.deltaTime;this.verticalValue=this.verticalDirection*this.speed*Time.deltaTime;//如果在跳起状态if(this.isJumping)this.roleActionEnum=URoleActionEnum.JUMP;if(this.horizontalQEDirection==0f&&this.horizontalDirection==0f&&this.verticalValue==0f&&!this.isJumping)this.roleActionEnum=URoleActionEnum.IDLE;Vector3forward=this.cameraTransform.TransformDirection(Vector3.forward);if(this.buttonLeftStatus)forward=this.prevForward;forward.y=0;forward=forward.normalized;Vector3right=newVector3(forward.z,0,-forward.x);//设置移动向量this.moveDirection=this.horizontalValue*right+this.verticalValue*forward+newVector3(0,this.verticalVelocity*Time.deltaTime,0);//设置对象状态动画this.ChangeAction(this.roleActionEnum);this.characterController.Move(this.moveDirection);}privatevoidChangeAction(stringroleActionEnum){if(roleActionEnum==URoleActionEnum.IDLE){this.animation.CrossFade(this.idleClip.name);}elseif(roleActionEnum==URoleActionEnum.WALK){this.animation.CrossFade(this.walkClip.name);}elseif(roleActionEnum==URoleActionEnum.RUN){this.animation.CrossFade(this.runClip.name);}elseif(roleActionEnum==URoleActionEnum.JUMP){this.animation.CrossFade(this.jumpClip.name);}elseif(roleActionEnum==URoleActionEnum.RETREAT){this.animation.CrossFade(this.retreatClip.name);}}voidLateUpdate(){if(this.cameraTransform==null)return;//设置头部旋转this.headTransform.rotation=this.prevQuaternion;//下面代码保证视角内没有透视区域RaycastHithitCamera=newRaycastHit();RaycastHit[]hits=Physics.SphereCastAll(this.headTransform.position,0.3f*0.5f,-this.cameraTransform.forward,this.cameraDistance);hitCamera.distance=Mathf.Infinity;foreach(RaycastHithitinhits){//判断是否是地形Terrainterrain=hit.transform.GetComponent<Terrain>();if(hit.distance<hitCamera.distance&&hit.transform!=this.transform.transform&&terrain!=null){boolfound=false;if(this.transform.transform.childCount>0){foreach(TransformchildTransforminthis.transform){if(hit.transform==childTransform){found=true;break;}}}if(!found)hitCamera=hit;}}if(hitCamera.distance!=Mathf.Infinity){this.cameraDistance-=this.cameraReviseDistance;}}protectedvirtualboolIsGrounded(){return(this.characterController.collisionFlags==CollisionFlags.CollidedBelow);}}

UMouseTypeEnum.cs 代码如下:

usingUnityEngine;usingSystem.Collections;publicenumUMouseTypeEnum{LEFT=0,RIGHT=1}

URoleActionEnum.cs 代码如下:

usingUnityEngine;usingSystem.Collections;publicclassURoleActionEnum{publicconststringIDLE="idle";publicconststringWALK="walk";publicconststringRUN="run";publicconststringRETREAT="retreat";publicconststringJUMP="jump";publicconststringATTACK="attack";publicconststringMAGIC="magic";publicconststringDIE="die";}

然后给角色对象挂载 CharacterController 组件 和 UPlayerController.cs,如图:

运行游戏,我们就可以灵活的控制角色在场景中移动、旋转了!

下载地址:链接: /s/1kTzlYWB 密码: aa8r

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。