我正在空心球世界中制作第一人称游戏,并通过让玩家成为世界中心物体的孩子来移动玩家,然后旋转。球体内部有物体,我不希望玩家走过。
附着碰撞器和刚体使得玩家在与所述物体碰撞时变得与父母脱离并且在碰撞物理学指示的任何方向上滚动。我似乎在这里需要一个Trigger而不是Collider,但我不确定为了保持玩家在Trigger之外的移动而向OnTriggerEnter提供什么方向,同时不允许它进一步进入Trigger。
所以我需要的是确保满足以下条件的方法:
父级中心棋子和儿童玩家对象始终保留在其中 原始关系。
与另一个对象发生碰撞会阻止父对象的旋转 在所述物体的方向上。
如果有任何帮助,下面是播放器脚本,它附加到球体世界中心的父对象。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class PlayerController2 : MonoBehaviour
{
public float XSensitivity = 2f;
public float YSensitivity = 2f;
public bool clampVerticalRotation = true;
public float MinimumX = -90F;
public float MaximumX = 90F;
public float speed = 1;
public bool smooth;
public float smoothTime = 5f;
public bool lockCursor = true;
public bool playerMovement = false;
private Quaternion m_PlayerTargetRot;
private Quaternion m_CameraTargetRot;
private bool m_cursorIsLocked = true;
private Transform player;
public Transform cam;
// Use this for initialization
void Awake()
{
player = GetComponent<Transform>();
m_PlayerTargetRot = player.localRotation;
m_CameraTargetRot = cam.localRotation;
}
// Update is called once per frame
void Update()
{
float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity; //mouselook, lookrotation()
float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
if (playerMovement)
{
Vector2 input = new Vector2
{
x = CrossPlatformInputManager.GetAxis("Horizontal") * speed,
y = CrossPlatformInputManager.GetAxis("Vertical") * speed
};
m_PlayerTargetRot *= Quaternion.Euler(-input.y, yRot, input.x);
}
else
m_PlayerTargetRot *= Quaternion.Euler(0f, yRot, 0f);
m_CameraTargetRot *= Quaternion.Euler(-xRot, 0.0f, 0.0f);
if (clampVerticalRotation)
m_CameraTargetRot = ClampRotationAroundXAxis(m_CameraTargetRot);
cam.localRotation = Quaternion.Slerp(cam.localRotation, m_CameraTargetRot, smoothTime * Time.deltaTime);
player.localRotation = Quaternion.Slerp(player.localRotation, m_PlayerTargetRot, smoothTime * Time.deltaTime);
UpdateCursorLock();
}
public void SetCursorLock(bool value)
{
lockCursor = value;
if (!lockCursor)
{//we force unlock the cursor if the user disable the cursor locking helper
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
public void UpdateCursorLock()
{
//if the user set "lockCursor" we check & properly lock the cursos
if (lockCursor)
InternalLockUpdate();
}
private void InternalLockUpdate()
{
if (Input.GetKeyUp(KeyCode.Escape))
{
m_cursorIsLocked = false;
}
else if (Input.GetMouseButtonUp(0))
{
m_cursorIsLocked = true;
}
if (m_cursorIsLocked)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
else if (!m_cursorIsLocked)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
Quaternion ClampRotationAroundXAxis(Quaternion q) //I haven't dissected this yet, but it works... (taken from Unity's "MouseLook.cs") like much of the above.
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1.0f;
float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);
angleX = Mathf.Clamp(angleX, MinimumX, MaximumX);
q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX);
return q;
}
}