[英]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;
的速度移动角色。 所以我现在唯一的问题和问题是我的播放器没有朝着我播放器上的相机所面对的方向移动,所以我不确定如何整体解决这个特定问题?
希望能帮助到你。
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.