3D人物移动和相机跟随_学习整理资料

核心1、新建工程,取名Exercise_3D。
2、新建个文件夹(3D_Assets),将所有素材资源,导入或拖入。
3、新建一个3DObject——Plane,取名(Ground)作为地面。
4、新建一个空物体,取名Player,然后将3D人物模型拖入,作为子物体。
5、对Player添加Animator组件和CharacterController组件。
5、选中Player,在Animator窗口,新建BlendTree(混合树动画),并将 idle动画、walk动画、run动画拖入。然后 创建Speed,作为速度判断的阀值条件。Jump动画拖入,创建Bool条件。
6、对 Player添加脚本(PlayerController)。
       1.获取private CharacterController、并创建其他需要的条件;
       2.Start里:_characterController=GetComponent<CharacterController>();
       3.新建方法PlayerMove(); 里面写 移动和转向代码、鼠标旋转视角代码、动画播放。***(移动和跳跃代码放FixedUpdate里)
         3.1.动画播放:使用混合树动画,用BlandSpeed做切换动画的条件,并 写播放动画的代码
7、在Player脚本里,新建方法playerJump(); 里面写 跳跃代码、动画播放。
       1.创建 bool值(isJump,表示是否按下跳跃键),创建float值(jumpVelocity表示跳跃速度;jumpForce表示跳跃时给的力)
       2.创建3个if方法,表示:跳跃、受重力影响下落、停止播放跳跃动画。
8、在Player脚本里,新建方法CameraRotation(); 里面写 相机的跟随和旋转代码。(相机方法在LateUpdate里调用)
       1.新建空物体(取名Follow),作为Player的子物体,挂在人物头顶(作为相机跟随的对象)。
       2.下载Cinema组件,并添加CinemachineVirtualCamera组件(取名PlayerFollowCamera),并进行一些设置。
       3.在方法内写脚本
*******(目前来说,简单的移动、跳跃和相机跟随就完成了,没有判断是否接触地面,所以现在可以无限跳跃)******

代码:

public class PlayerController : MonoBehaviour
{
    private CharacterController _characterController;
    public float walkSpeed = 2f;//走路速度
    public float runSpeed = 5f;//跑步速度
    public float smoothTime = 0.2f;//平滑转向用时
    public float targetSpeed;//当前速度
    private Vector3 targetDirection;//当前前进的方向
    private float targetRotation;//当前旋转角度
    private float currentVelocity;//当前旋转速度(使旋转平滑用的)(固定写法,必须要的)

    public bool isRun;//是否按下跑步键
    public bool isJump;//是否按下跳跃键

    public float jumpForce = 10.0f;//跳跃力
    private float jumpVelocity = -1.0f;//跳跃速度
    public float _gravity = -9.8f;//重力

    private Animator _animator;
    private float animationBlend;//混合树动画条件

    public GameObject _mainCamera;//获取 主相机
    private float _cinemachineTargetYaw;//获取 鼠标输入X(水平左右旋转)(偏航)
    private float _cinemachineTargetPitch;//获取 鼠标输入Y(竖直上下旋转)(倾斜、坠落)
    public float mouseMoveSpeed = 2;//鼠标旋转的速度
    public float bottomClamp = -30.0f;//鼠标向下限制,你能把相机向下移动多少
    public float topClamp = 70.0f;//鼠标向上限制,你能把相机向上移动多少
    public GameObject cinemachineCameraTarget;//获取 相机跟随的目标


    private void Start()
    {
        _characterController = GetComponent<CharacterController>();//初始化组件
        _animator = GetComponent<Animator>();
    }

    private void Update()
    {
        IsRun();
        IsJump();
    }

    private void FixedUpdate()
    {
        PlayerMove();
        PlayerJump();
    }

    private void LateUpdate()
    {
        CameraRotation();//鼠标旋转视角
    }

    //是否按下了 跑步键(Shift)
    private void IsRun()
    {
        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            isRun = true;
        }
        if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            isRun = false;
        }
    }
    //是否按下了 跳跃键(空格)
    private void IsJump()
    {
        if (Input.GetButtonDown("Jump"))
        {
            isJump = true;
        }
    }

    //玩家 移动
    public void PlayerMove()
    {
        //获取 前后左右 的键盘输入
        Vector2 _input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
        Vector2 inputDir = _input.normalized;//向量单位化

        //根据 是否按下跑步键,判断玩家此时状态(跑步?还是走路?)
        targetSpeed = isRun ? runSpeed : walkSpeed;

        //如果没有输入,将目标速度设置为0
        if (inputDir == Vector2.zero)
        {
            targetSpeed = 0.0f;
        }

        //只用于 混合树动画 的Speed值
        animationBlend = Mathf.Lerp(0.0f, targetSpeed, Time.deltaTime * 95.0f);

        if (inputDir != Vector2.zero)
        {
            //获取 转动的角度(+按住方向键时玩家突然转动鼠标时,相机跟随转动)  弧度转换为度
            targetRotation = Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg + _mainCamera.transform.eulerAngles.y;
            //平滑旋转(用于欧拉角的)
            float _rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref currentVelocity, smoothTime);
            //将平滑旋转 (以欧拉角的形式)给到 玩家
            transform.rotation = Quaternion.Euler(0.0f, _rotation, 0.0f);
        }

        //获取 前进的方向(这是一个Vector3)
        targetDirection = Quaternion.Euler(0.0f, targetRotation, 0.0f) * Vector3.forward;

        //动起来(+垂直速度(下落))
        _characterController.Move(targetDirection.normalized * targetSpeed * Time.deltaTime + new Vector3(0.0f, jumpVelocity, 0.0f) * Time.deltaTime);

        _animator.SetFloat("Speed", animationBlend);//移动动画
    }

    //玩家 跳跃
    public void PlayerJump()
    {
        if (isJump)
        {
            //如果按下了 跳跃键

            jumpVelocity = jumpForce;//获得跳跃力

            _animator.SetBool("Jump", true);//跳跃动画

            isJump = false;//防止长按一直跳
        }

        if (jumpVelocity < 50.0f)
        {
            jumpVelocity += _gravity * Time.deltaTime;//受重力影响,使玩家一直有一个下坠力
            //Debug.Log(jumpVelocity);
        }

        if (jumpVelocity < 0)
        {
            _animator.SetBool("Jump", false);//停止播放 跳跃动画
        }
    }

    //鼠标旋转视角
    public void CameraRotation()
    {
        _cinemachineTargetYaw += Input.GetAxis("Mouse X") * mouseMoveSpeed;//获取 鼠标输入X(水平左右旋转)
        _cinemachineTargetPitch -= Input.GetAxis("Mouse Y") * mouseMoveSpeed;//获取 鼠标输入Y(竖直上下旋转)

        //限制鼠标角度
        _cinemachineTargetYaw = ClampAngle(_cinemachineTargetYaw, float.MinValue, float.MaxValue);
        _cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, bottomClamp, topClamp);

        //让相机跟随的目标旋转(相机也就跟着转)*****************(鼠标的旋转传给Follow,相机是跟随Follow旋转的,也就是Follow旋转,相机才旋转)
        cinemachineCameraTarget.transform.rotation = Quaternion.Euler(_cinemachineTargetPitch, _cinemachineTargetYaw, 0.0f);
    }

    //限制鼠标角度
    private static float ClampAngle(float Angle, float MinAngle, float MaxAngle)
    {
        if (Angle < -360f)
        {
            Angle += 360f;
        }
        if (Angle > 360f)
        {
            Angle -= 360f;
        }
        return Mathf.Clamp(Angle, MinAngle, MaxAngle);
    }


}

跟随相机的设置:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值