如何在 C# 中重复一个动作来修复跳跃机制
How do I repeat an action in c# to fix the jumping mechanism
我正在创建一个基本的 2D 平台游戏,但是跳跃机制只会 运行 一次,然后直接着陆。我该如何循环播放?
我尝试了检测碰撞(来自标签:Terrain),这确实有很大帮助,但它仍然无法正常工作。
这是我的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController2D : MonoBehaviour
{
private Rigidbody2D rb2D;
private Vector2 velocity;
Vector2 xvelocity = new Vector2(10, 0);
Vector2 yvelocity = new Vector2(0, 10);
public float jumptime;
bool grounded = true;
bool jump = false;
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetButton("Jump"))
{
jump = true;
}
}
private void FixedUpdate()
{
//Debug.Log(Input.GetAxisRaw("Vertical"));
if (left == true)
{
//Debug.Log("Left");
rb2D.MovePosition(rb2D.position + -xvelocity * Time.fixedDeltaTime);
}
if (right == true)
{
//Debug.Log("Right");
rb2D.MovePosition(rb2D.position + xvelocity * Time.fixedDeltaTime);
}
//if (jump == true && grounded == true)
//{
// jumptime -= Time.fixedDeltaTime;
// if (jumptime > 0)
// {
// rb2D.MovePosition(rb2D.position + yvelocity * Time.fixedDeltaTime);
// }
// if (jumptime <= 0)
// {
// jump = false;
// jumptime = 2;
// }
if (jump == true && grounded == true && jumptime > 0)
{
jumptime -= Time.fixedDeltaTime;
rb2D.MovePosition(rb2D.position + yvelocity * Time.fixedDeltaTime);
} else if (jumptime <= 0)
{
jump = false;
jumptime = 2f;
}
//if (Time.fixedDeltaTime >= 2)
//{
// jump = false;
// rb2D.MovePosition(rb2D.position + -yvelocity * Time.fixedDeltaTime);
//}
}
void OnCollisionExit2D(Collision2D other)
{
Debug.Log("No longer in contact with " + other.transform.name);
jump = true;
grounded = false;
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Terrain")
{
Debug.Log("Landed");
jump = false;
grounded = true;
}
}
}
预期的结果是动作 'jump' 将以良好的高度(vector2 yvelocity)循环约 1/1.5 秒,因此它会跳得更高,然后会下降(由于重力来自刚体 (2D))
如评论中所述,我认为主要问题来自这行代码。
if (jump == true && grounded == true && jumptime > 0)
很可能其中一个布尔值不是您期望的那样。无论如何,我建议你像这样转换行:
if (jump && grounded && jumptime > 0)
布尔值不需要 == true。
无论如何,为了以更简单的方式解决您的问题,我建议您使用 AddForce 而不是移动(因为您正在使用 rigibody2d)。
rb2D.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
关于水平速度的小笔记。如果您使用的是刚体,最好使用相同的刚体而不是变换来移动它:
rb2D.MovePosition(rb2D.position + Vector2.left * xspeed * Time.fixedDeltaTime);
您的代码将变为:
public class PlayerController2D : MonoBehaviour
{
private Rigidbody2D rb2D;
private Vector2 velocity;
public float jumpForce = 5;
bool grounded = true;
void Start() { rb2D = GetComponent<Rigidbody2D>(); }
void Update()
{
if (Input.GetButton("Jump") && grounded)
rb2D.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
//calculate horizontal speed here
xspeed = ...;
}
private void FixedUpdate()
{
rb2D.MovePosition(rb2D.position + Vector2.left * xspeed * Time.fixedDeltaTime);
}
void OnCollisionExit2D(Collision2D other)
{
Debug.Log("No longer in contact with " + other.transform.name);
grounded = false;
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Terrain")
{
Debug.Log("Landed");
grounded = true;
}
}
}
我正在创建一个基本的 2D 平台游戏,但是跳跃机制只会 运行 一次,然后直接着陆。我该如何循环播放?
我尝试了检测碰撞(来自标签:Terrain),这确实有很大帮助,但它仍然无法正常工作。
这是我的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController2D : MonoBehaviour
{
private Rigidbody2D rb2D;
private Vector2 velocity;
Vector2 xvelocity = new Vector2(10, 0);
Vector2 yvelocity = new Vector2(0, 10);
public float jumptime;
bool grounded = true;
bool jump = false;
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetButton("Jump"))
{
jump = true;
}
}
private void FixedUpdate()
{
//Debug.Log(Input.GetAxisRaw("Vertical"));
if (left == true)
{
//Debug.Log("Left");
rb2D.MovePosition(rb2D.position + -xvelocity * Time.fixedDeltaTime);
}
if (right == true)
{
//Debug.Log("Right");
rb2D.MovePosition(rb2D.position + xvelocity * Time.fixedDeltaTime);
}
//if (jump == true && grounded == true)
//{
// jumptime -= Time.fixedDeltaTime;
// if (jumptime > 0)
// {
// rb2D.MovePosition(rb2D.position + yvelocity * Time.fixedDeltaTime);
// }
// if (jumptime <= 0)
// {
// jump = false;
// jumptime = 2;
// }
if (jump == true && grounded == true && jumptime > 0)
{
jumptime -= Time.fixedDeltaTime;
rb2D.MovePosition(rb2D.position + yvelocity * Time.fixedDeltaTime);
} else if (jumptime <= 0)
{
jump = false;
jumptime = 2f;
}
//if (Time.fixedDeltaTime >= 2)
//{
// jump = false;
// rb2D.MovePosition(rb2D.position + -yvelocity * Time.fixedDeltaTime);
//}
}
void OnCollisionExit2D(Collision2D other)
{
Debug.Log("No longer in contact with " + other.transform.name);
jump = true;
grounded = false;
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Terrain")
{
Debug.Log("Landed");
jump = false;
grounded = true;
}
}
}
预期的结果是动作 'jump' 将以良好的高度(vector2 yvelocity)循环约 1/1.5 秒,因此它会跳得更高,然后会下降(由于重力来自刚体 (2D))
如评论中所述,我认为主要问题来自这行代码。
if (jump == true && grounded == true && jumptime > 0)
很可能其中一个布尔值不是您期望的那样。无论如何,我建议你像这样转换行:
if (jump && grounded && jumptime > 0)
布尔值不需要 == true。
无论如何,为了以更简单的方式解决您的问题,我建议您使用 AddForce 而不是移动(因为您正在使用 rigibody2d)。
rb2D.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
关于水平速度的小笔记。如果您使用的是刚体,最好使用相同的刚体而不是变换来移动它:
rb2D.MovePosition(rb2D.position + Vector2.left * xspeed * Time.fixedDeltaTime);
您的代码将变为:
public class PlayerController2D : MonoBehaviour
{
private Rigidbody2D rb2D;
private Vector2 velocity;
public float jumpForce = 5;
bool grounded = true;
void Start() { rb2D = GetComponent<Rigidbody2D>(); }
void Update()
{
if (Input.GetButton("Jump") && grounded)
rb2D.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
//calculate horizontal speed here
xspeed = ...;
}
private void FixedUpdate()
{
rb2D.MovePosition(rb2D.position + Vector2.left * xspeed * Time.fixedDeltaTime);
}
void OnCollisionExit2D(Collision2D other)
{
Debug.Log("No longer in contact with " + other.transform.name);
grounded = false;
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Terrain")
{
Debug.Log("Landed");
grounded = true;
}
}
}