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();
}
}
}
私の最近の試みは、ジャンプ-rigidbody.velocity.magnitude * 50を試して、ボールが移動する速度によってジャンプ力を減らすことでした。ボールの速度が速度と同等であると思われる速度に達したときに、ジャンプ力を比例的にゼロまで下げることで、バウンス+ジャンプの問題をほぼ解決しました。それは停止状態から機能しましたが、問題は、ボールが接地している間の大きさも考慮しているため、ボールがフルスピードで回転してジャンプするのを妨げています。私は近くにいましたが、そこにはまったくありませんでした!
私は初心者プログラマーであり、私はここで困惑しています。この問題の独創的な解決策を見つけるのを手伝ってくれる人はいますか?プレイヤーが継続的に跳ね返り、より高くジャンプできる限り、すべてのレベルを設計することはできません。すべてのレベルをだますことができるからです。先に進みたいと思います-この問題は長い間私を抑えてきましたので、アドバイスをいただければ幸いです!