zoukankan      html  css  js  c++  java
  • Unity模拟龙之谷人物行走简单控制

    我个人挺喜欢龙之谷(DN)的人物控制的(不是广告哈....),就是人物太萌了一点,动作、打击感都挺好的。

    今天用Unity简单模仿了一下DN的人物控制,当然,游戏里面动作非常多,我这里仅仅做了简单的walk和run的測试哈,可是感觉也蛮舒服的,哈哈。

    期待的效果:鼠标旋转控制视角位置,滚轮控制镜头缩放。点击一次W键为行走,高速点击两次为奔跑。

    1.准给工作:

    场景中,

    一个Camera、一块地皮、一仅仅Cube



    2.镜头的缩放和旋转实现:

    看下Camera的组件:


    再看下Cube的组件:


    mouselook和smoothfollow的脚本就不贴出来了,都有的。

    为了方便,以下是NMove和TestMove的代码:

    using UnityEngine;
    using System.Collections;
    
    public class NMove : MonoBehaviour {
    
        //注意,開始之所以在滑动滚轮的时候,相机是抛物线的形式靠近/远离目标的,原因是,目标模型的中心点设置在了脚底。
        //解决方法:设置初始时,相机的高度与人物模型中心的高度一致,就可以!
        public int MouseWheelSensitivity = 5;   //鼠标敏感度
        public int MouseZoomMin = 2;            //最小值
        public int MouseZoomMax = 10;           //最大值
        public float normalDistance;            //正常距离
        public GameObject Camera;
        smooth_follow CameraScript;     
    	// Use this for initialization
    	void Start () 
        {
            CameraScript = Camera.GetComponent<smooth_follow>();	
    	}		
        void LateUpdate()
        {
            if (Input.GetAxis("Mouse ScrollWheel") != 0)        //转动了滚轮
            {
                Debug.Log(Input.GetAxis("Mouse ScrollWheel"));
                //Debug.Log(distance);
                if (normalDistance >= MouseZoomMin && normalDistance <= MouseZoomMax)
                {
                    normalDistance -= Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity;
                }
                if (normalDistance < MouseZoomMin)
                {
                    normalDistance = MouseZoomMin;
                }
                if (normalDistance > MouseZoomMax)
                {
                    normalDistance = MouseZoomMax;
                }
                CameraScript.distance = normalDistance;
            }
        }
    }
    
    TestMove.cs:

    using UnityEngine;
    using System.Collections;
    
    public class TestMove : MonoBehaviour {
    
        public float speed = 1.0f;
        public GameObject camera;
    	//当按下行走坐标后,物体旋转至camera的方向
        public float rospeed = 1.0f;    //rotate speed
    	// Update is called once per frame
    	void Update () {
            if (Input.GetKey(KeyCode.W | KeyCode.S | KeyCode.A | KeyCode.D))
            { 
                //按下了行走键,旋转            
                transform.rotation = Quaternion.Slerp(transform.rotation,camera.transform.rotation ,Time.deltaTime*rospeed);        
                transform.eulerAngles = new UnityEngine.Vector3(0,transform.eulerAngles.y,transform.eulerAngles.z);
                //notice only Quaternion have Slerp methods.
            }
            if (Input.GetKey(KeyCode.W))
            {
                this.transform.Translate(Vector3.forward*Time.deltaTime*speed);
            }
            if (Input.GetKey(KeyCode.S))
            {
                this.transform.Translate(Vector3.forward * Time.deltaTime * speed * -1);
            }
            if (Input.GetKey(KeyCode.D))
            {
                this.transform.Translate(Vector3.right * Time.deltaTime * speed);
            }
            if (Input.GetKey(KeyCode.A))
            {
                this.transform.Translate(Vector3.right * Time.deltaTime * speed * -1);
            }
    
    	
    	}
    }
    

    OK,如今你的Cube角色已经活动自如了!

    注意,我这里用Cube由于是标准的立方体,主要是为了方便。

    3.加入你喜欢的人物模型,制作状态机,使Cube成为其父物体:



    状态机:



    以下是PlayerSM(state machine)的代码:

    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// @author ZJC  player state machine study note 
    /// 问题:
    /// 1.怎样实现对同一按键点击两次run,点击一次walk?设置一个信号signal进行区分.要注意按键的逻辑顺序问题,这是关键
    /// 2.人物转身的时候,有点斜着飘
    /// (恩,这个问题解决,就是girl的父物体,我用了一个标准的cube,这样cube旋转的时候,就不会有那种斜着旋转的效果了,girl也就不会了。
    /// </summary>
    public class PlayerSM : MonoBehaviour {
    
        private Animator animator;    
        // 动画状态机參数Key
        private static readonly string ActionCMD = "ActionCMD";
        private static readonly string Run = "run";   
        float timefirst = 0f;   //记录按下W的时间
        float timesecond = 0f;
        int n = 0;
        bool runsignal = false;
        public float KeyTime = 0.3f;
        void Start()
        {
            animator = this.GetComponent<Animator>();   
        }	
    	// Update is called once per frame
        void Update ()
        {
           
            AnimatorStateInfo stateinfo = animator.GetCurrentAnimatorStateInfo(0);         
            if (Input.GetKey(KeyCode.W))
            {
           
                print("runsigl = "+runsignal);
                if ( !runsignal ) 
                {
                    animator.SetInteger(ActionCMD, 1);
           
                } 
                else
                {                
                    animator.SetInteger(Run, 1);
                    animator.SetInteger(ActionCMD, 0);
                    print("wwwww+runsigal = " + runsignal);
                }           
            }    
            if (Input.GetKeyDown("w") ) 
            {
              //  print("up.....");
               // runsignal = false;
            
                    if (n == 0)
                    {
                        timefirst = Time.time;
                        n++;
                    }
                    else if (n == 1)
                    {
                        timesecond = Time.time;
                        n = 0;
                    }
                    if (Mathf.Abs(timesecond - timefirst) <= KeyTime)
                    {
                        // print("wreff");
                        animator.SetInteger(Run, 1);
                        print("run = 1..........................");
                        runsignal = true;
                    }            
             
            }
            if(!Input.anyKey)   //仅仅要按下了键(包含持续按键),就为真,否则为false
            {
                //參数清0      
                animator.SetInteger(ActionCMD, 0);
                animator.SetInteger(Run, 0);
                runsignal = false;         
    
            }
           
    	}
    }
    

    4.隐藏掉cube的mesh render.再測试,OK!

    效果:鼠标位置控制旋转视角、滚轮控制视角缩放、点击一次W人物行走,高速点击两次奔跑,无按键为idle状态。




  • 相关阅读:
    【L.M.W.Y.D】Scrum Meeting 2
    【L.M.W.Y.D】Scrum Meeting 1
    L.M.W.Y.D 实验八 团队作业4—团队项目需求建模与系统设计
    L.M.W.Y.D 实验七 团队作业3:团队项目需求分析与原型设计
    L.M.W.Y.D 实验六 团队作业2:健康管理系统
    L.M.W.Y.D 实验五 团队作业1:软件研发团队组建与软件案例分析
    多喝热水 [Alpha] Scrum Meeting 3
    多喝热水 [Alpha] Scrum Meeting 2
    多喝热水 [Alpha] Scrum Meeting 1
    多喝热水 实验八 团队作业4:团队项目需求建模与系统设计
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4533762.html
Copyright © 2011-2022 走看看