【学习日志】2022.10.08 Unity人物运动(移动+转身)、Character Controller、射线检测、动画融合

 Angelyatou/Endless_Unity_Projects: Unity Projects of Endlessdaydram (github.com)icon-default.png?t=M85Bhttps://github.com/Angelyatou/Endless_Unity_Projects

最简单的人物运动(移动+转身)

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

public class Cha1 : MonoBehaviour
{
    public float speed = 3;
    Vector3 move;
    void Update()
    {
        //获取输入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Move(h, 0, v);
    }

    void Move(float x,float y,float z)
    {
        //世界坐标
        move = new Vector3(x, y, z);

        //要看向的位置
        Vector3 to = transform.position + move;
        transform.LookAt(to);
        transform.position += move * speed * Time.deltaTime;
    }
}

FBX文件(包含模型、骨骼、动画、材质)

动画状态机

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

public class Cha1 : MonoBehaviour
{
    Animator animator;

    public float speed = 3;
    Vector3 move;

    private void Start()
    {
        animator = GetComponent<Animator>();
    }
    void Update()
    {
        //获取输入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Move(h, 0, v);
        //更新动画
        UpdateAnim();
    }

    void Move(float x,float y,float z)
    {
        //世界坐标
        move = new Vector3(x, y, z);
        //要看向的位置
        Vector3 to = transform.position + move;
        transform.LookAt(to);
        transform.position += move * speed * Time.deltaTime;
    }

    void UpdateAnim()
    {
        float forward = move.magnitude;
        animator.SetFloat("Forward", forward);
    }
}

把FBX里的动画文件拖到Animator窗口,设置动画状态机 

 

添加刚体、碰撞体并冻结刚体旋转

 然后发现在撞东西的时候会抖,像这样

 于是我们修改一下代码

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

public class Cha2 : MonoBehaviour
{
    Animator animator;
    Rigidbody rigid;

    public float speed = 3;
    Vector3 move;

    private void Start()
    {
        animator = GetComponent<Animator>();
        rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        //获取输入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Move(h, 0, v);
        //更新动画
        UpdateAnim();
    }

    void Move(float x, float y, float z)
    {
        //世界坐标
        move = new Vector3(x, y, z);
    }
    //刚体移动,要在FixedUpdate里写
    public void FixedUpdate()
    {
        //根据move,直接改变刚体速度
        Vector3 v = move * speed;
        v.y = rigid.velocity.y;
        rigid.velocity = new Vector3(move.x,rigid.velocity.y,move.z)* speed;

        //让刚体朝向目标
        Quaternion q = Quaternion.LookRotation(move);  //向量 转成 朝向
        rigid.MoveRotation(q);
    }

    void UpdateAnim()
    {
        float forward = move.magnitude;
        animator.SetFloat("Forward", forward);
    }
}

 就变成这样了

 如果想让他碰到东西停下动作,也可以把UpdateAnim改成这样

    void UpdateAnim()
    {
        //float forward = move.magnitude;
        //animator.SetFloat("Forward", forward);

        //基于刚体速度播放动画
        animator.SetFloat("Forward", rigid.velocity.magnitude / speed);
    }

就变成这样 


使用Character Controller控制角色运动(移动+转身)

角色控制器

Step Offset:上楼梯的台阶高度最大值

Skin Width:皮肤(柔软物质厚度)(避免卡死)

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

public class Cha3 : MonoBehaviour
{
    Animator animator;
    CharacterController cc;

    public float speed = 3;
    Vector3 move;

    private void Start()
    {
        animator = GetComponent<Animator>();
        cc = GetComponent<CharacterController>();
    }
    void Update()
    {
        //获取输入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        Move(h, 0, v);

        //更新动画
        UpdateAnim();
    }

    void Move(float x, float y, float z)
    {
        move = new Vector3(x, 0, z);
        //这一帧移动的向量,很小
        Vector3 m = move * speed * Time.deltaTime;

        //朝向移动方向
        transform.LookAt(transform.position + m);

        //通过cc去移动
        cc.Move(m);
    }

    void UpdateAnim()
    {
        //基于刚体速度播放动画
        animator.SetFloat("Forward",cc.velocity.magnitude / speed);
    }
}

运行unity发现能爬楼梯爬坡但不下落

使用射线检测改进(使人物能下落)

Test Raycast: 

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

public class Cha3Fall : MonoBehaviour
{
    Animator animator;
    CharacterController cc;

    public float speed = 3;
    Vector3 move;

    bool isGround = true;
    private void Start()
    {
        animator = GetComponent<Animator>();
        cc = GetComponent<CharacterController>();
    }
    void Update()
    {
        //获取输入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        Move(h, 0, v);

        //更新动画
        UpdateAnim();
    }

    void Move(float x, float y, float z)
    {
        move = new Vector3(x, 0, z);
        //这一帧移动的向量,很小
        Vector3 m = move * speed * Time.deltaTime;

        //朝向移动方向
        transform.LookAt(transform.position + m);

        //通过cc去移动
        cc.Move(m);
    }

    private void FixedUpdate()
    {
        Ray ray = new Ray(transform.position + new Vector3(0, 0.2f, 0), Vector3.down);

        RaycastHit hit;
        Color c = Color.red;

        isGround = false;
        if(Physics.Raycast(ray,out hit, 0.35f))
        {
            c = Color.green;
            isGround = true;
        }
        //调式
        Debug.DrawLine(transform.position + new Vector3(0, 0.2f, 0),transform.position - new Vector3(0,0.15f,0),c);
    }
    void UpdateAnim()
    {
        //基于刚体速度播放动画
        animator.SetFloat("Forward", cc.velocity.magnitude / speed);
    }
}

下落:

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

public class Cha3Fall : MonoBehaviour
{
    Animator animator;
    CharacterController cc;

    public float speed = 3;
    Vector3 move;

    bool isGround = true;
    private void Start()
    {
        animator = GetComponent<Animator>();
        cc = GetComponent<CharacterController>();
    }
    void Update()
    {
        //获取输入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        Move(h, 0, v);

        //更新动画
        UpdateAnim();
    }

    //纵向速度
    float vy = 0;
    void Move(float x, float y, float z)
    {
        move = new Vector3(x, 0, z);
        //这一帧移动的向量,很小
        Vector3 m = move * speed * Time.deltaTime;

        if (isGround)
        {
            vy = 0;
        }
        else
        {
            //物理公式:v = v0 + gt   (v0=0)
            vy += Physics.gravity.y * Time.deltaTime;
        }

        //Δy = v * Δt
        m.y = vy * Time.deltaTime;

        //朝向移动方向
        transform.LookAt(transform.position + m);

        //通过cc去移动
        cc.Move(m);
    }

    private void FixedUpdate()
    {
        Ray ray = new Ray(transform.position + new Vector3(0, 0.2f, 0), Vector3.down);

        RaycastHit hit;
        Color c = Color.red;

        isGround = false;
        if(Physics.Raycast(ray,out hit, 0.35f))
        {
            c = Color.green;
            isGround = true;
        }
        //调式
        Debug.DrawLine(transform.position + new Vector3(0, 0.2f, 0),transform.position - new Vector3(0,0.15f,0),c);
    }
    void UpdateAnim()
    {
        //基于刚体速度播放动画
        animator.SetFloat("Forward", cc.velocity.magnitude / speed);
    }
}


动画融合

 

加个Test Speed进行调试

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

public class Cha3Fall : MonoBehaviour
{
    Animator animator;
    CharacterController cc;

    public float speed = 3;
    [Range(0.0f, 1.0f)]
    public float testSpeed = 1;


    Vector3 move;

    bool isGround = true;
    private void Start()
    {
        animator = GetComponent<Animator>();
        cc = GetComponent<CharacterController>();
    }
    void Update()
    {
        //获取输入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        Move(h, 0, v);

        //更新动画
        UpdateAnim();
    }

    //纵向速度
    float vy = 0;
    void Move(float x, float y, float z)
    {
        move = new Vector3(x, 0, z);
        //这一帧移动的向量,很小
        Vector3 m = move * speed * Time.deltaTime;

        if (isGround)
        {
            vy = 0;
        }
        else
        {
            //物理公式:v = v0 + gt   (v0=0)
            vy += Physics.gravity.y * Time.deltaTime;
        }

        //Δy = v * Δt
        m.y = vy * Time.deltaTime;

        //朝向移动方向
        transform.LookAt(transform.position + move);

        //通过cc去移动
        cc.Move(m);
    }

    private void FixedUpdate()
    {
        Ray ray = new Ray(transform.position + new Vector3(0, 0.2f, 0), Vector3.down);

        RaycastHit hit;
        Color c = Color.red;

        isGround = false;
        if(Physics.Raycast(ray,out hit, 0.35f))
        {
            c = Color.green;
            isGround = true;
        }
        //调式
        Debug.DrawLine(transform.position + new Vector3(0, 0.2f, 0),transform.position - new Vector3(0,0.15f,0),c);
    }
    void UpdateAnim()
    {
        //基于刚体速度播放动画
        animator.SetFloat("Forward", cc.velocity.magnitude / speed * testSpeed);
    }
}

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值