首页 > 解决方案 > 如何以不同的速度编写一堆第一人称动画

问题描述

我在动画师中为一个名为“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");
        }
    }
}

标签: c#unity3d

解决方案


不幸的是,与 Game Dev 中的许多问题一样,这可能是许多不同的问题(或所有问题!)。您可以从这里开始调试:

  1. 检查你的错误日志,看看是否有任何明显的东西跳出来,比如对游戏对象/组件的错误引用。
  2. 看动画师。在游戏运行时,您应该能够让 Animator 与您的游戏窗口并排打开。您应该能够看到正在运行和转换的动画。查看是否某些内容未正确链接,或者动画时间是否配置不正确等。
  3. 添加一些调试语句,例如输出当前设置的触发器。我什至会验证您的输入是否配置正确。也许在开始时添加一些额外的条件来调试正在按下的输入。
  4. 正如@OnionFan 所说,您的输入检查是针对Crouch 键的KeyUp。那应该是KeyDown。

推荐阅读