Unity3D游戏开发之仿仙剑奇侠传角色控制效果Word文档下载推荐.docx
《Unity3D游戏开发之仿仙剑奇侠传角色控制效果Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Unity3D游戏开发之仿仙剑奇侠传角色控制效果Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。
承君此诺,必守一生。
好了,我们正式开始技术分享(博主内心有很多话想说)!
在仙剑奇侠传四中,玩家可以通过鼠标右键来旋转场景(水平方向),按下前进键时角色将向着朝前(Forward)的方向运动,按下后退键时角色将向着朝后(Backword)的方向运动、当按下向左、向右键时角色将向左、向右旋转90度。
从严格意义上来说,仙剑四不算是一部完全的3D游戏,因为游戏视角是锁死的,所以玩家在平时跑地图的时候基本上是看不到角色的正面的。
我们今天要做的就是基于Unity3D来做这样一个角色控制器。
虽然Unity3D为我们提供了第一人称角色控制器和第三人称角色控制器,但是博主感觉官方提供的第三人称角色控制器用起来感觉怪怪的,尤其是按下左右键时那个旋转,感觉控制起来很不容易,所以博主决定自己来写一个角色控制器。
首先我们打开项目,我们还是用昨天的那个例子:
很多朋友可能觉得控制角色的脚本很好写嘛,这是一个我们通常见到的版本:
1./向左2.if(Input.GetKey(KeyCode.A)3.4.SetAnimation(LeftAnim);
5.this.mState=PersonState.Walk;
6.mHero.transform.Translate(Vector3.right*Time.deltaTime*mSpeed);
7.8./向右9.if(Input.GetKey(KeyCode.D)10.11.SetAnimation(RightAnim);
12.this.mState=PersonState.Walk;
13.mHero.transform.Translate(Vector3.right*Time.deltaTime*(-mSpeed);
14.15./向上16.if(Input.GetKey(KeyCode.W)17.18.SetAnimation(UpAnim);
19.this.mState=PersonState.Walk;
20.mHero.transform.Translate(Vector3.forward*Time.deltaTime*(-mSpeed);
21.22./向下23.if(Input.GetKey(KeyCode.S)24.25.SetAnimation(DownAnim);
26.this.mState=PersonState.Walk;
27.mHero.transform.Translate(Vector3.forward*Time.deltaTime*(mSpeed);
28.Vector3mHeroPos=mHero.transform.position;
29.复制代码那么,我们姑且认为这样写没什么问题,那么现在我们导入官方提供的Script脚本资源包,找到MouseLook脚本,在Update()方法中添加对右键是否按下的判断,这样我们就可以实现按下鼠标右键时视角的旋转。
修改后的脚本如下:
1.2.usingUnityEngine;
3.usingSystem.Collections;
4.5./MouseLookrotatesthetransformbasedonthemousedelta.6./MinimumandMaximumvaluescanbeusedtoconstrainthepossiblerotation7.8./TomakeanFPSstylecharacter:
9./-Createacapsule.10./-AddtheMouseLookscripttothecapsule.11./-SetthemouselooktouseLookX.(Youwanttoonlyturncharacterbutnottiltit)12./-AddFPSInputControllerscripttothecapsule13./-ACharacterMotorandaCharacterControllercomponentwillbeautomaticallyadded.14.15./-Createacamera.Makethecameraachildofthecapsule.Resetitstransform.16./-AddaMouseLookscripttothecamera.17./-SetthemouselooktouseLookY.(Youwantthecameratotiltupanddownlikeahead.Thecharacteralreadyturns.)18.AddComponentMenu(Camera-Control/MouseLook)19.publicclassMouseLook:
MonoBehaviour20.21.publicenumRotationAxesMouseXAndY=0,MouseX=1,MouseY=222.publicRotationAxesaxes=RotationAxes.MouseXAndY;
23.publicfloatsensitivityX=15F;
24.publicfloatsensitivityY=15F;
25.26.publicfloatminimumX=-360F;
27.publicfloatmaximumX=360F;
28.29.publicfloatminimumY=-60F;
30.publicfloatmaximumY=60F;
31.32.floatrotationY=0F;
33.34.voidUpdate()35.36.if(Input.GetMouseButton
(1)37.38.if(axes=RotationAxes.MouseXAndY)39.40.floatrotationX=transform.localEulerAngles.y+Input.GetAxis(MouseX)*sensitivityX;
41.42.rotationY+=Input.GetAxis(MouseY)*sensitivityY;
43.rotationY=Mathf.Clamp(rotationY,minimumY,maximumY);
44.45.transform.localEulerAngles=newVector3(-rotationY,rotationX,0);
46.47.elseif(axes=RotationAxes.MouseX)48.49.transform.Rotate(0,Input.GetAxis(MouseX)*sensitivityX,0);
50.51.52.else53.54.rotationY+=Input.GetAxis(MouseY)*sensitivityY;
55.rotationY=Mathf.Clamp(rotationY,minimumY,maximumY);
56.57.transform.localEulerAngles=newVector3(-rotationY,transform.localEulerAngles.y,0);
58.59.60.61.62.voidStart()63.64./Maketherigidbodynotchangerotation65.if(rigidbody)66.rigidbody.freezeRotation=true;
67.68.69.复制代码接下来,我们将这个脚本拖放到我们的角色上,运行游戏,我们发现了一个问题:
当旋转视角后,角色并没有如我们期望地向朝前的方向移动,相反,角色依然沿着世界坐标系里的Vector3.forward向前运动。
按照我们的想法,当旋转视角以后,角色应该可以朝着前方运动。
怎么办呢?
这里我们在上面的代码中加上这样的代码:
1.2./计算旋转角3.if(Input.GetMouseButton
(1)4.5./计算水平旋转角6.mAngles+=Input.GetAxis(MouseX)*15;
7./旋转角色8.transform.rotation=Quaternion.Euler(newVector3(0,mAngles,0);
9.10.复制代码这里代码的作用是当用户按下鼠标右键旋转视角时,我们首先计算在水平上的旋转角,然后让角色的坐标系跟着视角一起旋转,这样就相当于把Vector3.forward和旋转后的目标角度平行。
这样的话,我们控制人物向前运动的时候,它就会按照这个新的方向去运动。
这样我们的第一个问题就解决了。
我们继续往下看,由于这个模型中只提供了一个行走/奔跑的方向动画,所以就出现了角色动画和角色行为不符的问题,怎么办呢?
这时候,我们可以这样想,我们可以先把角色旋转到指定的方向,然后让角色朝着向前的方向运动,这样角色动画和角色行为就可以相互对应起来了。
为此我们做下面的工作:
1./角色行动方向枚举2.publicenumPersonDirection3.4./正常向前5.Forward=90,6./正常向后7.Backward=270,8./正常向左9.Left=180,10./正常向右11.Right=0,12.复制代码我们这里定义了四个方向上的角度,当我们角色旋转到Forward方向时,我们根据用户按下的键,来判断角色要向那个方向旋转:
1.privatevoidSetPersonDirection(PersonDirectionmDir)2.3./根据目标方向与当前方向让角色旋转4.if(mDirection!
=mDir)5.6.transform.Rotate(Vector3.up*(mDirection-mDir);
7.mDirection=mDir;
8.9.复制代码在该方法中,如果目标方向大于当前方向,那么角色将逆时针旋转,否则将顺时针旋转,角度差值为0,则不旋转。
好了,现在角色已经旋转到相应的方向了,我们让它朝前运动:
1.transform.Translate(Vector3.forward*WalkSpeed*Time.deltaTime);
复制代码接下来我们为角色定义状态枚举值:
1./角色状态枚举2.publicenumPersonState3.4.idle,5.run,6.walk,7.jump,8.attack9.复制代码我们在上面的代码上面做修改,最终形成的代码为:
4.5.publicclassRPGControl:
MonoBehaviour6.7./定义角色动画8.privateAnimationmAnimation;
9./定义角色状态10.publicPersonStatemState=PersonState.idle;
11./定义方向状态12.publicPersonDirectionmDirection=PersonDirection.Forward;
13./定义角色弹跳量14.publicfloatmJumpValue=2F;
15./定义旋转角16.privatefloatmAngles;
17./定义相机18.publicGameObjectmCamera;
19./定义角色行动方式20.publicPersonStateRunOrWalk=PersonState.walk;
21.22.publicfloatWalkSpeed=1.5F;
23.publicfloatRunSpeed=3.0F;
24./角色状态枚举25.publicenumPersonState26.27.idle,28.run,29.walk,30.jump,31.attack32.33./角色行动方向枚举34.publicenumPersonDirection35.36./正常向前37.Forward=90,38./正常向后39.Backward=270,40./正常向左41.Left=180,42./正常向右43.Right=0,44.45.46.voidStart()47.48./获取动画49.mAnimation=gameObject.GetComponent();
50.51.52.voidUpdate()53.54./前进55.if(Input.GetKey(KeyCode.W)56.57.SetPersonDirection(PersonDirection.Forward);
58.SetPersonAnimation();
59.60./后退61.if(Input.GetKey(KeyCode.S)62.63.SetPersonDirection(PersonDirection.Backward);
64.SetPersonAnimation();
65.66./向左67.if(Input.GetKey(KeyCode.A)68.69.SetPersonDirection(PersonDirection.Left);
70.SetPersonAnimation();
71.72./向右73.if(Input.GetKey(KeyCode.D)74.75.SetPersonDirection(PersonDirection.Right);
76.SetPersonAnimation();
77.78./巡逻或等待79.if(Input.GetKeyUp(KeyCode.A)|Input.GetKeyUp(KeyCode.D)|Input.GetKeyUp(KeyCode.S)|Input.GetKeyUp(KeyCode.W)|Input.GetKeyUp(KeyCode.Space)80.81.mAnimation.Play(idle);
82.mState=PersonState.idle;
83.84./跳跃85.if(Input.GetKey(KeyCode.Space)86.87.transform.GetComponent().AddForce(Vector3.up*mJumpValue,ForceMode.Force);
88.mAnimation.Play(Jump);
89.mState=PersonState.jump;
90.91./攻击92.if(Input.GetMouseButton(0)93.94.mAnimation.Play(Attack);
95.mState=PersonState.attack;
96.StartCoroutine(ReSetState);
97.98./计算旋转角99.if(Input.GetMouseButton
(1)100.101./计算水平旋转角102.mAngles+=Input.GetAxis(MouseX)*15;
103./旋转角色104.transform.rotation=Quaternion.Euler(newVector3(0,mAngles,0);
105.106.107.108.privatevoidSetPersonDirection(PersonDirectionmDir)109.110./根据目标方向与当前方向让角色旋转111.if(mDirection!
=mDir)112.113.transform.Rotate(Vector3.up*(mDirection-mDir);
114.mDirection=mDir;
115.116.117.118.privatevoidSetPersonAnimation()119.120.if(RunOrWalk=PersonState.walk)121.122.mAnimation.Play(Walk);
123.mState=PersonState.walk;
124.transform.Translate(Vector3.forward*WalkSpeed*Time.deltaTime);
125.126.elseif(RunOrWalk=PersonState.run)127.128.mAnimation.Play(Run);
129.mState=PersonState.run;
130.transform.Translate(Vector3.forward*RunSpeed*Time.deltaTime);
131.132.133.134.IEnumeratorReSetState()135.136./当攻击动画播放完毕时,自动切换到巡逻状态137.yieldreturnnewWaitForSeconds(mAnimation.clip.length);
138.mAnimation.Play(idle);
139.mState=PersonState.idle;
140.141.142.143.复制代码其中,SetPersonAnimation()方法将根据RunOrWalk值来决定角色是采用行走还是奔跑的方式移动。
最后,我们加上一个摄像机跟随的脚本SmoothFollow,这个脚本在官方提供的Script资源包里,我们把该脚本绑定到主摄像机上,并设定我们的角色为其跟随目标。