Я работаю над игрой на Unity, в которой мне нужно, чтобы персонаж игрока находился в пределах определенных граничных коллайдеров. Я хочу зафиксировать положение игрока, чтобы он не мог выйти за пределы этих границ. Однако даже когда игрок находится за пределами границ, кажется, что позиция фиксируется неправильно.
Позиция игрока фиксируется, но кажется, что она всё равно ограничена даже после пересечения граничных коллайдеров. . Я настроил метод ClampPositionToRoad для фиксации координаты X игрока между левой и правой границами, но он не работает должным образом.
protected virtual void ClampPositionToRoad()
{
float leftBoundary = leftBoundaryCollider.transform.position.x - (leftBoundaryCollider.size.x * 0.5f);
float rightBoundary = rightBoundaryCollider.transform.position.x + (rightBoundaryCollider.size.x * 0.5f);
Debug.Log($"Left Boundary: {leftBoundary}, Right Boundary: {rightBoundary}");
Vector3 clampedPosition = transform.position;
clampedPosition.x = Mathf.Clamp(transform.position.x, leftBoundary, rightBoundary);
transform.position = clampedPosition;
}
Как повернуть на 90 градусов влево или вправо, когда положение x ограничено границами?
Как я это пробовал много методов, только добавление границ, но это не работает.
Я пробовал настроить граничные значения и распечатать границы и положение игрока с помощью Debug.Log, но проблема сохраняется. Я также тестировал жестко заданные значения границ, но результат был тот же.
Как правильно зафиксировать положение игрока внутри граничных коллайдеров в Unity? Есть ли какие-либо ошибки в моем нынешнем подходе или есть ли лучший способ справиться с этим?
Версия Unity: 2022.3.17f56
Платформа: MAC
Мой полный код приведен ниже. Предложите мне другие изменения, пожалуйста.
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
using UnityEngine.UI;
public class Player : MonoBehaviour
{
public BoxCollider leftBoundaryCollider;
public BoxCollider rightBoundaryCollider;
public float speedModifier = 0.05f;
public float cameraSpeed = 0.05f;
public Vector3 cameraRotation;
public Vector3 cameraPosition;
public GameObject skinnedMeshObject;
private SkinnedMeshRenderer skinnedMeshRenderer;
public float timeScoreMultiplier = 10f;
public float crouchDuration = 1f;
public float pursuerPositionOffset = 4f;
public float initialHitSpeed = -10f;
public float hitSpeedDecreaseSpeed = 80f;
public LayerMask levelLayer;
public AudioClip jumpSideClip;
public AudioClip jumpClip;
public AudioClip gameOverClip;
public AudioClip crouchClip;
public BoxCollider[] boxCollider;
public CapsuleCollider[] capsuleColliders;
public float mouseAndTouchMoveDistance = 80f;
public bool enableKeyboardMovement = true;
public bool enableMouseMovement = true;
[SerializeField]
protected float m_GroundCheckDistance = 0.1f;
protected float m_OrigGroundCheckDistance;
protected Vector3 m_GroundNormal;
[SerializeField]
protected float m_JumpPower = 12f;
[SerializeField]
protected float stepDistance = 1.5f;
private bool countdownFinished = false;
public float speed = 3f;
public int skinPrice = 1000;
protected Animator anim;
public AudioSource countdownSound;
public Text CountText;
protected float posX = 0.0f;
protected float startTime;
protected float jumpSpeed;
protected bool m_Jump;
protected Rigidbody m_Rigidbody;
protected bool m_PreviouslyGrounded, m_IsGrounded;
protected Collider m_Collider;
protected Vector3 m_GroundContactNormal;
protected bool dead;
protected int coins;
protected float time;
protected bool crouching;
protected float crouchDeltaHeight = 1f;
protected Manager manager;
protected float jumpMultiplier = 1f;
protected float timeMultiplier = 1f;
protected float coinsMultiplier = 1f;
protected float jumpMultiplierTime;
protected float timeMultiplierTime;
protected float coinsMultiplierTime;
protected AudioSource audioSource;
protected Vector2 fp; // first finger position
protected Vector2 lp; // last finger position
protected bool swiped = true;
protected float animForward = 0.5f;
public bool gamemodeon = false;
public bool cameramode = true;
protected float hitSpeedLoc;
[HideInInspector]
public Transform thisTransform;
protected bool atThreeWayJunction = false; // Flag to check if player is at a three-way junction
protected bool atTwoWayJunction = false;
protected virtual void Awake()
{
thisTransform = transform;
}
protected virtual void Start()
{
hitSpeedLoc = speed;
anim = GetComponentInChildren();
anim.applyRootMotion = false;
m_Collider = GetComponent();
m_Rigidbody = GetComponent();
m_OrigGroundCheckDistance = m_GroundCheckDistance;
audioSource = GetComponent();
skinnedMeshRenderer = skinnedMeshObject.GetComponent();
StartCoroutine(StartCountdown());
leftBoundaryCollider = GameObject.FindGameObjectWithTag("LeftBoundary").GetComponent();
rightBoundaryCollider = GameObject.FindGameObjectWithTag("RightBoundary").GetComponent();
}
IEnumerator StartCountdown()
{
countdownSound.Play();
// Display "3"
CountText.text = "3";
yield return new WaitForSeconds(1f);
// Display "2"
CountText.text = "2";
yield return new WaitForSeconds(1f);
// Display "1"
CountText.text = "1";
yield return new WaitForSeconds(1.5f);
// Display "Go!"
CountText.text = "Run!";
yield return new WaitForSeconds(1f);
// Set the countdown finished flag to true
countdownFinished = true;
countdownSound.Stop();
// Clear the countdown text
CountText.text = "";
gamemodeon = true;
cameramode = false;
}
private IEnumerator SlowPlayerSpeedAndFlashCoroutine(float slowDownFactor, float duration, float flashInterval)
{
float elapsedTime = 0f;
bool isVisible = true;
float originalSpeed = speed;
while (elapsedTime < duration)
{
if (skinnedMeshRenderer != null)
{
skinnedMeshRenderer.enabled = isVisible;
isVisible = !isVisible;
speed = 2.5f;
}
yield return new WaitForSeconds(flashInterval);
elapsedTime += flashInterval;
}
if (skinnedMeshRenderer != null)
{
skinnedMeshRenderer.enabled = true; // Ensure the player is visible at the end
}
speed = originalSpeed;
}
private void HandleSwipe(bool left)
{
if (atThreeWayJunction || atTwoWayJunction)
{
RotatePlayer(left);
}
else
{
MoveSide(left);
}
}
protected virtual void RotatePlayer(bool left)
{
if (atThreeWayJunction)
{
float rotationAngle = left ? 90f : -90f;
Quaternion targetRotation = Quaternion.Euler(0, rotationAngle, 0);
// Rotate smoothly over time
StartCoroutine(RotateOverTime(targetRotation, 0.5f));
// // Ensure movement aligns with new rotation
// StartCoroutine(EnsureMovementAfterRotation(rotationAngle));
}
if (atTwoWayJunction)
{
if (left)
{
float rotationAngle = 90f;
Quaternion targetRotation = Quaternion.Euler(0, rotationAngle, 0);
// Rotate smoothly over time
StartCoroutine(RotateOverTime(targetRotation, 0.5f));
}
}
}
private IEnumerator RotateOverTime(Quaternion targetRotation, float duration)
{
Quaternion startRotation = thisTransform.rotation;
float elapsedTime = 0f;
while (elapsedTime < duration)
{
thisTransform.rotation = Quaternion.Slerp(startRotation, targetRotation, elapsedTime / duration);
elapsedTime += Time.deltaTime;
yield return null;
}
thisTransform.rotation = targetRotation;
}
private IEnumerator HighPlayerSpeedCoroutine(float highDownFactor, float duration)
{
float originalSpeed = speed;
speed *= highDownFactor;
yield return new WaitForSeconds(duration);
speed = originalSpeed;
}
protected virtual void Crouch()
{
audioSource.PlayOneShot(crouchClip);
anim.SetBool("Crouch", true);
crouching = true;
for (int i = 0; i < boxCollider.Length; i++)
{
boxCollider.size -= new Vector3(0, crouchDeltaHeight, 0);
boxCollider.center -= new Vector3(0, crouchDeltaHeight / 2, 0);
}
for (int i = 0; i < capsuleColliders.Length; i++)
{
capsuleColliders.height -= crouchDeltaHeight;
capsuleColliders.center -= new Vector3(0, crouchDeltaHeight / 2, 0);
}
Invoke("stopCrouching", crouchDuration);
}
protected virtual void stopCrouching()
{
anim.SetBool("Crouch", false);
crouching = false;
for (int i = 0; i < boxCollider.Length; i++)
{
boxCollider.size += new Vector3(0, crouchDeltaHeight, 0);
boxCollider.center += new Vector3(0, crouchDeltaHeight / 2, 0);
}
for (int i = 0; i < capsuleColliders.Length; i++)
{
capsuleColliders.height += crouchDeltaHeight;
capsuleColliders.center += new Vector3(0, crouchDeltaHeight / 2, 0);
}
}
protected virtual void Jump()
{
RaycastHit hitInfo;
if (!Physics.Raycast(thisTransform.position + Vector3.up, Vector3.up, out hitInfo, 2f, levelLayer))
{
m_Jump = true;
if (crouching)
{
CancelInvoke("stopCrouching");
stopCrouching();
}
}
}
protected virtual void MoveSide(bool right)
{
if (m_IsGrounded)
{
anim.SetBool("Side", right);
anim.SetTrigger("JumpSide");
audioSource.PlayOneShot(jumpSideClip);
}
if (crouching)
{
CancelInvoke("stopCrouching");
stopCrouching();
}
Vector3 direction = right ? thisTransform.right : -thisTransform.right;
// Calculate new position
Vector3 newPosition = thisTransform.position + direction * stepDistance;
// // Apply movement without rotation
thisTransform.position = newPosition;
// Debugging information
Debug.Log("Moving " + (right ? "right" : "left") + ". Direction: " + direction);
}
protected bool HasMouseMoved()
{
return (Input.GetAxis("Mouse X") != 0) || (Input.GetAxis("Mouse Y") != 0);
}
protected virtual void Update()
{
if (!dead && gamemodeon && !cameramode && Time.timeScale != 0)
{
CheckGroundStatus();
if (animForward < 1f)
{
anim.SetFloat("Forward", animForward);
animForward += Time.deltaTime * 2f;
}
else
anim.SetFloat("Forward", 1f);
if (!crouching)
anim.SetBool("OnGround", m_IsGrounded);
if (!m_IsGrounded)
anim.SetFloat("Jump", m_Rigidbody.velocity.y);
#if UNITY_ANDROID || UNITY_IOS
//Mobile Platforms movement
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
swiped = false;
fp = touch.position;
lp = touch.position;
}
if (touch.phase == TouchPhase.Moved)
{
lp = touch.position;
}
if (touch.phase == TouchPhase.Ended)
{
swiped = true;
}
if(!swiped)
{
if ((fp.x - lp.x) > mouseAndTouchMoveDistance) // left swipe
{
// swiped = true;
// MoveSide(false);
HandleSwipe(false);
}
else if ((fp.x - lp.x) < -mouseAndTouchMoveDistance) // right swipe
{
// swiped = true;
// MoveSide(true);
HandleSwipe(true);
}
else if ((fp.y - lp.y) < -mouseAndTouchMoveDistance) // up swipe
{
if (!m_Jump)
{
swiped = true;
Jump();
}
}
else if ((fp.y - lp.y) > mouseAndTouchMoveDistance) // down swipe
{
if (m_IsGrounded && !crouching)
{
swiped = true;
Crouch();
}
}
}
}
#else
//Mouse movement
if (enableMouseMovement)
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
swiped = false;
fp = Input.mousePosition;
lp = Input.mousePosition;
}
if (HasMouseMoved())
{
lp = Input.mousePosition;
}
if (Input.GetKeyUp(KeyCode.Mouse0))
{
swiped = true;
}
if (!swiped)
{
if ((fp.x - lp.x) > mouseAndTouchMoveDistance) // left swipe
{
// swiped = true;
// MoveSide(false);
HandleSwipe(false);
}
else if ((fp.x - lp.x) < -mouseAndTouchMoveDistance) // right swipe
{
// swiped = true;
// MoveSide(true);
HandleSwipe(true);
}
else if ((fp.y - lp.y) < -mouseAndTouchMoveDistance) // up swipe
{
if (!m_Jump)
{
swiped = true;
Jump();
}
}
else if ((fp.y - lp.y) > mouseAndTouchMoveDistance) // down swipe
{
if (m_IsGrounded && !crouching)
{
swiped = true;
Crouch();
}
}
}
}
//Keyboard movement
if (enableKeyboardMovement)
{
float horizontal = CrossPlatformInputManager.GetAxis("Horizontal");
float vertical = CrossPlatformInputManager.GetAxis("Vertical");
Vector3 m_Input = new Vector2(horizontal, vertical);
if (CrossPlatformInputManager.GetButtonDown("Horizontal") && m_Input.x < 0)
{
// MoveSide(false);
HandleSwipe(false);
}
if (CrossPlatformInputManager.GetButtonDown("Horizontal") && m_Input.x > 0)
{
// MoveSide(true);
HandleSwipe(true);
}
if (CrossPlatformInputManager.GetButtonDown("Vertical") && m_Input.y > 0)
{
if (!m_Jump)
{
Jump();
}
}
if (CrossPlatformInputManager.GetButtonDown("Vertical") && m_Input.y < 0)
{
if (m_IsGrounded && !crouching)
{
Crouch();
}
}
}
#endif
if (m_IsGrounded)
{
HandleGroundedMovement(m_Jump);
}
speed += Time.deltaTime * speedModifier;
if (timeMultiplierTime > 0)
{
timeMultiplierTime -= Time.deltaTime;
if (timeMultiplierTime 0)
{
coinsMultiplierTime -= Time.deltaTime;
if (coinsMultiplierTime 0)
{
jumpMultiplierTime -= Time.deltaTime;
if (jumpMultiplierTime
Подробнее здесь: https://stackoverflow.com/questions/788 ... -colliders
Как правильно зафиксировать положение игрока в граничных коллайдерах? ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение