Unity - 我的移动脚本带有按住 运行 但我想将它变成一个开关 运行

Unity - I have my movement script with a hold down run but i want to turn it into a toggle run

AH 是的,我有这个简单动作的脚本,它在最后有主要动作。在脚本中,我检查输入脚本的输入并进行移动,对于脚本,我检查字符是否为 运行(来自不同脚本的输入)以及是否为 运行 移动速度为等于 运行 速度。否则就是步行速度。 我希望我的角色有一个切换冲刺而不是按住(这个脚本有) 谁能帮我输入 toggle run.Thank 你

动作脚本

using System.Linq;
using UnityEngine;

namespace LowPolyShooterPack
{
    [RequireComponent(typeof(Rigidbody), typeof(CapsuleCollider))]
    public class Movement : MovementBehaviour
    {
    #region FIELDS SERIALIZED

    [Header("Audio Clips")]

    [Tooltip("The audio clip that is played while walking.")]
    [SerializeField]
    private AudioClip audioClipWalking;

    [Tooltip("The audio clip that is played while running.")]
    [SerializeField]
    private AudioClip audioClipRunning;

    [Header("Speeds")]

    [SerializeField]
    private float speedWalking = 5.0f;

    [Tooltip("How fast the player moves while running."), SerializeField]
    private float speedRunning = 9.0f;

    #endregion

    #region PROPERTIES

    //Velocity.
    private Vector3 Velocity
    {
        //Getter.
        get => rigidBody.velocity;
        //Setter.
        set => rigidBody.velocity = value;
    }

    #endregion

    #region FIELDS

    /// <summary>
    /// Attached Rigidbody.
    /// </summary>
    private Rigidbody rigidBody;
    /// <summary>
    /// Attached CapsuleCollider.
    /// </summary>
    private CapsuleCollider capsule;
    /// <summary>
    /// Attached AudioSource.
    /// </summary>
    private AudioSource audioSource;

    /// <summary>
    /// True if the character is currently grounded.
    /// </summary>
    private bool grounded;

    /// <summary>
    /// Player Character.
    /// </summary>
    private CharacterBehaviour playerCharacter;
    /// <summary>
    /// The player character's equipped weapon.
    /// </summary>
    private WeaponBehaviour equippedWeapon;

    /// <summary>
    /// Array of RaycastHits used for ground checking.
    /// </summary>
    private readonly RaycastHit[] groundHits = new RaycastHit[8];

    #endregion

    #region UNITY FUNCTIONS

    /// <summary>
    /// Awake.
    /// </summary>
    protected override void Awake()
    {
        //Get Player Character.
        playerCharacter = ServiceLocator.Current.Get<IGameModeService>().GetPlayerCharacter();
    }

    /// Initializes the FpsController on start.
    protected override  void Start()
    {
        //Rigidbody Setup.
        rigidBody = GetComponent<Rigidbody>();
        rigidBody.constraints = RigidbodyConstraints.FreezeRotation;
        //Cache the CapsuleCollider.
        capsule = GetComponent<CapsuleCollider>();

        //Audio Source Setup.
        audioSource = GetComponent<AudioSource>();
        audioSource.clip = audioClipWalking;
        audioSource.loop = true;
    }

    /// Checks if the character is on the ground.
    private void OnCollisionStay()
    {
        //Bounds.
        Bounds bounds = capsule.bounds;
        //Extents.
        Vector3 extents = bounds.extents;
        //Radius.
        float radius = extents.x - 0.01f;
        
        //Cast. This checks whether there is indeed ground, or not.
        Physics.SphereCastNonAlloc(bounds.center, radius, Vector3.down,
            groundHits, extents.y - radius * 0.5f, ~0, QueryTriggerInteraction.Ignore);
        
        //We can ignore the rest if we don't have any proper hits.
        if (!groundHits.Any(hit => hit.collider != null && hit.collider != capsule)) 
            return;
        
        //Store RaycastHits.
        for (var i = 0; i < groundHits.Length; i++)
            groundHits[i] = new RaycastHit();

        //Set grounded. Now we know for sure that we're grounded.
        grounded = true;
    }
        
    protected override void FixedUpdate()
    {
        //Move.
        MoveCharacter();
        
        //Unground.
        grounded = false;
    }

    /// Moves the camera to the character, processes jumping and plays sounds every 
        frame.
    protected override  void Update()
    {
        //Get the equipped weapon!
        equippedWeapon = playerCharacter.GetInventory().GetEquipped();
        
        //Play Sounds!
        PlayFootstepSounds();
    }

    #endregion

    #region METHODS

    private void MoveCharacter()
    {
        #region Calculate Movement Velocity

        //Get Movement Input!
        Vector2 frameInput = playerCharacter.GetInputMovement();
        //Calculate local-space direction by using the player's input.
        var movement = new Vector3(frameInput.x, 0.0f, frameInput.y);
        
        //Running speed calculation.
        if(playerCharacter.IsRunning())
            movement *= speedRunning;
        else
        {
            //Multiply by the normal walking speed.
            movement *= speedWalking;
        }

        //World space velocity calculation. This allows us to add it to the rigidbody's 
            velocity properly.
        movement = transform.TransformDirection(movement);

        #endregion
        
        //Update Velocity.
        Velocity = new Vector3(movement.x, 0.0f, movement.z);
    }

    /// <summary>
    /// Plays Footstep Sounds. This code is slightly old, so may not be great, but it 
        functions alright-y!
    /// </summary>
    private void PlayFootstepSounds()
    {
        //Check if we're moving on the ground. We don't need footsteps in the air.
        if (grounded && rigidBody.velocity.sqrMagnitude > 0.1f)
        {
            //Select the correct audio clip to play.
            audioSource.clip = playerCharacter.IsRunning() ? audioClipRunning : 
                audioClipWalking;
            //Play it!
            if (!audioSource.isPlaying)
                audioSource.Play();
        }
        //Pause it if we're doing something like flying, or not moving!
        else if (audioSource.isPlaying)
            audioSource.Pause();
    }

    #endregion
    }
}

角色行为

using UnityEngine;

namespace LowPolyShooterPack
{
/// <summary>
/// Character Abstract Behaviour.
/// </summary>
public abstract class CharacterBehaviour : MonoBehaviour
{
    #region UNITY

    /// <summary>
    /// Awake.
    /// </summary>
    protected virtual void Awake(){}

    /// <summary>
    /// Start.
    /// </summary>
    protected virtual void Start(){}

    /// <summary>
    /// Update.
    /// </summary>
    protected virtual void Update(){}

    /// <summary>
    /// Late Update.
    /// </summary>
    protected virtual void LateUpdate(){}

    #endregion
    
    #region GETTERS

    /// <summary>
    /// Returns the player character's main camera.
    /// </summary>
    public abstract Camera GetCameraWorld();
    
    /// <summary>
    /// Returns a reference to the Inventory component.
    /// </summary>
    public abstract InventoryBehaviour GetInventory();

    /// <summary>
    /// Returns true if the Crosshair should be visible.
    /// </summary>
    public abstract bool IsCrosshairVisible();
    /// <summary>
    /// Returns true if the character is running.
    /// </summary>
    public abstract bool IsRunning();
    
    /// <summary>
    /// Returns true if the character is aiming.
    /// </summary>
    public abstract bool IsAiming();
    /// <summary>
    /// Returns true if the game cursor is locked.
    /// </summary>
    public abstract bool IsCursorLocked();

    /// <summary>
    /// Returns true if the tutorial text should be visible on the screen.
    /// </summary>
    public abstract bool IsTutorialTextVisible();

    /// <summary>
    /// Returns the Movement Input.
    /// </summary>
    public abstract Vector2 GetInputMovement();
    /// <summary>
    /// Returns the Look Input.
    /// </summary>
    public abstract Vector2 GetInputLook();
    
    #endregion

    #region ANIMATION

    /// <summary>
    /// Ejects a casing from the equipped weapon.
    /// </summary>
    public abstract void EjectCasing();
    /// <summary>
    /// Fills the character's equipped weapon's ammunition by a certain amount, or fully if set to -1.
    /// </summary>
    public abstract void FillAmmunition(int amount);

    /// <summary>
    /// Sets the equipped weapon's magazine to be active or inactive!
    /// </summary>
    public abstract void SetActiveMagazine(int active);
    
    /// <summary>
    /// Reload Animation Ended.
    /// </summary>
    public abstract void AnimationEndedReload();

    /// <summary>
    /// Inspect Animation Ended.
    /// </summary>
    public abstract void AnimationEndedInspect();
    /// <summary>
    /// Holster Animation Ended.
    /// </summary>
    public abstract void AnimationEndedHolster();

    #endregion
    }
}

任何帮助将不胜感激。 顺便说一句,我通过实现此代码尝试了自己'

if(Input.getKeyDown("shift") {
    playerCharacter.isRunning = !playerCharacter.isRunning;
}

if(playerCharacter.isRunning)
{
            movement *= speedRunning;
}

我想你所要做的就是添加

Input.GetKeyDown(KeyCode.LeftShift) {
    playerCharacter.isRunning = !playerCharacter.isRunning;
}

在 MoveCharacter 之前进入您的更新函数。

也许在 if 或更新方法中添加一个 Debug.Log("Running: " + playerCharacter.isRunning);

我想你试过的东西不起作用的原因是你需要使用 Input.GetKeyDown("left shift")Input.GetKeyDown("right shift") 使用 KeyCode 通常更节省。

if(Input.GetKeyDown(KeyCode.LeftShift)) 
        {
            playerCharacter.IsRunning(!playerCharacter.IsRunning);
        }