制作了一款类似《地铁冲浪者》的游戏,但角色在车道移动时会结结巴巴/颤抖



我制作了一款类似《地铁冲浪者》的游戏。游戏在单位编辑器上运行良好,但当我将其导出到apk并在手机上玩时,当我左右移动时,角色会振动。我没有添加任何刚体,而是添加了一个角色控制器。

这是玩家的移动代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PLAYERLANEMOV : MonoBehaviour
{
public const float LANE_DISTANCE = 2.5f;
private const float TURN_SPEED = 0.5f;
//
private bool isRunning = false;
//animation 
private Animator anim;
// movement 
private CharacterController controller;
private float jumbForce = 10.0f;
private float gravity = 12.0f;
private float verticalVelocity;

private int desiredLane = 1; // 0=left , 1 = center ,2 = right 
//speed modifier
private float originalSpeed = 7.0f;
private float speed = 7.0f;
private float speedIncreaseLastTick;
private float speedIncreaseTime = 2.5f;
private float speedIncreaseAmount = 0.1f;
private void Start()
{
speed = originalSpeed;
controller = GetComponent<CharacterController>();
anim = GetComponent<Animator>();
}
private void LateUpdate()
{
if (!isRunning)
return;
if (Time.time - speedIncreaseLastTick > speedIncreaseTime)
{
speedIncreaseLastTick = Time.time;
speed += speedIncreaseAmount;
GameManager.Instance.UpdateModifier(speed - originalSpeed);
}

if (MobileInput.Instance.SwipeLeft)
MoveLane(false);
if (MobileInput.Instance.SwipeRight)
MoveLane(true);
Vector3 targetPosition = transform.position.z * Vector3.forward;
if (desiredLane == 0)
targetPosition += Vector3.left * LANE_DISTANCE;
else if (desiredLane == 2)
targetPosition += Vector3.right * LANE_DISTANCE;
Vector3 moveVector = Vector3.zero;
moveVector.x = (targetPosition - transform.position).normalized.x * speed;
bool isGrounded = IsGrounded();
anim.SetBool("Grounded", isGrounded);
//gravity
if (isGrounded)
{
verticalVelocity = 0f;

if (MobileInput.Instance.SwipeUp)
{
//jumb
anim.SetTrigger("Jump");
verticalVelocity = jumbForce;
}
else if (MobileInput.Instance.SwipeDown)
{
//slide
StartSliding();
Invoke("StopSliding", 1.0f);
}
}
else
{
verticalVelocity -= (gravity * Time.deltaTime);
//fast falling
if (MobileInput.Instance.SwipeDown)
{
verticalVelocity = -jumbForce;
}
}
moveVector.y = verticalVelocity;
moveVector.z = speed;
controller.Move(moveVector * Time.deltaTime);
//rotate to where he is going
// Vector3 dir = controller.velocity;
// if (dir != Vector3.zero)
// {
//      dir.y = 0;
//      transform.forward = Vector3.Lerp(transform.forward, dir, TURN_SPEED);
//  }
}
private void StartSliding()
{
anim.SetBool("Sliding", true);
controller.height /= 2;
controller.center = new Vector3(controller.center.x, controller.center.y / 2, controller.center.z);
}
private void StopSliding()
{
anim.SetBool("Sliding", false);
controller.height *= 2;
controller.center = new Vector3(controller.center.x, controller.center.y * 2, controller.center.z);
}
private void MoveLane(bool goingRight)
{
desiredLane += (goingRight) ? 1 : -1;
desiredLane = Mathf.Clamp(desiredLane, 0, 2);
}
bool IsGrounded()
{
Ray groundRay = new Ray(
new Vector3(
controller.bounds.center.x,
(controller.bounds.center.y - controller.bounds.extents.y) + 0.2f,
controller.bounds.center.z),
Vector3.down);
Debug.DrawRay(groundRay.origin, groundRay.direction, Color.cyan, 1.0f);
return Physics.Raycast(groundRay, 0.2f + 0.1f); ;
}
public void StartRunning()
{
isRunning = true;
anim.SetTrigger("StartRunning");
} 
private void Crash()
{
anim.SetTrigger("Death");
isRunning = false;
GameManager.Instance.OnDeath();
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
switch (hit.gameObject.tag)
{
case "Obstacle":
Crash();
break;
}
}

}

这是相机移动代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CAMERAFOLLO : MonoBehaviour
{
public Transform lookAt;// our charcter we are looking at 
public Vector3 offset = new Vector3( 3.0f, -3.0f);
public Vector3 rotation = new Vector3(35, 0, 0);
public bool IsMoving { set; get; }

private void LateUpdate()
{
if (!IsMoving)
return;
Vector3 desiredPosition = lookAt.position + offset;
// desiredPosition.x = 0;
transform.position = Vector3.Lerp(transform.position, desiredPosition,0.1f);
transform.rotation = Quaternion.Lerp(transform.rotation,Quaternion.Euler(rotation),Time.deltaTime);
}
}

CameraGameObject结结巴巴通常是由Update调用的不匹配引起的。

一般来说,你应该在LateUpdate中移动你的相机,并在FixedUpdate中执行与帧速率无关的事情,比如播放器的移动。

尝试在PLAYERLANEMOV类中将private void LateUpdate()更改为private void FixedUpdate()

不要忘记,当您使用不同的Update调用(如void Updatevoid FixedUpdate(时,您应该为每个调用使用正确的时间间隔,因为它们在调用之间使用不同的时间步长。对于void Update,它将是Time.deltaTime,对于void FixedUpdate,它将为Time.fixedDeltaTime

最新更新