我尝试了聊天 GPT,它无法弄清楚,我也无法弄清楚。 玩家.cs:
using System.Collections;
using UnityEngine;
public class Player : MonoBehaviour
{
private CharacterController characterController;
private Vector3 moveDir;
public float speed = 5f;
private float gravity = 20f;
private Vector3 gravityDir = Vector3.down; // Başlangıçta yerçekimi aşağıya doğru
public float jumpForce = 10f;
private Vector3 verticalVelocity;
private bool isWalking;
private RootLook rootLook;
public float gravityRotationSpeed = 5f;
public float gravityChangeCooldown = 10f;
private float lastGravityChangeTime = -Mathf.Infinity;
// LayerMask for surfaces (walls, ceilings, etc.)
public LayerMask surfaceLayer;
void Awake()
{
characterController = GetComponent<CharacterController>();
rootLook = FindObjectOfType<RootLook>();
}
void Update()
{
MoveThePlayer();
CheckGravityChange();
}
void MoveThePlayer()
{
Vector3 inputDir = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
// Get camera directions based on gravity
Transform cameraTransform = Camera.main.transform;
Vector3 forward = Vector3.ProjectOnPlane(cameraTransform.forward, gravityDir).normalized;
Vector3 right = Vector3.ProjectOnPlane(cameraTransform.right, gravityDir).normalized;
// Calculate movement direction
moveDir = (right * inputDir.x + forward * inputDir.z).normalized * speed;
// Check if the player is walking
isWalking = moveDir != Vector3.zero;
// Apply gravity and vertical movement
ApplyGravity();
// Move the character including both movement and vertical velocity (gravity/jumping)
characterController.Move((moveDir + verticalVelocity) * Time.deltaTime);
}
void ApplyGravity()
{
if (!IsGrounded())
{
// Karakter zeminde değilse yerçekimi uygulanır
verticalVelocity += gravityDir * gravity * Time.deltaTime;
}
else if (verticalVelocity.magnitude < 0.1f)
{
// Eğer zemindeyse ve dikey hız çok küçükse, yerçekimini sıfırla
verticalVelocity = Vector3.zero;
}
PlayerJump(); // Karakter zıplayabiliyorsa, zıplama işlemi yapılır
}
bool IsGrounded()
{
Ray ray = new Ray(transform.position, gravityDir);
RaycastHit hit;
// Zeminle temas edip etmediğini kontrol et
if (Physics.Raycast(ray, out hit, 1f, surfaceLayer))
{
return true;
}
return false;
}
void PlayerJump()
{
// Space tuşuna basılıyken ve karakter zemindeyken zıplamaya izin ver
if (Input.GetKey(KeyCode.Space) && IsGrounded())
{
verticalVelocity = -gravityDir * jumpForce;
}
}
public bool IsWalking()
{
return isWalking;
}
void CheckGravityChange()
{
if (Input.GetKeyDown(KeyCode.G) && Time.time - lastGravityChangeTime >= gravityChangeCooldown)
{
lastGravityChangeTime = Time.time;
Vector3 newGravityDir = GetNewGravityDirection();
newGravityDir.Normalize();
// Yerçekimi değiştikten sonra hareket yönlerini tekrar hesapla
StartCoroutine(ChangeGravityAndMovePlayer(newGravityDir));
}
}
IEnumerator ChangeGravityAndMovePlayer(Vector3 newGravityDir)
{
yield return StartCoroutine(RotatePlayerTowardsGravity(newGravityDir));
yield return StartCoroutine(RotateCameraTowardsGravity(newGravityDir));
gravityDir = newGravityDir;
verticalVelocity = Vector3.zero; // Zıplamadan sonra verticalVelocity'yi sıfırla
yield return StartCoroutine(DetachFromWalls());
MoveThePlayer();
}
Vector3 GetNewGravityDirection()
{
// Yerçekimi yönlerini sıralı olarak değiştir
if (gravityDir == Vector3.down) return Vector3.left;
if (gravityDir == Vector3.left) return Vector3.up;
if (gravityDir == Vector3.up) return Vector3.right;
return Vector3.down;
}
IEnumerator RotatePlayerTowardsGravity(Vector3 newGravityDir)
{
Quaternion targetRotation = Quaternion.FromToRotation(transform.up, -newGravityDir) * transform.rotation;
// Karakterin düzgün bir şekilde yönlenmesi için yerçekimi yönüne doğru döndürme işlemi
while (Quaternion.Angle(transform.rotation, targetRotation) > 0.1f)
{
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * gravityRotationSpeed);
yield return null;
}
transform.rotation = targetRotation;
}
IEnumerator RotateCameraTowardsGravity(Vector3 newGravityDir)
{
Quaternion targetRotation = Quaternion.FromToRotation(Camera.main.transform.up, -newGravityDir) * Camera.main.transform.rotation;
// Kameranın düzgün bir şekilde yönlenmesi için yerçekimi yönüne doğru döndürme işlemi
while (Quaternion.Angle(Camera.main.transform.rotation, targetRotation) > 0.1f)
{
Camera.main.transform.rotation = Quaternion.Slerp(Camera.main.transform.rotation, targetRotation, Time.deltaTime * gravityRotationSpeed);
yield return null;
}
Camera.main.transform.rotation = targetRotation;
}
IEnumerator DetachFromWalls()
{
float detachTime = 0.2f; // Detach işlemi için zamanı artırdık
Vector3 detachVelocity = gravityDir * gravity * detachTime;
float elapsedTime = 0f;
while (elapsedTime < detachTime)
{
characterController.Move(detachVelocity * Time.deltaTime);
elapsedTime += Time.deltaTime;
yield return null;
}
}
}
也许你运行新游戏的方式是关键。
但是,您应该尝试使用 Visual Studio 中的调试器来跟踪导致不必要的玩家垂直移动的原因。