Unity的三種人物移動方式(ET,鍵盤,鼠標點擊)

核心都是求出輸出input的移動方向乘以給定的速度乘以時間間隔,以一定角速度進行旋轉來計算。注意這裏的CamCtrl的rotation是和主角的forward前方是一致的。過段時間發Camera的設計試試看。

Unity 三種常用人物移動方式,手機觸屏移動,鍵盤移動,鼠標點擊移動,在不同類型的遊戲中就可能會用到,不過不管是哪種移動方式,都是根據玩家的輸入來獲得主角移動的朝向:x方向,y方向,在根據主角的角速度,移動速度來每幀改變主角的朝向和行走。

ET移動:

//使用ET Move
            float axisXValue = _RoleFSMMgr.RoleCtrl.JoyStick.axisX.axisValue;
            float axisYValue = _RoleFSMMgr.RoleCtrl.JoyStick.axisY.axisValue;
            speed = (Mathf.Abs(axisXValue) >Math.Abs(axisYValue)) ? axisXValue : axisYValue;  //選擇按的最大的哪一個按鍵來判斷主角是不是全力衝刺
            speed = Mathf.Abs(speed);
            if (axisXValue != 0 || axisYValue != 0)
            {
                Vector3 _Dir = new Vector3(axisXValue, 0, axisYValue);
                _Dir = _Dir.normalized;  //獲得方向
                _Dir = CamCtrl.Instance.transform.rotation * _Dir;
                Quaternion q = Quaternion.LookRotation(_Dir);
                if (Quaternion.Angle(_RoleFSMMgr.RoleCtrl.transform.rotation, q) > 1)
                {
                    _RotSpeed += 10 * Time.deltaTime;
                    _RoleFSMMgr.RoleCtrl.transform.rotation = Quaternion.Slerp(_RoleFSMMgr.RoleCtrl.transform.rotation, q, _RotSpeed);
                }
                else
                {
                    _RotSpeed = 0;
                }
                _RoleFSMMgr.RoleCtrl.CC.Move(new Vector3(_Dir.x, _Gravity, _Dir.z) * _MoveSpeed * Time.deltaTime*speed);
            }

手機上我都是使用EasyTouch的,放在有限狀態機中的RoleStateMove狀態腳本中,可以每幀的隨時更新主角的行動信息。這裏我的角速度是每幀加10*Time.deltaTime到1的時候就朝向一致了,我使用CharacterController的Move方法來控制移動,通過Gravity來讓主角一直處於地面,因爲攝像機也是有旋轉的,爲了讓角度的計算不是始終都是絕對座標軸來算,這裏特地乘以攝像機的旋轉,以攝像機視角爲前方計算。

鍵盤:

//使用KeyBoard Move
            if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
            {
                float hh = Input.GetAxis("Horizontal");
                float vv = Input.GetAxis("Vertical");
                speed = (Mathf.Abs(hh)>Mathf.Abs(vv)) ? hh : vv;
                speed = Mathf.Abs(speed);
                _Dir = new Vector3(hh, 0, vv);
                _Dir = _Dir.normalized;
                _Dir = CamCtrl.Instance.transform.rotation * _Dir;
                Quaternion q = Quaternion.LookRotation(_Dir);
                if (Quaternion.Angle(_RoleFSMMgr.RoleCtrl.transform.rotation, q) > 1)
                {
                    _RotSpeed += 10 * Time.deltaTime;
                    _RoleFSMMgr.RoleCtrl.transform.rotation = Quaternion.Slerp(_RoleFSMMgr.RoleCtrl.transform.rotation, q, _RotSpeed);
                }
                else
                {
                    _RotSpeed = 0;
                }
                _RoleFSMMgr.RoleCtrl.CC.Move(new Vector3(_Dir.x,_Gravity,_Dir.z)*_MoveSpeed*Time.deltaTime*speed);
            }

鍵盤除了獲得X,Y方向的方法不一樣以外,其餘都是和EasyTouch一樣的。

鼠標點擊:

 //使用A* Path Auto Move
        if (_RoleFSMMgr.RoleCtrl.APath!=null)
        {
            speed = 1;
            if (_RoleFSMMgr.RoleCtrl.CurWayPointIndex>=_RoleFSMMgr.RoleCtrl.APath.vectorPath.Count)
            {
                _RoleFSMMgr.RoleCtrl.ToIdle();
                _RoleFSMMgr.RoleCtrl.CurWayPointIndex = 1;
                _RoleFSMMgr.RoleCtrl.APath = null;
                return;
            }
            else
            {
                _NextPos = new Vector3(_RoleFSMMgr.RoleCtrl.APath.vectorPath[_RoleFSMMgr.RoleCtrl.CurWayPointIndex].x, _RoleFSMMgr.RoleCtrl.transform.position.y, _RoleFSMMgr.RoleCtrl.APath.vectorPath[_RoleFSMMgr.RoleCtrl.CurWayPointIndex].z);
                _Dir = _NextPos - _RoleFSMMgr.RoleCtrl.transform.position;
                _Dir = _Dir.normalized;
                Quaternion q = Quaternion.LookRotation(_Dir);
                if (Quaternion.Angle(_RoleFSMMgr.RoleCtrl.transform.rotation,q)>1)
                {
                    _RotSpeed += 10 * Time.deltaTime;
                    _RoleFSMMgr.RoleCtrl.transform.rotation = Quaternion.Slerp(_RoleFSMMgr.RoleCtrl.transform.rotation,q,_RotSpeed);
                }
                else
                {
                    _RotSpeed = 0;
                }
                _RoleFSMMgr.RoleCtrl.CC.Move(new Vector3(_Dir.x, _Gravity, _Dir.z) * _RoleFSMMgr.RoleCtrl.RoleInfo.MoveSpeed * Time.deltaTime * speed);
                if (Vector3.Distance(_NextPos, _RoleFSMMgr.RoleCtrl.transform.position) < _RoleFSMMgr.RoleCtrl.RoleInfo.MoveSpeed * Time.deltaTime + .2f)
                {
                    _RoleFSMMgr.RoleCtrl.CurWayPointIndex++;
                }
            }
        }

鼠標點擊自然是要先通過A*計算出路徑來,根據下一個要行走的點和角色當前的位置算出移動的向量方向,再向前面說的那樣移動就好了,等到了目標點之後就要切換下一個目標點,直到終點讓路徑爲NULL。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章