unity3d仿仙剑角色控制

来源:互联网 发布:linux查看snmp团体名 编辑:程序博客网 时间:2024/06/06 05:54

       沉了一段时间,又开始写脚本了。前段时间跑去研究Ruby去了,现在又可以用unity3d挖坑了。近段时间学了点截取模型的软件,一个叫做disunity的神奇软件,可以截取任何用unity开发的游戏模型,于是就兴高采烈的去截取了仙剑和轩辕剑。可是这软件有很大的弊端截取出来的模型不是整体的,而是零散的,这就意味着需要导入3dsMax中重新组合和贴图,如果想要截取一个场景这该是多么浩大的一个工程?还有disunity不能截取动画,原本以为截取出来的今朝和司空宇模型能用别的状态机做动画控制,可是本身没有bone,也就只能白开心一场了,先上图再说。


      只能说眼睛贴图没贴好,disunity想学可以自行百度。

      段时间仿照仙剑的角色控制写了点脚本,根据多年的玩家经验。无非就是WASD控制角色移动,LeftShift切换角色跑步,QE旋转角色视觉,鼠标右键移动摄像机视角,轮滚缩放视角这样的。可是遗憾的是,我用的这个模型没有“跳起来”(Jump)的动画,所以这块控制功能没做。说起来容易,编写的过程中却发现很多问题,下面来看脚本。虽然写的脚本好像有点多,但是相对于其他大神写的还算是比较容易理解的。

using UnityEngine;using System.Collections;public class PlayerControl : MonoBehaviour {private CharacterController controller;public float speed=0.8f;//定义走的速度public float runspeed=1.6f;//定义跑的速度private int moveDirection = 1;//定义向前的方向为正private float movespeed=0;//用来计算上下移动的速度变量private float Movespeed=0;//用来计算左右移动的速度变量public bool isrun=false;//一开始跑步设置为falseprivate Animator anim;void Start () {//获取角色控制器,需要在角色上添加Character Controller组件controller = GetComponent<CharacterController> ();anim = GetComponent<Animator> ();}// Update is called once per framevoid Update () {move ();}void move(){   //定义forward和right分别记录上下和左右的方向Vector3 forward = transform.TransformDirection (Vector3.forward);Vector3 right = transform.TransformDirection (Vector3.right);//按下左键可以切换跑步,再按左键可以切换回走路if (isrun == false && Input.GetKeyDown (KeyCode.LeftShift)) {isrun = true;} else if (isrun == true && Input.GetKeyDown (KeyCode.LeftShift)) {isrun = false;}    if (Input.GetKey (KeyCode.W)) {moveDirection = 1;if (isrun == false) {anim.SetInteger ("animationID", 1);movespeed = moveDirection * speed;} elseanim.SetInteger ("animationID", 5);movespeed = moveDirection * runspeed;} else if (Input.GetKey (KeyCode.S)) {moveDirection = -1;if (isrun == false) {anim.SetInteger ("animationID", 2);movespeed = moveDirection * speed;} elseanim.SetInteger ("animationID", 6);movespeed = moveDirection * runspeed;} else if (Input.GetKey (KeyCode.A)) {moveDirection = -1;if (isrun == false) {anim.SetInteger ("animationID", 3);Movespeed = moveDirection * speed;} elseanim.SetInteger ("animationID", 7);Movespeed = moveDirection * runspeed;} else if (Input.GetKey (KeyCode.D)) {moveDirection = 1;if (isrun == false) {anim.SetInteger ("animationID", 4);Movespeed = moveDirection * speed;} elseanim.SetInteger ("animationID", 8);Movespeed = moveDirection * runspeed;}  //任何按键不被按下,切换idle默认动画   else if (Input.anyKey == false) {anim.SetInteger ("animationID", 0);}  //当移动的按键不被按下,速度计算清0,否则不按键盘角色也会移动   if (Input.GetKeyUp (KeyCode.W) || Input.GetKeyUp (KeyCode.S)          ||Input.GetKeyUp (KeyCode.A) || Input.GetKeyUp (KeyCode.D)) {movespeed = 0;Movespeed = 0;}   //角色SimpleMove移动方法调用    controller.SimpleMove (forward * movespeed);    controller.SimpleMove (right * Movespeed);}}


           写好脚本赋予给角色模型,并且给角色添加角色控制器Character Controller组件。下面来看摄像机的脚本。

using UnityEngine;using System.Collections;public class CameraF : MonoBehaviour{public Transform target;//定义视角目标public float targetHeight = 0.5f;//摄像机视角高度public float distance = 2.0f;//运行游戏初始化摄像机距离public float maxDistance = 3.0f;//缩放最大距离public float minDistance = 1.0f;//缩放最小距离public float xSpeed = 150.0f;//(左右)X轴旋转速度public float ySpeed = 120.0f;//(上下)Y轴旋转速度public int yMinLimit = -30;//(上下)Y旋转最小距离public int yMaxLimit = 60;//(上下)Y旋转最大距离public int zoomRate = 10;//轮滚缩放速度//上面参数可以根据模型大小需求更改public float zoomDampening = 10.0f;private float x = 0.0f;private float y = 0.0f;private float currentDistance;private float desiredDistance;private float correctedDistance;private bool grounded = false;private Animator anim;void Start (){   anim = target.GetComponent<Animator> ();Vector3 angles = transform.eulerAngles;x = angles.x;y = angles.y;currentDistance = distance;desiredDistance = distance;correctedDistance = distance - 0.2f;if (GetComponent<Rigidbody>())GetComponent<Rigidbody>().freezeRotation = true;}void Update(){   //当按右键旋转视角时,同时播放角色一个走的动画if (Input.GetMouseButton (1)) {anim.SetInteger ("animationID", 1);}}void LateUpdate (){   //按下右键旋转摄像机视角if (Input.GetMouseButton(1)){x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;  //目标角色随着(左右)X轴水平旋转    target.rotation=Quaternion.Euler(new Vector3(0,x,0));}y = ClampAngle(y, yMinLimit, yMaxLimit);Quaternion rotation = Quaternion.Euler(y, x, 0);//轮滚缩放摄像机视角desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);correctedDistance = desiredDistance;Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance + new Vector3(0, -targetHeight, 0));RaycastHit collisionHit;Vector3 trueTargetPosition = new Vector3(target.position.x, target.position.y + targetHeight, target.position.z);bool isCorrected = false;if (Physics.Linecast(trueTargetPosition, position, out collisionHit)){if(collisionHit.transform.name!=target.name){position = collisionHit.point;correctedDistance = Vector3.Distance(trueTargetPosition, position);isCorrected = true;}}currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;position = target.position - (rotation * Vector3.forward * currentDistance + new Vector3(0, -targetHeight - 0.05f, 0));transform.rotation = rotation;transform.position = position;}private static float ClampAngle(float angle, float min, float max){if (angle < -360)angle += 360;if (angle > 360)angle -= 360;return Mathf.Clamp(angle, min, max);}}
             写好脚本赋予给主摄像机并且调整好其位置。然后创建一个Animator Controller,设置好动画连接条件。把Animator Controller赋予给角色,并且也把Apply Root Motion设置为false吧,否则角色移动起来会卡。

      

     下面来看运行效果,因为博客限制GIF大小不超过2M,也只有这么点GIF了。


0 0
原创粉丝点击