实现根据相机视角输入WASD移动和转向的功能

记录一下从官方第三人称模板简化出来的角色移动控制。

实现效果

最终实现的效果是,当按下w时,角色向当前相机方向移动;按ad时,向当前相机方向左右转;按s时向相机移动。

角色控制演示

环境

unity2021.3.5f1c1版本普通3d工程
插件使用到了cinemachine2.8.6,视频中的相机移动为cinemachine的自由视角相机,但不重要

进入正题

场景
一个简单的场景
角色组件
角色上挂载了Animator(用于控制移动动画),Character Controller(unity自带的角色控制器),Player Controller(自己写的控制脚本)
动画状态机
角色的动画状态机,当speed大于0.3时从站立状态转移到移动状态,移动状态由一个混合了走路和奔跑的混合树完成。在脚本中通过对speed赋值来控制角色移动。

然后是代码部分

	public Camera playerFollowCamera;
    public Animator animator;

    [Tooltip("How fast the character turns to face movement direction")]
    [Range(0.0f, 0.3f)]
    public float RotationSmoothTime = 0.12f;

声明公开变量

	private float _rotationVelocity;
    private float _targetRotation = 0.0f;
    private CharacterController _controller;
    
    private int _aniId_speed;
    private int _aniId_hurt;
    private int _aniId_atk;
    private int _aniId_beHit;

私有变量,包括了角色控制器、运动参数和状态机参数的id

	// Start is called before the first frame update
    void Start()
    {
        InitComponents();
        InitAnimator();
    }

    // Update is called once per frame
    void Update()
    {
        PlayerMove();
    }

在start中获取角色控制器,并计算出状态机参数的哈希值,在update中调用移动函数

	private void InitComponents()
    {
        _controller = GetComponent<CharacterController>();
    }
    private void InitAnimator()
    {
        _aniId_speed = Animator.StringToHash("speed");
        _aniId_atk = Animator.StringToHash("atk");
        _aniId_hurt = Animator.StringToHash("hurt");
        _aniId_beHit = Animator.StringToHash("be hit");
    }

角色移动函数

	private void PlayerMove()
    {
        var ad = Input.GetAxis("Horizontal");
        var ws = Input.GetAxis("Vertical");
        if (ad == 0 && ws == 0) return;

        Vector3 inputDirection = new Vector3(ad, 0.0f, ws).normalized;
        
        _targetRotation = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg + playerFollowCamera.transform.eulerAngles.y;
        float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity, RotationSmoothTime);
        transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
        
        Vector3 targetDirection = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;
        
        // move the player
        _controller.Move(targetDirection.normalized * Time.deltaTime);

        animator.SetFloat(_aniId_speed, new Vector3(ad, 0, ws).magnitude);
    }

获取两个轴的输入,当玩家有输入时,进行旋转和移动。不进行是否有输入的判断的话,会出现相机移动角色自动跟随转变方向的效果。
然后计算出要转动的角度。使用了平滑过度,可以根据需要调整RotationSmoothTime和_rotationVelocity
再计算出欧拉角与forward做乘算,就得到了带有合适转动的位移向量。
因为角色应用了根运动,跑动的位移由动画控制,所以直接调用控制器的move即可,不需要在这里指定移动速度。
最后设置动画状态机的参数,让角色播放移动动画。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值