【问题标题】:Points on collision (points only working for first platform)碰撞点(点仅适用于第一个平台)
【发布时间】:2018-09-15 02:23:40
【问题描述】:

我正在尝试在 Unity 上进行涂鸦跳跃,不同之处在于,当我降落在平台上时,会增加 10 分。但是,这仅适用于第一个平台。我从 0 开始,当我进入第一个平台时,我得到 10 分,但它停在那里。

我的代码有什么问题,为什么其他平台不会继续发生这种情况?

public class PlatformScript : MonoBehaviour {

    public int currentScore;
    public Text displayScore;

    public float jumpForce = 10f; 

    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.relativeVelocity.y <= 0) {

            Rigidbody2D rb = collision.collider.GetComponent<Rigidbody2D> ();

            if (rb != null) {
                Vector2 velocity = rb.velocity;
                velocity.y = jumpForce; 
                rb.velocity = velocity;
            }

            Destroy (gameObject);
            currentScore += 10;                
            Update ();
        }
    }

    void Update()
    {
        displayScore.text = "Score: " + currentScore;
    }
}

另外,这是我的关卡生成页面。平台随机生成:

public class LevelGenerator : MonoBehaviour {

public GameObject platformPrefab;

public int numberOfPlatforms = 200;
public float levelWidth = 3f;
public float minY = 1f; 
public float maxY = 3.2f;


void Start () {
    Vector3 spawnPosition = new Vector3 ();
    for (int i = 0; i < numberOfPlatforms; i++) 
    {
        spawnPosition.y += Random.Range (minY, maxY);
        spawnPosition.x = Random.Range (-levelWidth, levelWidth); 
        Instantiate (platformPrefab, spawnPosition, Quaternion.identity); 
    }
  }
}

您可能已经注意到,我对 Unity 非常陌生。

【问题讨论】:

  • 不要手动调用Update函数。此函数由 Unity 自动调用。
  • 现在它完全不起作用了..点仍然保持在 0
  • 你已经在当前脚本中声明了currentScore,我很确定脚本是它所附加的每个游戏对象的一个​​实例,所以你基本上有很多@987654325的实例@ 那都是零。当您击中平台时,您添加 10,然后销毁平台。这意味着您只能获得 10 的得分值。我不知道统一,所以这可能不准确

标签: c# unity3d collision


【解决方案1】:

但这仅适用于第一个平台。我从0开始 当我在第一个平台上时,我得到 10 分,但它停在那里。

那是因为你正在用Destroy (gameObject); 销毁它(你的PlatformScript 脚本附加到的游戏对象)。

如果PlatformScript 脚本附加到平台并且您的目标是销毁其他游戏对象,则使用Destroy(collision.gameObject); 而不是Destroy (gameObject);

最后,不要手动调用Update 函数。此函数由 Unity 自动调用。此外,最好在修改currentScore 时更新displayScore 文本,而不是更新Update 函数中的每一帧。


如果这不起作用,请使用 Debug.Log 验证是否正在调用 OnCollisionEnter2D。还可以使用它来验证 if (collision.relativeVelocity.y &lt;= 0) 甚至评估为 true。如果这两个中的任何一个是false,那么您的分数将不会更新。请参阅下面的固定 OnCollisionEnter2D 函数。用它来调试你的代码。

您的新代码:

void OnCollisionEnter2D(Collision2D collision)
{
    Debug.Log("Collision detected!");

    if (collision.relativeVelocity.y <= 0)
    {
        Debug.Log("RelativeVelocity <=0");
        Rigidbody2D rb = collision.collider.GetComponent<Rigidbody2D>();
        if (rb != null)
        {
            Vector2 velocity = rb.velocity;
            velocity.y = jumpForce;
            rb.velocity = velocity;
        }
        Destroy(collision.gameObject);

        currentScore += 10;
        displayScore.text = "Score: " + currentScore;
    }
}

【讨论】:

  • 我尝试了你刚才所说的一切,但都没有奏效。
  • 使用 Destroy(collision.gameObject),它甚至不会让玩家跳跃,因为关卡每次都会重新加载,而且这种情况会反复发生。我还尝试删除 Destroy(gameObject) 并且这些点也不起作用。它们只是从 0 上升到 10 并且保持不变。基本上和以前一样的问题。我不认为破坏是问题
【解决方案2】:

你正在破坏保存分数的平台。将数据保存在可全局访问(在平台之间共享)的对象中,例如 LevelGenerator。稍加洗牌,它看起来像这样(static 用于简单);

public class PlatformScript : MonoBehaviour
{
    public float jumpForce = 10f;

    void OnCollisionEnter2D (Collision2D collision)
    {
        if (collision.relativeVelocity.y <= 0)
        {
            Rigidbody2D rb = collision.collider.GetComponent<Rigidbody2D>();

            if (rb != null)
            {
                Vector2 velocity = rb.velocity;
                velocity.y = jumpForce;
                rb.velocity = velocity;
            }

            // update our global score
            LevelGenerator.currentScore += 10;
            Destroy(gameObject);
        }
    }
}

public class LevelGenerator : MonoBehaviour
{
    // global persistent data
    public static int currentScore;

    public Text displayScore;
    public GameObject platformPrefab;

    public int numberOfPlatforms = 200;
    public float levelWidth = 3f;
    public float minY = 1f;
    public float maxY = 3.2f;

    void Start ()
    {
        Vector3 spawnPosition = new Vector3();
        for (int i = 0; i < numberOfPlatforms; i++)
        {
            spawnPosition.y += Random.Range(minY, maxY);
            spawnPosition.x = Random.Range(-levelWidth, levelWidth);
            Instantiate(platformPrefab, spawnPosition, Quaternion.identity);
        }
    }

    void Update ()
    {
        displayScore.text = "Score: " + currentScore;
    }
}

【讨论】:

  • 天哪,它现在起作用了!!!!!! (我忘了保存LOL)!谢谢乐乐!!!!!!!
  • 谢谢谢谢谢谢 :D 现在我只需要在他死时将其重置为 0 :D 不过不要认为这太难了 :D
  • 太棒了,不客气!他死后就做LevelGenerator.currentScore = 0;
  • 如果您的问题已经解决,您可以接受Lece的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多