C# &引用;“接地”;变量不';在Unity中初始跳跃后,t更改为false
概述 使用Unity2D 2019.3.5,我正在使用C#制作一个platformer游戏。我实现了raycast来检测我的玩家何时触地,并试图使它只允许玩家跳一次 问题 虽然我认为我已经将角色编程为跳跃一次,但是在第一次跳跃之后,Unity引擎仍然会对我的“isGrounded”变量显示一个复选标记,并且只有在第二次跳跃之后,在触地之前才会变为false(未选中) 我的代码C# &引用;“接地”;变量不';在Unity中初始跳跃后,t更改为false,c#,unity3d,raycasting,C#,Unity3d,Raycasting,概述 使用Unity2D 2019.3.5,我正在使用C#制作一个platformer游戏。我实现了raycast来检测我的玩家何时触地,并试图使它只允许玩家跳一次 问题 虽然我认为我已经将角色编程为跳跃一次,但是在第一次跳跃之后,Unity引擎仍然会对我的“isGrounded”变量显示一个复选标记,并且只有在第二次跳跃之后,在触地之前才会变为false(未选中) 我的代码 using System.Collections; using System.Collections.Generic;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Controller : MonoBehaviour
{
public int playerSpeed = 10;
public int playerJumpPower = 1250;
private float moveX;
public bool isGrounded;
public float distanceToBottomOfPlayer = .7f;
// Update is called once per frame
void Update()
{
PlayerMove();
PlayerRaycast();
}
void PlayerMove()
{
// CONTROLS
moveX = Input.GetAxis("Horizontal");
if (Input.GetButtonDown("Jump") && isGrounded == true)
{
Jump();
}
// ANIMATIONS
// PLAYER DIRECTION
if (moveX < 0.0f)
{
GetComponent<SpriteRenderer>().flipX = true;
}
else if (moveX > 0.0f)
{
GetComponent<SpriteRenderer>().flipX = false;
}
// PHYSICS
gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(moveX * playerSpeed,
gameObject.GetComponent<Rigidbody2D>().velocity.y);
}
void Jump()
{
GetComponent<Rigidbody2D>().AddForce(Vector2.up * playerJumpPower);
isGrounded = false;
}
void PlayerRaycast()
{
// Ray Down
RaycastHit2D rayDown = Physics2D.Raycast(transform.position, Vector2.down);
if (rayDown.collider != null && rayDown.distance < distanceToBottomOfPlayer &&
rayDown.collider.tag == "ground")
{
isGrounded = true;
}
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类玩家\控制器:单行为
{
公共int播放器速度=10;
公共int-playerJumpPower=1250;
私人浮动moveX;
公共学校停课;
公共浮动距离到Bottomofplayer=.7f;
//每帧调用一次更新
无效更新()
{
PlayerMove();
PlayerRaycast();
}
void PlayerMove()
{
//控制
moveX=Input.GetAxis(“水平”);
if(Input.GetButtonDown(“Jump”)&&isground==true)
{
跳跃();
}
//动画
//球员方向
如果(移动X<0.0f)
{
GetComponent().flipX=true;
}
否则如果(移动X>0.0f)
{
GetComponent().flipX=false;
}
//物理学
gameObject.GetComponent().velocity=新矢量2(moveX*玩家速度,
gameObject.GetComponent().velocity.y);
}
无效跳转()
{
GetComponent().AddForce(Vector2.up*playerJumpPower);
isfounded=false;
}
void PlayerRaycast()
{
//扫射
RaycastHit2D rayDown=Physics2D.Raycast(transform.position,Vector2.down);
if(rayDown.collider!=null&&rayDown.distance
额外信息
我确实需要在“编辑>项目设置>物理2D>在碰撞器中开始查询”中更改Unity设置。为了让我的播放器使用我上面写的代码跳转,我不得不关闭这个设置(取消选中)。我知道还有其他方法可以让我的播放器跳转,但是,在保持代码可读性的同时,这似乎是最有效的方法
尝试过的解决方案
我认为问题在于我有一个raycast问题,我不知道如何解决。我查看了其他堆栈溢出帖子,包括写这篇帖子后推荐的帖子,但没有一篇适用于我的问题
最终注释
正如我之前所说的,我知道还有其他方法可以让我的玩家使用不同的代码只跳转一次,但是,为了我自己的学习目的和将来的参考,我想继续使用这些代码。因为当你调用
跳转()
时,你不能确定是否是假
我认为问题就在那里。
调用Jump()
时,请尝试不设置isground
标志。设置isground
纯粹是PlayerRaycast()
的工作
void Update()
{
// Raycast before moving
PlayerRaycast();
PlayerMove();
}
void PlayerRaycast()
{
// Ray Down
RaycastHit2D rayDown = Physics2D.Raycast(transform.position, Vector2.down);
if (rayDown.collider != null && rayDown.collider.tag == "ground")
{
if( rayDown.distance < distanceToBottomOfPlayer )
{
isGrounded = true;
}
else
{
isGrounded = false;
}
}
}
void Jump()
{
GetComponent<Rigidbody2D>().AddForce(Vector2.up * playerJumpPower);
//isGrounded = false;
}
void Update()
{
//移动前的光线投射
PlayerRaycast();
PlayerMove();
}
void PlayerRaycast()
{
//扫射
RaycastHit2D rayDown=Physics2D.Raycast(transform.position,Vector2.down);
if(rayDown.collider!=null&&rayDown.collider.tag==“地面”)
{
if(rayDown.distance
第一个问题是,在同一帧上添加力并检查地面
在FixedUpdate中或通过显式调用
物理模拟法
因此,按下“跳跃”按钮后,对象仍在地面上,直到下一帧出现
要解决此问题,只需交换“移动”和“光线投射”的顺序
第二个问题是,如果跳跃功率不够大,则在下一帧中对象仍可能接近地面,应避免在跳跃处于上升状态时检查着陆
void PlayerRaycast()
{
if(GetComponent<Rigidbody2D>().velocity.y > 0)
return;
...
}
void PlayerRaycast()
{
如果(GetComponent().velocity.y>0)
返回;
...
}
我喜欢看这样的问题,很少有资格回答。我想说的是,从局外人的角度来看,表达式rayDown.distance
似乎容易出现问题,特别是因为我们处理的是浮动。此外,在我看来,isGrounded
的状态应该始终基于“物理”条件。投票给有趣且结构良好的人。
void PlayerRaycast()
{
if(GetComponent<Rigidbody2D>().velocity.y > 0)
return;
...
}