文章目录

  • 一、最近的感想
  • 二、Movement
  • 1)创建平面去移动
  • 2)导入人物模型
  • 3)安装unity的输入安装包
  • 4)设置unity的输入 系统(涉及到三个脚本)
  • (1)涉及到的脚本
  • (2)设定PlayerControl是的监听哪些键盘按键(InputHandler.cs)
  • 5)人物碰撞和刚体
  • 6)人物移动模块和输入脚本(player_locomotion)
  • 7)动画脚本控制
  • 8)动画控制和人物执行动画帧控制
  • 三、一些名词解释


一、最近的感想

最近有点疑惑,想做好个mmorpg的服务器程序员,至少得会点客户端的东西,所以想参考下油管上制作黑魂向的指导视频学习下,小哥叫做SebastianGraves,传送门,另外在docker学习结束后,还会进行nginx搭建和对原理的简单了解博客撰写。

二、Movement

sebastian小哥的视频传送门

1)创建平面去移动

unity 接入视频监控 avpro_unity 接入视频监控 avpro


但是这样没地板图纹很硬核,所以得先该变下纹理

unity 接入视频监控 avpro_学习_02


改名为Floor_MAT,并选择纹理

unity 接入视频监控 avpro_Time_03


并选择格子的大小为5x5

unity 接入视频监控 avpro_Time_04

2)导入人物模型

  • 加载人物模型,因为是收费的,所以这里没链接下载,但是网上都有这个,只需要上网购买就行,需要配套对应人物移动动画
  • 创建场景obj并命名为Player
  • 把人物模型导入这个obj里面

    现在导入后就有个人物obj
  • 现在需要编辑C#脚本来让人物移动
  • 名词解释
    locomotion 移动
  • 这里让人物移动就需要两个东西
    ①InputHandler 玩家输入识别系统
    ②player_locomotion 玩家移动系统

3)安装unity的输入安装包

  • 安装移动识别输入的安装包
  • unity 接入视频监控 avpro_unity 接入视频监控 avpro_05


  • unity 接入视频监控 avpro_unity 接入视频监控 avpro_06

  • 如果找不到这个Input System,那么就点击Adcanced,选择
  • unity 接入视频监控 avpro_学习_07

  • 注意点
    安装完后重启unity重载项目
  • 新建Input Actions
  • unity 接入视频监控 avpro_学习_08

  • 脚本生成C#类,然后apply
  • unity 接入视频监控 avpro_System_09

4)设置unity的输入 系统(涉及到三个脚本)

(1)涉及到的脚本

①InputHandler 输入

②PlayerControls 控制输入

③PlayerLocomotion 人物移动

unity 接入视频监控 avpro_unity 接入视频监控 avpro_10

(2)设定PlayerControl是的监听哪些键盘按键(InputHandler.cs)

①双击PlayerControls,引出一个窗口,新建action

unity 接入视频监控 avpro_ci_11


②改名为Player Movement,actions改名为Movement,actions type改为 Pass Through,control Type改为Vector

unity 接入视频监控 avpro_ci_12


③并删除默认的No Bingdings ,增加 2D Vector Composite,并改名为WASD

unity 接入视频监控 avpro_unity 接入视频监控 avpro_13


④修改对应Composite为2D Vector,Mode为Analog

unity 接入视频监控 avpro_System_14


⑤让wasd绑定对应键盘设定

unity 接入视频监控 avpro_Time_15


⑥新增Camera监听,让摄像机右边跟随,增加StickDeazone

unity 接入视频监控 avpro_ci_16


⑦新增Binding(Delta(Mouse))

unity 接入视频监控 avpro_Time_17


Processors选择Normalize Vector2

unity 接入视频监控 avpro_unity 接入视频监控 avpro_18


⑧设置项目配置(这个能修改一些输入设定)

unity 接入视频监控 avpro_ci_19


unity 接入视频监控 avpro_Time_20


change Default Hold Time to 0,如果不设置为0,那么人物移动的时候会有延迟

unity 接入视频监控 avpro_unity 接入视频监控 avpro_21

5)人物碰撞和刚体

unity刚体文档 ①点击人物Player 的GameObject增加胶囊碰撞体

unity 接入视频监控 avpro_unity 接入视频监控 avpro_22


修改一些参数

unity 接入视频监控 avpro_Time_23


②增加RighidBody,然后设置Constraints,设置Freeze Rotation(因为我们要自己控制旋转)

unity 接入视频监控 avpro_学习_24


③修改InputHandler这个C#脚本()

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace SG
{
    public class InputHandler : MonoBehaviour
    {
        public float horizontal;
        public float vertical;
        public float moveAmount;
        public float mouseX;
        public float mouseY;

        //人物移动键盘监听的管理器
        PlayerControls inputActions;
        CameraHandler cameraHandler;

        //移动输入
        Vector2 movementInput;
        //摄像头输入
        Vector2 cameraInput;
         
        private void Awake()
        {
            cameraHandler = CameraHandler.singleton;
        }

        private void FixedUpdate()
        {
            float delta = Time.fixedDeltaTime;

            if (cameraHandler != null)
            {
                cameraHandler.FollowTarget(delta);
                cameraHandler.HandlerCameraRotation(delta,mouseX,mouseY);
            }
        }

        public void OnEnable()
        {
            //①初始化单例和单例对应的回调函数
            //获取键盘的输入数据,从2D坐标数据读进来
            if (inputActions == null)
            {
                inputActions = new PlayerControls();
                inputActions.PlayerMovement.Movement.performed += inputActions => movementInput = inputActions.ReadValue<Vector2>();
                inputActions.PlayerMovement.Camera.performed += i => cameraInput = i.ReadValue<Vector2>();
            }

            //②初始化这个输入资源库
            inputActions.Enable();
        }

        private void OnDisable()
        {
            //回收输入资源库对应数据 
            inputActions.Disable();
        }

        //这里应该是每帧去调用,转进来应该是时间?
        public void TickInput(float delta)
        {
            MoveInput(delta);
        }

        //这里应该是每帧去调用,转进来应该是时间?
        private void MoveInput(float delta)
        {
            //记录水平垂直移动值,并计算移动值
            horizontal = movementInput.x;
            vertical = movementInput.y;
            moveAmount = Mathf.Clamp01(Mathf.Abs(horizontal) + Mathf.Abs(vertical));
            mouseX = cameraInput.x;
            mouseY = cameraInput.y;
        }
    }
}

6)人物移动模块和输入脚本(player_locomotion)

①代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace SG
{
    public class PlayerLocomotion : MonoBehaviour
    {
        //主摄像机的坐标
        Transform cameraObject;
        InputHandler inputHandler;
        Vector3 moveDirection;

        [HideInInspector]
        public Transform myTransform;
        [HideInInspector]
        public AnimatorHandler animatorHandler;

        public new Rigidbody rigidbody;
        //后面会有个lock Camera
        public GameObject normalCamera;  

        [Header("Stats")]
        [SerializeField]
        float movementSpeed = 5;
        [SerializeField]
        float rotationSpeed = 1;

        void Start()
        {
            //初始化单例
            rigidbody = GetComponent<Rigidbody>();
            inputHandler = GetComponent<InputHandler>();
            animatorHandler = GetComponentInChildren<AnimatorHandler>();
            cameraObject = Camera.main.transform;
            //这个的transform是默认的哪个?
            myTransform = transform;
            animatorHandler.Initialize();

        }

        public void Update()
        {
            //获得距离上一帧的间隔时间
            float delta = Time.deltaTime;

            inputHandler.TickInput(delta);

            //移动主摄像头坐标位置
            moveDirection = cameraObject.forward * inputHandler.vertical;
            moveDirection += cameraObject.right * inputHandler.horizontal;
            moveDirection.Normalize();
            moveDirection.y = 0;

            float speed = movementSpeed;
            moveDirection *= speed;

            Vector3 projectedVelocity = Vector3.ProjectOnPlane(moveDirection, normalVector);
            rigidbody.velocity = projectedVelocity;

            animatorHandler.UpdateAnimatorValues(inputHandler.moveAmount, 0);

            if (animatorHandler.canRotate)
            {
                HandleRotation(delta);
            }


        }

        #region Movement
        Vector3 normalVector;  //后面会用到
        Vector3 targetPosition;

        //调整玩家的旋转
        private void HandleRotation(float delta)
        {
            Vector3 targetDir = Vector3.zero;
            float moveOverride = inputHandler.moveAmount;

            targetDir = cameraObject.forward * inputHandler.vertical;
            targetDir += cameraObject.right * inputHandler.horizontal;

            //向量单位化,a vector keeps the same direction but its length is 1.0 
            targetDir.Normalize();
            targetDir.y = 0;

            if (targetDir == Vector3.zero)
                targetDir = myTransform.forward;

            float rs = rotationSpeed;

            Quaternion tr = Quaternion.LookRotation(targetDir);
            Quaternion targetRotation = Quaternion.Slerp(myTransform.rotation, tr, rs * delta);

            myTransform.rotation = targetRotation;
        }

        #endregion
    }
}

②点击player这个obj,挂载C#脚本到人物下面

unity 接入视频监控 avpro_System_25


③再挂载locomotion

unity 接入视频监控 avpro_Time_26

  • 总结
    这样人物就能再这个平面上移动了

7)动画脚本控制

①新建动画管理脚本Animations.cs
②代码展示

using System.Collections.Generic;
using UnityEngine;

namespace SG
{
    public class AnimatorHandler : MonoBehaviour
    {
        public Animator anim;
        int vertical;
        int horizontal;
        public bool canRotate;

        //相当于C++类自定义个init函数
        public void Initialize()
        {
            anim = GetComponent<Animator>();
            vertical = Animator.StringToHash("Vertical");
            horizontal = Animator.StringToHash("Horizontal");
        }

        //用移动值选择更新不同移动值,来选择不同动画
        public void UpdateAnimatorValues(float verticalMovement, float horizontalMovement)
        {
            #region Vertical
            float v = 0;

            if (verticalMovement > 0 && verticalMovement < 0.55f)
            {
                v = 0.5f;
            }
            else if (verticalMovement > 0.55f)
            {
                v = 1;
            }
            else if (verticalMovement < 0 && verticalMovement > -0.55f)
            {
                v = -0.5f;
            }
            else if (verticalMovement < -0.55f)
            {
                v = -1;
            }
            else
            {
                v = 0;
            }
            #endregion

            #region Horizontal
            float h = 0;

            if (horizontalMovement > 0 && horizontalMovement < 0.55f)
            {
                h = 0.5f;
            }
            else if (horizontalMovement > 0.55f)
            {
                h = 1;
            }
            else if (horizontalMovement < 0 && horizontalMovement > -0.55f)
            {
                h = -0.5f;
            }
            else if (horizontalMovement < -0.55f)
            {
                h = -1;
            }
            else
            {
                h = 0;
            }
            #endregion

            anim.SetFloat(vertical, v, 0.1f, Time.deltaTime);
            anim.SetFloat(horizontal, h, 0.1f, Time.deltaTime);
        }

        public void CanRotate()
        {
            canRotate = true;
        }

        public void StopRotation()
        {
            canRotate = false;
        }

    }
}

③点击Player下面的小player,添加动画组件

unity 接入视频监控 avpro_Time_27

  • 总结
    现在就可以旋转人物了

8)动画控制和人物执行动画帧控制

①增加动画控制组件,改名为humanoid

unity 接入视频监控 avpro_学习_28


②把humanoid放到Controller对应组件位置

unity 接入视频监控 avpro_System_29


③打开动画组件页面

unity 接入视频监控 avpro_ci_30


④增加两个参数

unity 接入视频监控 avpro_ci_31


⑤点击图层Layers创建xin的Blend Tree

unity 接入视频监控 avpro_Time_32


⑥双击点开这个新加的BlendTree,修改Blend Type为2D Freeform Cartesian,参数修改为刚刚新增的两个参数

unity 接入视频监控 avpro_System_33

⑦新增三个奔跑、行走等动画,重置参数为0

unity 接入视频监控 avpro_学习_34

三、一些名词解释

1)velocity 速度
2)InputSystem 输入系统

playeControl  负责处理存储键鼠、手柄的输入。
InputHandle   处理PlayerControl里的数据,把InputSystem里的数据类型转化为float、Vector2这种常用、直接的数据类型。
AnimatorHandle   负责给animator传入数值,改变动画状态
PlayerLocomotion  负责Player的rigidbody.velocity,以及transform.rotation
CameraHandle 负责控制相机的跟随,旋转。

补充说明:
InputHandle处理完输入数据后,其他脚本进行计算和封装。Player的相关函数在PlayerLocomotion的Update中统一执行,CameraHandle则在InputSystem中执行。

3)animation 动画
4)resemble 看起来像
5)locomotion 移动运动
6) encapsulating
v. 简述; 概括; 压缩;
7)magnitude
n. 巨大; 重大; 重要性; 星等; 星的亮度; 震级;
8)animation
n. 动画; 动画片; 生气; 活力; 富有生命力; (指电影、录像、电脑游戏的)动画制作;