繁体   English   中英

使用 C# 阻止我的第一人称角色 controller 在 Unity 中穿墙?

[英]Stop my first person character controller going through the wall in Unity using C#?

如视频所示: https://i.gyazo.com/ad45ef9e231fd2f9ec6d4cf76889aece.mp4

我的代码:

MouseLook.cs:

using UnityEngine;
using System.Collections;

public class MouseLook : MonoBehaviour
{
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 3F;
public float sensitivityY = 3F;
public Camera playerCamera;

public float minimumX = -360F;
public float maximumX = 360F;

public float minimumY = -60F;
public float maximumY = 60F;



private float rotationX = 0F;
private float rotationY = 0F;

private Quaternion originalRotation;

void Update()
{
    if (axes == RotationAxes.MouseXAndY)
    {
        rotationX += Input.GetAxis("Mouse X") * sensitivityX;
        rotationY += Input.GetAxis("Mouse Y") * sensitivityY;

        rotationX = ClampAngle(rotationX, minimumX, maximumX);
        rotationY = ClampAngle(rotationY, minimumY, maximumY);

        Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
        Quaternion yQuaternion = Quaternion.AngleAxis(rotationY, -Vector3.right);

        transform.localRotation = originalRotation * xQuaternion * yQuaternion;
    }

    if (axes == RotationAxes.MouseX)
    {
        rotationX += Input.GetAxis("Mouse X") * sensitivityX;
        rotationX = ClampAngle(rotationX, minimumX, maximumX);

        Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
        transform.localRotation = originalRotation * xQuaternion;
    }

    if (axes == RotationAxes.MouseY || playerCamera != null)
    {
        rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
        rotationY = ClampAngle(rotationY, minimumY, maximumY);

        Quaternion yQuaternion = Quaternion.AngleAxis(-rotationY, Vector3.right);

        if (playerCamera != null)
        {
            playerCamera.transform.localRotation = originalRotation * yQuaternion;
        }
        else
        {
            transform.localRotation = originalRotation * yQuaternion;
        }
    }
}

void Start()
{
    /*
    if (gameObject.GetComponent<Rigidbody>())
    {
        gameObject.GetComponent<Rigidbody>().freezeRotation = true;
    }
    */
    originalRotation = transform.localRotation;
}

public static float ClampAngle(float angle, float min, float max)
{
    if (angle < -360F)
    {
        angle += 360F;
    }

    if (angle > 360F)
    {
        angle -= 360F;
    }

    return Mathf.Clamp(angle, min, max);
}

}

FirstPersonController.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using Cursor = UnityEngine.Cursor;




public class FirstPersonController : MonoBehaviour
{
    private float speed = 5;
    private float jumpPower = 4;
    Rigidbody rb;
    CapsuleCollider col;
    public GameObject crossHair;
    bool isActive;
    float HorizontalInput;
    float VerticalInput;


    void Start()
    {
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
        rb = GetComponent<Rigidbody>();
        col = GetComponent<CapsuleCollider>();
        crossHair = GameObject.FindWithTag("CrossHair");
    }


    void Update()
    {
        HorizontalInput = Input.GetAxisRaw("Horizontal");
        VerticalInput = Input.GetAxisRaw("Vertical");

        if (Input.GetKeyDown("escape"))
        {
            Cursor.lockState = CursorLockMode.None;
        }

        if (Input.GetButtonDown("Sprint"))
        {
            speed = 15;
        }

        if (Input.GetButtonUp("Sprint"))
        {
            speed = 5;
        }

        if (Input.GetKeyDown(KeyCode.H))
        {
            isActive = !isActive;
        }

        if (isActive)
        {
            crossHair.SetActive(true);
        }
        else
        {
            crossHair.SetActive(false);
        }

    }


    void FixedUpdate()
    {
        Vector3 xMovement = transform.right * speed * HorizontalInput * Time.deltaTime;
        Vector3 zMovement = transform.forward * speed * VerticalInput * Time.deltaTime;
        rb.velocity = new Vector3(HorizontalInput, 0, VerticalInput) * speed;



        if (isGrounded() && Input.GetButtonDown("Jump"))

        {
            rb.AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
        }
    }


    private bool isGrounded()
    {
        return Physics.Raycast(transform.position, Vector3.down, col.bounds.extents.y + 0.1f);
    }
}

我在这段代码中做错了什么,如果有,我该如何解决?

整个项目可以在这里下载: https://github.com/Some-T/FirstPersonController-CSharp

项目设置了相关的对撞机和刚体!

有人建议我使用 shapecast,但我认为这可能不正确? 我看不出这将如何工作,因为我的播放器没有添加角色 controller 组件?

总的来说,我如何阻止我的第一人称角色 controller 像上面指定的初始视频一样穿过墙壁?

经过进一步研究,我发现了以下内容:

答案是使用:

https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html作为快速修复。

但绝对是为了完美使用:

https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html

至于如何在 C# 我不太确定,但这是我在螺栓资产中所做的屏幕截图。

在此处输入图像描述

目前我的运动与速度一起工作,但它不能正常工作,不知道为什么? 所以总的来说,我现在的问题是如何使用速度进行运动? 我在 FirstPersonController.cs 中添加了一行,它使用rb.velocity = new Vector3(HorizontalInput, 0, VerticalInput) * speed;的速度移动角色。 所以我现在唯一的问题和问题是我的播放器没有朝着我播放器上的相机所面对的方向移动,所以我不确定如何整体解决这个特定问题?

  1. 您的项目代码与您在此处提供的代码不同。
  2. 尝试启用刚体的旋转约束 - 冻结 X 和 Z 旋转,只留下 Y。当您旋转胶囊对撞机(因为它在您的项目中工作)时,它可以“爬”在墙上。
  3. 移动时进行 isGrounded 检查,如果未接地,则锁定移动。
  4. 尝试增加Collider.contactOffset
  5. 如果上述方法没有帮助,请尝试使用 Rigidbody.velocity 而不是 Rigidbody.MovePosition。
  6. 您还可以减少 Rigidbody.drag
  7. 一般来说,很好的技术是使用导航网格进行移动——这样,您可以明确地锁定玩家,使其无法在导航网格表面之外移动。 但是,当然,它不适合许多游戏玩法。

希望能帮助到你。

upd 你像这样移动你的播放器:

void FixedUpdate()
    {
        Vector3 xMovement = transform.right * speed * HorizontalInput * Time.deltaTime;
        Vector3 zMovement = transform.forward * speed * VerticalInput * Time.deltaTime;
    }

请注意,您甚至没有将其应用于刚体; 但是您可以通过以下方式获得输入:

float HorizontalInput = Input.GetAxis("Horizontal");         
float VerticalInput = Input.GetAxis("Vertical");

在更新中,所以输入只是留在更新中,根本不应用。 您声明了两次变量,一次在 class 顶部,另一次在 Update() 中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM