我正在Unity3D中构建一个相当简单的大理石赛车游戏。球是仅在X和Y轴上移动的3D物理对象。它具有左右滚动和跳跃的能力。非常基本的东西,除了我遇到了打破比赛的问题:当摔倒并撞击地面时,球的反弹幅度可以与其弹跳力相结合,从而产生超高跳跃。这意味着,通过适当地按下按钮,玩家可以使球反弹得更高,达到意想不到的高度。在解决此故障之前,我无法正确设计关卡。我已经说明了这个示例:
但是,跳跃并不像直接将球向上射击那样简单。为了简化关卡设计中的复杂性,我将跳跃角度编程为相对于球在其上滚动的表面。
图3是该游戏到目前为止的工作方式;没有图4。这使解决弹跳问题变得更具挑战性,因为我不能简单地测量和设置Y轴上的精确力或速度。这样做会导致怪异的行为,当球在陡峭的斜坡上行驶时,这种行为会变得更加明显。
到目前为止,我已经能够构思出该游戏中所有其他设计问题的解决方案,然后找到如何对它们进行编程的方法,但是这使我陷入了困境。我尝试了许多不同的方法,但是没有一个起作用。
这是控制球跳动的C#脚本:
using UnityEngine;
using System.Collections;
public class BallJumping : MonoBehaviour {
public System.Action onJump;
public Rigidbody objRigidbody; // Set this to the player
public bool isGrounded; // Determines whether or not the ball is on the ground
public Transform groundChecker; // A child object that's slightly larger than the ball
public float groundRadius = 0.6f;
public LayerMask whatIsGround; // Determines what layers qualify as ground
public AudioClip jumpSFX;
public AudioClip stickyJumpSFX;
private float p_WillJumpTimeRemaining; // Grace periods before/after hitting the ground to trigger jump
private float p_CanJumpTimeRemaining;
public float earlyJumpToleranceDuration = 0.2f;
public float lateJumpToleranceDuration = 0.2f;
public float jump = 500f; // Jumping power
private float halfJump = 250f; // Used for the sticky puddles
public bool stuck = false; // Used for sticky materials
private float contactX;
private float contactY;
// Input for jumping
void Update () {
if (Input.GetButtonDown ("Jump") && isGrounded == true) {
ProcessJump();
}
}
// Continuously checks whether or not the ball is on the ground
void FixedUpdate () {
if (Physics.CheckSphere (groundChecker.position, groundRadius, whatIsGround) == true) {
isGrounded = true;
} else {
isGrounded = false;
}
}
// Sets a grace period for before or after the ball contacts the ground for jumping input
void ProcessJump () {
bool boolGetJump = Input.GetButtonDown("Jump");
if (boolGetJump && isGrounded == false) {
p_WillJumpTimeRemaining = earlyJumpToleranceDuration;
} else {
if (p_WillJumpTimeRemaining > 0) {
p_WillJumpTimeRemaining -= Time.fixedDeltaTime;
}
}
if (isGrounded) {
p_CanJumpTimeRemaining = lateJumpToleranceDuration;
}
if (isGrounded || p_WillJumpTimeRemaining > 0) {
Jump();
}
if (p_CanJumpTimeRemaining > 0) {
p_CanJumpTimeRemaining -= Time.fixedDeltaTime;
}
}
// Sticky puddles script -- hinders jumping while in the puddle
void OnTriggerEnter (Collider collision) {
if (collision.gameObject.tag == "Sticky") {
stuck = true;
}
}
void OnTriggerExit (Collider collision) {
if (collision.gameObject.tag == "Sticky") {
stuck = false;
}
}
// Calculates the normals for the jump angle
void OnCollisionStay (Collision collision) {
Debug.Log ("Collision.");
foreach (ContactPoint contact in collision.contacts) {
contactX = contact.normal.x;
contactY = contact.normal.y;
}
}
// Controls jumping
void Jump() {
Debug.Log ("Jump.");
p_WillJumpTimeRemaining = 0.0f;
p_CanJumpTimeRemaining = 0.0f;
halfJump = jump * 0.5f; // Cuts jumping force in half while in a sticky puddle
GetComponent<AudioSource>().volume = 1;
GetComponent<AudioSource>().pitch = Random.Range (0.9f, 1.1f);
if (stuck == false) {
objRigidbody.AddForce (contactX * jump, contactY * jump, 0);
GetComponent<AudioSource>().clip = jumpSFX;
GetComponent<AudioSource>().Play ();
}
else if (stuck == true) {
objRigidbody.AddForce (contactX * halfJump, contactY * halfJump, 0);
GetComponent<AudioSource>().clip = stickyJumpSFX;
GetComponent<AudioSource>().Play ();
}
if (onJump != null) {
onJump();
}
}
}
我最近的尝试是尝试跳跃-刚体。速度。幅度* 50,以通过球的行进速度降低跳跃力。当球的速度达到看上去与速度,幅度相等时,通过将跳跃力成比例地减小到零,它几乎解决了弹跳+跳跃问题。它从静止状态开始工作,但问题是,它还考虑了球着地时的大小,从而阻止了球全速滚动和跳跃。我离那儿很近,但还不在那里!
我是新手程序员,在这里很困惑。谁能帮助我找到解决这个问题的创造性方法?只要玩家能够不断弹跳并跳得更高,我就无法设计任何关卡,因为它们只会被欺骗。我很乐意继续前进-这个问题困扰了我很长时间,因此,我非常感谢您提供一些建议!