停止我的第一人称角色控制器使用C#在Unity中穿墙?

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

如视频所示: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
{
    public float speed = 5;
    public float jumpPower = 4;

    Rigidbody rb;
    CapsuleCollider col;


    private GameObject player;
    //private float minClamp = -45;
    //private float maxClamp = 45;
    [HideInInspector]
    public Vector2 rotation;
    private Vector2 currentLookRot;
    private Vector2 rotationV = new Vector2(0,0);
    public float lookSensitivity = 2;
    public float lookSmoothDamp = 0.1f;
    public Camera cam;
    public GameObject crossHair;
    bool isActive;
    //public float sensitivityX = 15F;
    //public float sensitivityY = 15F;
    //private float rotationX = 0F;
    //private float rotationY = 0F;
    //private Quaternion originalRotation;






    // Start is called before the first frame update
    void Start()
    {
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;

        rb = GetComponent<Rigidbody>();
        col = GetComponent<CapsuleCollider>();
        player = transform.gameObject;
        crossHair = GameObject.FindWithTag("CrossHair");


    }


    void FixedUpdate()
    {
        float Horizontal = Input.GetAxis("Horizontal");
        float Vertical = Input.GetAxis("Vertical");


        //Vector3 movement = new Vector3(Horizontal, 0, Vertical) * speed * Time.deltaTime;
        //rb.MovePosition(transform.position + movement);


        Vector3 xMovement = transform.right * speed * Horizontal * Time.deltaTime;
        Vector3 zMovement = transform.forward * speed * Vertical* Time.deltaTime;
        rb.MovePosition(transform.position + xMovement + zMovement);


    }



    // Update is called once per frame
        void Update()
    {





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

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

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

        if (Input.GetButtonDown("Sprint"))
        {
            speed = 15;
            //Debug.Log("Sprint Button Held Down");
        }

        if (Input.GetButtonUp("Sprint"))
        {
            speed = 5;
            //Debug.Log("Sprint Button Let Go");
        }

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

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

        /*
        rotationX += Input.GetAxis("Mouse X") * sensitivityX;
        rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
        Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
        Quaternion yQuaternion = Quaternion.AngleAxis(rotationY, -Vector3.right);
        transform.localRotation = originalRotation * xQuaternion * yQuaternion;
        */


        /*
        rotation.y += Input.GetAxis("Mouse Y") * lookSensitivity;
        rotation.y = Mathf.Clamp(rotation.y, minClamp, maxClamp);
        player.transform.RotateAround(transform.position, Vector3.up, Input.GetAxis("Mouse X") * lookSensitivity);
        currentLookRot.y = Mathf.SmoothDamp(currentLookRot.y, rotation.y, ref rotationV.y, lookSmoothDamp);
        cam.transform.localEulerAngles = new Vector3(-currentLookRot.y, 0, 0);
        */
    }

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




}

我在此代码中做错什么,如果是的话,我该如何解决?

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

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

有人建议我使用shapecast,但是我认为这可能不正确吗?我看不到播放器没有添加字符控制器组件的情况,该怎么办?

总体上,如何像上面指定的初始视频中那样阻止我的第一人称角色控制器穿过墙?

UPDATE#1:

此人有类似的问题:https://www.youtube.com/watch?v=QcaGuMor1jg

这似乎是网状对撞机的常见问题,但是没有简单可行的解决方案吗?

c# unity3d
1个回答
0
投票
  1. 您的项目代码与您在此处提供的代码不同。
  2. [尝试启用刚体的旋转约束-冻结X和Z旋转,仅保留Y。旋转胶囊碰撞器时(因为它在项目中起作用),它可以在墙上“爬升”。
  3. 在移动时进行isGrounded检查,如果未接地则锁定移动。
  4. 尝试增加Collider.contactOffset
  5. 如果上述方法无济于事,请尝试使用Rigidbody.velocity而不是Rigidbody.MovePosition。
  6. 您也可以减少Rigidbody.drag
  7. 通常,相当好的技术是使用NavMesh进行移动-这样,您就可以显式地将播放器锁定在导航网格表面之外的移动范围内。但是,当然,它并不适合许多游戏玩法。

希望,会有所帮助。

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