学习日志2022.10.08 Unity人物运动(移动+转身)Character Controller射线检测动画融合
Posted EndlessDaydream
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习日志2022.10.08 Unity人物运动(移动+转身)Character Controller射线检测动画融合相关的知识,希望对你有一定的参考价值。
Angelyatou/Endless_Unity_Projects: Unity Projects of Endlessdaydram (github.com)https://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);
unity3d控制模型的运动
这里就不多做解释了,直接上代码,只为了备忘。
public class HeroMove : MonoBehaviour { private float speed;//人物行动速度 private Animation ani; // Use this for initialization void Start () { speed = 1f; ani = GetComponent<Animation> (); } // Update is called once per frame void Update () { /*向前走/跑*/ if (Input.GetKey (KeyCode.W)) { transform.Translate (Vector3.forward * Time.deltaTime * speed); if (Input.GetKey (KeyCode.LeftShift)) { speed = 3f; ani.Play ("Run"); } else { speed = 1f; ani ["Walk"].speed = 1; ani.Play ("Walk"); } } else if (Input.GetKey (KeyCode.S)) { //向后退 transform.Translate (Vector3.back * Time.deltaTime * speed); ani ["Walk"].speed = -1; ani.Play ("Walk"); } else { //停止 ani.Play ("Idle"); } } }
以上是关于学习日志2022.10.08 Unity人物运动(移动+转身)Character Controller射线检测动画融合的主要内容,如果未能解决你的问题,请参考以下文章