c# - 如何以不同的速度编写一堆第一人称动画
问题描述
我在动画师中为一个名为“Animator”的空游戏对象制作了 4 种不同类型的动画剪辑。主相机是这个的孩子。动画以跑步循环、步行循环、蹲伏循环和空闲循环为特色。他们都有一个触发器,让他们玩。当玩家达到一定速度时,我如何测量玩家的速度并执行这些动画。我发现其他人试图这样做并且它有效,但仅适用于闲置和步行。但不幸的是,我无法让冲刺和蹲下工作。我不知道该怎么做,要么有冲刺和蹲伏动画,要么只是根据玩家是冲刺还是蹲伏来改变步行动画的速度。我会在我找到的代码所在的位置留下评论。
这是我的播放器控制器中的内容(触发停止用于空闲动画):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
Animator _ar;
public float speed;
[Range(-5, -20)]
public float gravity = -9.81f;
public float sprintSpeed = 6f;
public float walkSpeed = 4f;
public float crouchSpeed = 2f;
public float standHeight = 1.6f;
public float crouchHeight = 1f;
Vector3 velocity;
bool isGrounded;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public Light _l;
//Set this to the transform you want to check
public Transform objectTransfom;
private float noMovementThreshold = 0.0001f;
private const int noMovementFrames = 1;
Vector3[] previousLocations = new Vector3[noMovementFrames];
public bool isMoving;
//Let other scripts see if the object is moving
public bool IsMoving
{
get { return isMoving; }
}
void Awake()
{
//For good measure, set the previous locations
for (int i = 0; i < previousLocations.Length; i++)
{
previousLocations[i] = Vector3.zero;
}
}
void Start()
{
_ar = GameObject.Find("Animator").GetComponentInChildren<Animator>();
}
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
//Below here is the code I found. The if statements for isMoving, is what I put in to see if
//this worked.
//Store the newest vector at the end of the list of vectors
for (int i = 0; i < previousLocations.Length - 1; i++)
{
previousLocations[i] = previousLocations[i + 1];
}
previousLocations[previousLocations.Length - 1] = objectTransfom.position;
//Check the distances between the points in your previous locations
//If for the past several updates, there are no movements smaller than the threshold,
//you can most likely assume that the object is not moving
for (int i = 0; i < previousLocations.Length - 1; i++)
{
if (Vector3.Distance(previousLocations[i], previousLocations[i + 1]) >= noMovementThreshold)
{
//The minimum movement has been detected between frames
isMoving = true;
break;
}
else
{
isMoving = false;
}
}
if(isMoving == true)
{
if (Input.GetKeyDown(KeyCode.LeftShift))
{
speed = sprintSpeed;
_ar.SetTrigger("WalkSprint");
}
else if (Input.GetKeyUp(KeyCode.LeftControl))
{
speed = crouchSpeed;
_ar.SetTrigger("WalkCrouch");
//transform.localScale = new Vector3(0.8f, 0.5f, 0.8f);
}
else
{
speed = walkSpeed;
_ar.SetTrigger("Walk");
//transform.localScale = new Vector3(0.8f, 0.85f, 0.8f);
}
}
else
{
_ar.SetTrigger("Stop");
}
}
}
解决方案
不幸的是,与 Game Dev 中的许多问题一样,这可能是许多不同的问题(或所有问题!)。您可以从这里开始调试:
- 检查你的错误日志,看看是否有任何明显的东西跳出来,比如对游戏对象/组件的错误引用。
- 看动画师。在游戏运行时,您应该能够让 Animator 与您的游戏窗口并排打开。您应该能够看到正在运行和转换的动画。查看是否某些内容未正确链接,或者动画时间是否配置不正确等。
- 添加一些调试语句,例如输出当前设置的触发器。我什至会验证您的输入是否配置正确。也许在开始时添加一些额外的条件来调试正在按下的输入。
- 正如@OnionFan 所说,您的输入检查是针对Crouch 键的KeyUp。那应该是KeyDown。
推荐阅读
- list - 使用 SwiftUI 和 macOS 创建带有标题的列表
- nlp - PyTorch - 稀疏张量没有步幅
- authorization - Identity Server 4 令牌过期 API 与 ClientApp
- python - 为什么要删除您更改数字的行中的第 8 个位置?
- android - React Native 导航和状态管理
- android - OnePlus (Android 10) - 在 PIP 模式下主屏幕冻结
- ios - 不可能有白色背景的 UISearchBar?
- python - Alphavantage:来自不同 api 密钥但来自同一系统的请求
- javascript - three.js 中的多个画布
- c# - 整个页面的 OnChange:Blazor