簡體   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