Итак, я работаю над многопользовательской онлайн-игрой FPS для школьного проекта. Я запрограммировал скрипт перемещения локально, а затем переместил его в свою реализацию фотонов, где экземпляр игрока создается с использованием PhotonNetwork.Instantiate.
У меня есть локальная версия проигрывателя с почти таким же сценарием, только за вычетом требуемого сетевой код и минус просмотр фотонов и син c компонентов. Эта версия работает все время, в редакторе и при сборке.
Проблема в том, что движение будет работать нормально, когда я подключаюсь к фотонной комнате, запущенной из редактора, но когда я пытаюсь собрать игру, не работает Я попытался обменяться между главным и подчиненным клиентами, но, несмотря ни на что, автономная сборка не работает. Проблема в том, что когда я пытаюсь двигаться, ничего не происходит. Я могу прыгать, и иногда это позволяет мне двигаться, когда я нахожусь в воздухе, а затем, когда я приземляюсь, я могу продолжать двигаться, пока удерживаю клавишу нажатой. Я пытался использовать другую карту, и когда я заменил свою построенную карту просто плоскостью, я вообще не мог двигаться.
На моем плеере у меня есть контроллер персонажа, вид фотонов, вид фотонного преобразования и фотонный аниматор. У меня также есть другой сценарий transform syn c, который я пробовал, без изменений.
Я просто не знаю, что попробовать, или с чем проблема связана, поскольку я не получаю ошибок в своем журнале output.
EDIT Мне удалось исправить это, ограничив частоту кадров. Моя игра работала на 4k кадрах, и это, очевидно, не понравилось. Надеюсь, что это поможет любому с той же проблемой.
Код движения
using Photon.Pun;
using UnityEngine;
using UnityEngine.UI;
public class Movement : MonoBehaviourPun
{
[Header("Movement Settings")]
public float maxVelocityGround = 15f;
public float maxVelocityAir = 10f;
public float groundAccelerate = 90f;
public float airAccelerate = 180f;
public float fallMultiplier = 1.2f;
public float lookSens = 8f;
public float slowDrag = 0;
public float thrusterForce = 7f;
public float friction = 10f;
private float _friction = 0f;
public float input_x;
public float input_y;
[Header("Rotation")]
float xRot = 0F;
float yRot = 0F;
float minY = -90f;
float maxY = 90f;
Quaternion originalRotation;
//More Movement Variables
private float distToGround;
private Vector3 _velocity;
private Vector2 xyVelocity;
[Header("References")]
//public Text grounded;
public Camera cam;
private Camera cam2;
private CharacterController controller;
private Animator animator;
//Booleans
private bool jump = false;
public float jumpPressDuration = 0.1f;
private float ySpeed;
private float gravity = 9.81f;
private float animSpeed;
public Transform headLock;
public Transform head;
public Vector3 headOffset;
void Start()
{
cam2 = this.GetComponentInChildren<Camera>();
if (!photonView.IsMine)
{
cam2.enabled = false;
cam.enabled = false;
Debug.Log(photonView.IsMine);
//listener.enabled = false;
}
_friction = friction;
//Locks the cursor to the middle of the screen, and hides it from view
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
//These attatch the correct objects to their references in the script, defined above
controller = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
//Sets the distance to the ground from the center of the collider, used in determining whe nthe player is on the ground
distToGround = controller.bounds.extents.y;
originalRotation = transform.localRotation;
}
private void Update()
{
if (photonView.IsMine)
{
xyVelocity = new Vector2(controller.velocity.x, controller.velocity.z);
//velocity.GetComponent<Text>().text = xyVelocity.magnitude.ToString("0.000");
//Stuff for animations
animSpeed = xyVelocity.magnitude / (maxVelocityGround - 1);
animator.SetFloat("Move", animSpeed);
cameraRotate();
rbRotate();
CheckJump();
float input_y = Input.GetAxis("Vertical");
float input_x = Input.GetAxis("Horizontal");
Vector3 accelDir = (transform.forward * input_y + transform.right * input_x).normalized;
decelerate(accelDir);
RaycastHit hit;
Physics.Raycast(controller.center, Vector3.down, out hit, 1000);
accelDir = Vector3.ProjectOnPlane(accelDir, hit.normal).normalized;
Vector3 curVel = controller.velocity;
if (controller.isGrounded)
{
_velocity = MoveGround(accelDir, curVel);
}
else
{
_velocity = MoveAir(accelDir, curVel);
}
if (jump && controller.isGrounded)
{
ySpeed = thrusterForce;
animator.SetFloat("Speed", 0f);
animator.SetBool("Squat", true);
}
ySpeed -= gravity * Time.deltaTime;
_velocity.y = ySpeed;
controller.Move(_velocity * Time.deltaTime);
}
}
private Vector3 MoveGround(Vector3 accelDir, Vector3 prevVelocity)
{
// Apply Friction
float speed = prevVelocity.magnitude;
if (speed != 0 && !jump) // To avoid divide by zero errors
{
float drop = speed * _friction * Time.fixedDeltaTime;
prevVelocity *= Mathf.Max(speed - drop, 0) / speed; // Scale the velocity based on friction.
}
return Accelerate(accelDir, prevVelocity, groundAccelerate, maxVelocityGround);
}
private Vector3 MoveAir(Vector3 accelDir, Vector3 prevVelocity)
{
return Accelerate(accelDir, prevVelocity, airAccelerate, maxVelocityAir);
}
private Vector3 Accelerate(Vector3 accelDir, Vector3 prevVelocity, float accelerate, float max_velocity)
{
float projVel = Vector3.Dot(prevVelocity, accelDir); // Vector projection of Current velocity onto accelDir.
float accelVel = accelerate * Time.fixedDeltaTime; // Accelerated velocity in direction of movment
// If necessary, truncate the accelerated velocity so the vector projection does not exceed max_velocity
if (projVel + accelVel > max_velocity)
{
accelVel = max_velocity - projVel;
};
return prevVelocity + accelDir * accelVel;
}
private void CheckJump()
{
if (Input.GetButtonDown("Jump"))
{
jump = true;
}
else if (Input.GetButtonUp("Jump"))
{
jump = false;
}
}
//Function to check if we are on the ground
public bool isGrounded()
{
return Physics.Raycast(controller.bounds.center, Vector3.down, distToGround+0.1f);
//Below is a capsule cast, it would be better to implement because it has a thickness
//return Physics.CheckCapsule(collider.bounds.center, new Vector3(collider.bounds.center.x, collider.bounds.min.y, collider.bounds.center.z), collider.radius * 0.9f);
}
/// <summary>
/// decelerates us faster when not moving
/// </summary>
/// <param name="input"></param>
public void decelerate(Vector3 input)
{
if (input == Vector3.zero)
{
_friction = 10f * friction;
}
else
{
_friction = friction;
}
}
/// <summary>
/// This function is the camera rotation function
/// </summary>
public void cameraRotate()
{
//Get the input from the mouse and multiply it by sensitivity so it can be adjusted from ingame
yRot += Input.GetAxis("Mouse Y") * lookSens;
//Clamp it so that we cant just keep spinning in the Y direction
yRot = clamp(yRot, minY, maxY);
//Calculate the quaternion using the amount of rotation found before. We use the negative mouse input as the amount
//of rotation, and then specify that we want this rotation to be around the x axis. It seems counter intuitive, but this is the way to do it
Quaternion yRotAngle = Quaternion.AngleAxis(-yRot, Vector3.right);
//Apply this rotation to the cameras transform
cam.transform.localRotation = originalRotation * yRotAngle;
}
/// <summary>
/// Basically the same as above, but we dont need to clamp it because we want to be able to forever spin to the left and right
/// </summary>
public void rbRotate()
{
xRot += Input.GetAxis("Mouse X") * lookSens;
Quaternion xRotAngle = Quaternion.AngleAxis(xRot, Vector3.up);
controller.transform.localRotation = originalRotation * xRotAngle;
}
/// <summary>
/// just clamps the angle we input between the next 2 floats
/// </summary>
/// <param name="angle">the float representation of the angle</param>
/// <param name="min">the min that the angle can be</param>
/// <param name="max">you got it by now right?></param>
/// <returns></returns>
private float clamp(float angle, float min, float max)
{
return Mathf.Clamp(angle, min, max);
}
}