【学习日志】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;
    }
}

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

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

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

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

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

动画状态机

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

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();
    }
    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窗口,设置动画状态机 

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

 

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

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

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

 于是我们修改一下代码

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();
        rigid = GetComponent();
    }
    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控制角色运动(移动+转身)

角色控制器

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

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();
        cc = GetComponent();
    }
    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();
        cc = GetComponent();
    }
    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();
        cc = GetComponent();
    }
    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);
    }
}


动画融合

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

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

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

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

加个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();
        cc = GetComponent();
    }
    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);
    }
}

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

你可能感兴趣的:(学习日志,Unity知识树,学习)