CameraRig смещается в неправильное положение при переключении с вида от первого лица на вид от третьего после движенияC#

Место общения программистов C#
Ответить
Anonymous
 CameraRig смещается в неправильное положение при переключении с вида от первого лица на вид от третьего после движения

Сообщение Anonymous »

Код: Выделить всё

using System.Collections;
using Unity.Mathematics;
using Unity.Mathematics.Geometry;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
public class CameraController : MonoBehaviour
{
PlayerStats playerStats;
CharacterRagdollController characterRagdollController;
[SerializeField]
private Transform target;  // right eye of  character
[SerializeField]
private Camera TPCamera;
[SerializeField]
private Camera FPCamera;
[SerializeField]
private Transform CameraRig;
private Camera enabledCamera;
public Camera EnabledCamera =\> enabledCamera;
private new Renderer[] renderer;
private Color[] color;
private MaterialPropertyBlock propBlock;
private static readonly int colorPropertyID = Shader.PropertyToID("\_BaseColor");
[SerializeField]
private float FPFOV = 60;
[SerializeField]
private float FOVChangeSpeed = 5f;
[SerializeField]
private float cameraPositionSmoothSpeed = 10f;
[SerializeField]
private Vector3 TPOffset = new Vector3(0, 0, -6);
[SerializeField]
private Vector3 FPOffset = new Vector3(0, 0.4f, 0);
[SerializeField]
private float sensitivity = 3f;
[SerializeField]
private float minYAngle = -85f;
[SerializeField]
private float maxYAngle = 85f;
[SerializeField]
private float cameraCollisionBuffer = 0.2f;
private float currentX = 0f;
private float currentY = 20f;
Vector3 lastLookTarget;
private bool scopeMode;
public bool ScopeMode =\> scopeMode;
[SerializeField]
private GameObject crosshairUI;
[SerializeField]
private GameObject scopeUI;
private PlayerController playerController;
[SerializeField]
private LayerMask layerMask;
[SerializeField]
private LayerMask playerLayerMask;
RaycastHit hit;
float distance;
Vector3 aimPoint;
private void Awake()
{
playerStats = GetComponent\
();
characterRagdollController = GetComponent\();
propBlock = new MaterialPropertyBlock();
TPCamera.fieldOfView = playerStats.baseFOV;
FPCamera.fieldOfView = FPFOV;
playerController = GetComponent\();
renderer = GetComponentsInChildren\();
color = new Color[renderer.Length];
for (int i = 0; i \< renderer.Length;  i++)
{
if (renderer[i].material.HasProperty(colorPropertyID))
{
color[i] = renderer[i].material.color;
}
else
{
color[i] = Color.white;
}
}
TPCamera.depth = 1;
FPCamera.depth = 0;
scopeUI.SetActive(false);
enabledCamera = TPCamera;
}
void LateUpdate()
{
if (Input.GetMouseButtonDown(1))
{
EnterScopeMode();
}
if (Input.GetMouseButtonUp(1))
{
ExitScopeMode();
}
HandleCameraRotation();
HandleCameraRigPosition();
if (!scopeMode)
{
UpdateThirdPersonCameraPosition();
}
UpdateTPFOV();
}
private void EnterScopeMode()
{
lastLookTarget = GetAimPoint();
scopeMode = true;
scopeUI.SetActive(true);
crosshairUI.SetActive(false);
HandleFirstPersonCamera();
Vector3 direction = (lastLookTarget - CameraRig.position).normalized;
currentX = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
currentY = -Mathf.Asin(direction.y) * Mathf.Rad2Deg;
CameraRig.rotation = Quaternion.Euler(currentY, currentX, 0f);
TPCamera.depth = 0;
FPCamera.depth = 1;
enabledCamera = FPCamera;
SetPlayerRenderers(false);
}
private void ExitScopeMode()
{
lastLookTarget = GetAimPoint();
scopeMode = false;
scopeUI.SetActive(false);
crosshairUI.SetActive(true);
CorrectAimAfterFPtoTP();
TPCamera.depth = 1;
FPCamera.depth = 0;
enabledCamera = TPCamera;
SetPlayerRenderers(true);
}
private void HandleCameraRotation()
{
currentX += Input.GetAxis("Mouse X") * sensitivity;
currentY -= Input.GetAxis("Mouse Y") * sensitivity;
currentY = Mathf.Clamp(currentY, minYAngle, maxYAngle);
CameraRig.rotation = Quaternion.Euler(currentY, currentX, 0f);
}
private void HandleFirstPersonCamera()
{
CameraRig.position = transform.position + FPOffset;
}
private void HandleCameraRigPosition()
{
if (scopeMode)
{
CameraRig.position = transform.position + FPOffset;
}
else if (playerController.DevMode)
{
CameraRig.position = target.position;
}
else
{
distance = (target.position - CameraRig.position).magnitude;
CameraRig.position = Vector3.MoveTowards(CameraRig.position, target.position, cameraPositionSmoothSpeed * Time.deltaTime * distance);
}
}
private void UpdateThirdPersonCameraPosition()
{
Vector3 desiredTPCamPosX = CameraRig.position + Quaternion.Euler(0, currentX, 0) * new Vector3(TPOffset.x + math.sign(TPOffset.x) * cameraCollisionBuffer, 0, 0);
if (Physics.Raycast(CameraRig.position, (desiredTPCamPosX - CameraRig.position).normalized, out hit, (desiredTPCamPosX - CameraRig.position).magnitude, layerMask))
{
desiredTPCamPosX = hit.point - (desiredTPCamPosX - CameraRig.position).normalized * cameraCollisionBuffer;
}
else
{
desiredTPCamPosX -= (desiredTPCamPosX - CameraRig.position).normalized * cameraCollisionBuffer;
}
Vector3 desiredTPCamPosXY = desiredTPCamPosX + Quaternion.Euler(0, currentX, 0) * new Vector3(0, TPOffset.y + math.sign(TPOffset.y) * cameraCollisionBuffer, 0);
if (Physics.Raycast(desiredTPCamPosX, (desiredTPCamPosXY - desiredTPCamPosX).normalized, out hit, (desiredTPCamPosXY - desiredTPCamPosX).magnitude, layerMask))
{
desiredTPCamPosXY = hit.point - (desiredTPCamPosXY - desiredTPCamPosX).normalized * cameraCollisionBuffer;
}
else
{
desiredTPCamPosXY -= (desiredTPCamPosXY - desiredTPCamPosX).normalized * cameraCollisionBuffer;
}
Vector3 desiredTPCamPosXYZ = desiredTPCamPosXY + Quaternion.Euler(currentY, currentX, 0) * new Vector3(0, 0, TPOffset.z + math.sign(TPOffset.z) * cameraCollisionBuffer);
if (Physics.Raycast(desiredTPCamPosXY, (desiredTPCamPosXYZ - desiredTPCamPosXY).normalized, out hit, (desiredTPCamPosXYZ - desiredTPCamPosXY).magnitude,  layerMask))
{
desiredTPCamPosXYZ = hit.point - (desiredTPCamPosXYZ - desiredTPCamPosXY).normalized * cameraCollisionBuffer;
}
else
{
desiredTPCamPosXYZ -= (desiredTPCamPosXYZ - desiredTPCamPosXY).normalized * cameraCollisionBuffer;
}
TPCamera.transform.position = desiredTPCamPosXYZ;
}
private void SetPlayerRenderers(bool isEnabled)
{
for (int i = 0; i \< renderer.Length; i++)
{
renderer[i].enabled = isEnabled;
}
}
private float NormalizeAngle(float angle)
{
if (angle \> 180) angle -= 360f;
return angle;
}
public Vector3 GetAimPoint()
{
if (Physics.Raycast(enabledCamera.transform.position, enabledCamera.transform.forward, out hit, 1000, layerMask))
{
return hit.point;
}
else
{
return enabledCamera.transform.position + enabledCamera.transform.forward * 1000f;
}
}
private void CorrectAimAfterFPtoTP()
{
HandleCameraRigPosition();
for (int i = 0; i \< 10; i++)
{
UpdateThirdPersonCameraPosition();
Vector3 currentCameraDirection = TPCamera.transform.rotation * Vector3.forward;
Vector3 directionToTarget = (lastLookTarget - TPCamera.transform.position).normalized;
Quaternion errorRotation = Quaternion.FromToRotation(currentCameraDirection, directionToTarget);
CameraRig.rotation = errorRotation * CameraRig.rotation;
Vector3 direction = CameraRig.rotation * Vector3.forward;
currentX = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
currentY = -Mathf.Asin(direction.y) * Mathf.Rad2Deg;
}
}
public void UpdateTPFOV()
{
if (playerStats.currentFOV != TPCamera.fieldOfView)
{
TPCamera.fieldOfView = Mathf.Lerp(TPCamera.fieldOfView, playerStats.currentFOV, FOVChangeSpeed * Time.deltaTime);
if (Mathf.Abs(playerStats.currentFOV - TPCamera.fieldOfView) \< 0.1f)
{
TPCamera.fieldOfView = playerStats.currentFOV;
}
}
}
}
Когда я перемещаю персонажа в режиме от первого лица (прицел), а затем переключаюсь обратно на вид от третьего лица, CameraRig фиксируется в странном положении далеко от персонажа. В результате коррекция прицеливания также не работает должным образом. Если персонаж стоит на месте, переключение между видом от первого и третьего лица работает совершенно нормально.


Подробнее здесь: https://stackoverflow.com/questions/798 ... n-to-third
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»