无法获取控制器速度,它始终是0,0,0

问题描述 投票:0回答:1

过去 2 天我一直在尝试让 headbob 脚本运行,但我一直卡在检查控制器速度上,它一直返回零。我有 2 个脚本,playermotor(移动角色)和 headbob 脚本(根据控制器速度计算并应用 headbob),这两个脚本都位于玩家对象上,当我在 headbob 脚本中使用controller.velocity 时,它始终返回 0,0 ,0,但是当我在playermotor脚本中使用它时它工作正常。脚本的顺序是否导致此问题?我已经按照教程 1:1 完成了,唯一的区别是我使相机和电机脚本略有不同。 以下是脚本:

玩家电机脚本:

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

public class PlayerMotor : MonoBehaviour
{
    private CharacterController controller;
    private Vector3 playerVelocity;
    private PlayerLook look;

    private float speed = 5f;
    public float crouchSpeed = 2.5f;
    public float walkSpeed = 5f;
    public float sprintSpeed = 8f;
    public float jumpHeight = 0.6f;
    private float crouchTimer = 1f;
    public float gravity = -9.8f;
    private float standingHeight = 2;
    private float crouchingHeight = 1;
    private float targetHeight = 2;
    private bool isGrounded;
    private bool crouching= false;
    private bool sprinting = false;
    private bool lerpCrouch=false;
   
    
    Vector3 initialCameraPosition;
    void Start()
    {
        controller = GetComponent<CharacterController>();
        look = GetComponent<PlayerLook>();
        initialCameraPosition = look.cam.transform.localPosition;
    }

    // Update is called once per frame
    void Update()
    {
        isGrounded = controller.isGrounded;
        if(lerpCrouch)
        {
            crouchTimer += Time.deltaTime;
            float p = crouchTimer / 1;
            p *= p;
            if(controller.height<standingHeight && targetHeight == standingHeight)
                {           
                var castOrigin = transform.position + new Vector3(0, controller.height / 2, 0);
                if (Physics.Raycast(castOrigin, Vector3.up, out RaycastHit hit, 0.2f))
                {
                    var distanceToCeiling = hit.point.y - castOrigin.y;
                    targetHeight = Mathf.Max (controller.height + distanceToCeiling -0.1f,crouchingHeight);
                }
            }
            controller.height = Mathf.Lerp(controller.height, targetHeight, p);         
            if(p>1)
            {
                lerpCrouch = false;
                crouchTimer = 0f;

            }
        }
    }
    public void ProcessMove(Vector2 input)
    {
        Vector3 moveDirection = Vector3.zero;
        moveDirection.x = input.x;
        moveDirection.z = input.y;  
        controller.Move(transform.TransformDirection(moveDirection)*speed*Time.deltaTime);
        playerVelocity.y += gravity * Time.deltaTime;
        if(isGrounded &&playerVelocity.y <0)
        {
            playerVelocity.y = -2f;
        }
      
        if (!Mathf.Approximately(targetHeight, controller.height))
        {
            var halfHeightDifference = new Vector3(0, (standingHeight - controller.height) / 2, 0);
            var newCameraPosition = initialCameraPosition - halfHeightDifference;
            look.cam.transform.localPosition = newCameraPosition;
        }
        
        controller.Move(playerVelocity*Time.deltaTime);
    }
    public void Jump()
    { 
        if(isGrounded)
        {
            playerVelocity.y = Mathf.Sqrt(jumpHeight*-3.0f * gravity);
        }
    }
    public void Crouch()
    {
        crouching = !crouching;
        sprinting = false;
        if (crouching)
        {
            targetHeight = crouchingHeight;
            speed = crouchSpeed;
        }
        else
        {
            targetHeight = standingHeight;
            speed = walkSpeed;
        }
        crouchTimer = 0;
        lerpCrouch = true;
    }
    public void Sprint()
    {
        if(!crouching)
        {
            sprinting = !sprinting;
            if (sprinting)
            {
                speed = sprintSpeed;
            }
            else
            {
                speed = walkSpeed;
            }
        }
    }
}

Headbob 脚本:


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

public class HeadBobController : MonoBehaviour
{
    [SerializeField] private bool _enable = true;

    [SerializeField, Range(0, 0.1f)] private float _amplitude = 0.015f;
    [SerializeField, Range(0, 30)] private float _frequency = 10.0f;

    [SerializeField] private Transform _camera = null;
    [SerializeField] private Transform _cameraHolder = null;

    private float _toggleSpeed = 3.0f;
    private Vector3 _startPos;
    private CharacterController _controller;

    private void Awake()
    {
        _controller = GetComponent<CharacterController>();
        _startPos = _cameraHolder.localPosition;
    }

    private void Update()
    {
        if (!_enable)
            return;

        CheckMotion();
        ResetPosition();
        _camera.LookAt(FocusTarget());
    }

    private void CheckMotion()
    {
        float speed = new Vector3(_controller.velocity.x, 0, _controller.velocity.z).magnitude;
        Debug.Log(_controller.velocity.magnitude);
        if (speed < _toggleSpeed)
            return;
        if (!_controller.isGrounded)
            return;

        PlayMotion(FootStepMotion());
    }

    private void PlayMotion(Vector3 motion)
    {
        _camera.localPosition += motion;
    }

    private Vector3 FootStepMotion()
    {
        Vector3 pos = Vector3.zero;
        pos.y += Mathf.Sin(Time.time * _frequency) * _amplitude;
        pos.x += Mathf.Cos(Time.time * _frequency / 2) * _amplitude * 2;
        return pos;
    }

    private void ResetPosition()
    {
        if (_camera.localPosition == _startPos)
            return;
        _camera.localPosition = Vector3.Lerp(_camera.localPosition, _startPos, 1 * Time.deltaTime);
    }

    private Vector3 FocusTarget()
    {
        Vector3 pos = new Vector3(transform.position.x, transform.position.y + _cameraHolder.localPosition.y, transform.position.z);
        pos += _cameraHolder.forward * 15.0f;
        return pos;
    }
}

我尝试过多种方法,但这种摇头方法最接近我想要的。

c# unity-game-engine
1个回答
0
投票

我想通了,我从废品重新制作了外观脚本,直接在相机上,并合并了向量,使其成为单个移动调用,这解决了所有问题。

© www.soinside.com 2019 - 2024. All rights reserved.