【问题标题】:Variable change is shown in the unity inspector but doesn't actually take place变量更改显示在统一检查器中,但实际上并未发生
【发布时间】:2021-08-18 17:56:46
【问题描述】:

我对 c#、统一和编码非常陌生。我正在尝试制作一个可以蹲下、跳跃和冲刺的可控 3d 角色。由于我在标题中所描述的,Sprinting 目前不起作用:玩家的速度在统一检查器中更新,但实际上并没有在游戏中改变。

完整的玩家移动脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{


    public CharacterController controller;

    
    public float gravity = -9.807f;

    public Transform groundCheck;

    public float groundDistance = 0.4f;

    public LayerMask groundMask;

    public float jumpHeight = 3f;

    public float crouchHeight = 0.9f;

    public float playerPushPower = 2.0f;

    public float speed = 16f;

    public float sprintSpeed = 1.5f;

    public float crouchSpeed = 0.5f;

    private float baseSpeed = 16f;

    
    bool isGrounded;

    bool isSprinting = false;

    bool isCrouching = false;

    bool isJumping = false;
    
    bool isStanding = true;
    






    Vector3 velocity;







    void OnControllerColliderHit(ControllerColliderHit hit)
    {
        Rigidbody body = hit.collider.attachedRigidbody;


        playerPushPower = speed / 8;

        



        // no rigidbody
        if (body == null || body.isKinematic)
            return;

        // We dont want to push objects below us
        if (hit.moveDirection.y < -0.3f)
            return;

        // Calculate push direction from move direction,
        // we only push objects to the sides never up and down
        Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);

        // If you know how fast your character is trying to move,
        // then you can also multiply the push velocity by that.

        


    


        // Apply the push
        body.velocity = pushDir * playerPushPower;
    }
    
    
    

   
    // Update is called once per frame
    void Update()
    {
        isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);


        controller.height = 3.8f;

        



        if(isGrounded && velocity.y < 0)
        { 
            velocity.y = -2f;
        }

        


      

      if(Input.GetKey("left ctrl") && isGrounded) 
      {
        speed = speed * crouchSpeed;
        isCrouching = true;
        isStanding = false;
        

      }
      else 
      {
        speed = 16f;
        isCrouching = false;
        isStanding = true;
    
      }

      
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        Vector3 move = transform.right * x + transform.forward * z;

        controller.Move(move * speed * Time.deltaTime);

        if (Input.GetButtonDown("Jump") && isGrounded && isStanding)
        {
            velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
            isJumping = true;
        }

        velocity.y += gravity * Time.deltaTime;

        controller.Move(velocity * Time.deltaTime);




        if(Input.GetKey("left shift") && isGrounded && isStanding) 
      {
        speed = speed * sprintSpeed;
        isSprinting = true;
        
      }
      else 
      {
        speed = 16f;
        isSprinting = false;
      }





        
        
    }
}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    查看速度是如何计算并应用于移动角色的:

    void Update()
    {
        ...
        // 1) Reset the speed to 16 if left ctrl isn't pressed
        if(Input.GetKey("left ctrl") && isGrounded)
        {
            speed = speed * crouchSpeed;
            isCrouching = true;
            isStanding = false;
        }
        else 
        {
            speed = 16f;
            isCrouching = false;
            isStanding = true;
        }
        ...
        // 2) Move the character according to speed
        Vector3 move = transform.right * x + transform.forward * z;
        controller.Move(move * speed * Time.deltaTime);
        ...
        // 3) Apply the sprint factor to speed
        if(Input.GetKey("left shift") && isGrounded && isStanding) 
        {
            speed = speed * sprintSpeed;
            isSprinting = true;
        }
        else 
        {
            speed = 16f;
            isSprinting = false;
        }
    }
    

    如您所见,冲刺因子被忽略,因为角色在冲刺因子被应用之前被移动。 解决方案是在移动角色之前应用冲刺因子。

    void Update()
    {
        ...
        // 1) Reset the speed to 16 if left ctrl isn't pressed
        if(Input.GetKey("left ctrl") && isGrounded)
        {
            speed = speed * crouchSpeed;
            isCrouching = true;
            isStanding = false;
        }
        else 
        {
            speed = 16f;
            isCrouching = false;
            isStanding = true;
        }
        ...
        // 2) Apply the sprint factor to speed
        if(Input.GetKey("left shift") && isGrounded && isStanding) 
        {
            speed = speed * sprintSpeed;
            isSprinting = true;
        }
        else 
        {
            speed = 16f;
            isSprinting = false;
        }
        ...
        // 2) Move the character according to speed (included the sprint factor)
        Vector3 move = transform.right * x + transform.forward * z;
        controller.Move(move * speed * Time.deltaTime);
        ...
    }
    

    奖励:当按下左 ctrl 键时,速度不会重新初始化。 然后速度降低每一帧。我不认为这是预期的。

    【讨论】:

    • 首先,非常感谢您的回答。其次,您能否详细说明一下:“奖励:按下左键时速度不会重新初始化。然后每帧降低速度。我认为这不是预期的。”我不确定我是否理解。
    • 玩游戏,试着做一个蹲着的动作……我想你很快就会明白
    • 我明白了,我该如何解决它?
    • 我认为在任何情况下都需要重新设置速度。只需将speed = 16f; 作为方法Update 的第一行。
    猜你喜欢
    • 2011-04-27
    • 2017-04-04
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 1970-01-01
    相关资源
    最近更新 更多