Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# &引用;“接地”;变量不';在Unity中初始跳跃后,t更改为false_C#_Unity3d_Raycasting - Fatal编程技术网

C# &引用;“接地”;变量不';在Unity中初始跳跃后,t更改为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;

概述

使用Unity2D 2019.3.5,我正在使用C#制作一个platformer游戏。我实现了raycast来检测我的玩家何时触地,并试图使它只允许玩家跳一次

问题

虽然我认为我已经将角色编程为跳跃一次,但是在第一次跳跃之后,Unity引擎仍然会对我的“isGrounded”变量显示一个复选标记,并且只有在第二次跳跃之后,在触地之前才会变为false(未选中)

我的代码

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;
    ...
}