[英]teleport not working c# unity code (complete noob)
在拿起 4 个对象后,我试图让我的游戏对象角色在视频游戏中从一个位置移动到另一个位置。 它会传送,但一旦传送,它就会继续传送到指定位置。 我不知道如何阻止它,所以它让我可以自由地移动到新位置。 使它转到新位置的原因是if (scoreValue >= 4)
{winTextObject.SetActive(true);}。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerScript: MonoBehaviour {
private Rigidbody2D rd2d;
public float speed;
public Text scoreText;
private int scoreValue;
public GameObject winTextObject;
public GameObject loseTextObject;
private int lives;
public Text livesText;
// Start is called before the first frame update
void Start() {
rd2d = GetComponent < Rigidbody2D > ();
scoreValue = 0;
scoreText.text = "Score: " + scoreValue.ToString();
winTextObject.SetActive(false);
loseTextObject.SetActive(false);
lives = 3;
}
// Update is called once per frame
void FixedUpdate() {
float hozMovement = Input.GetAxis("Horizontal");
float verMovement = Input.GetAxis("Vertical");
rd2d.AddForce(new Vector2(hozMovement * speed, verMovement * speed));
}
private void OnCollisionEnter2D(Collision2D collision) {
if (collision.collider.tag == "Coin") {
scoreValue += 1;
scoreText.text = "Score: " + scoreValue.ToString();
Destroy(collision.collider.gameObject);
} else if (collision.collider.tag == "Enemy") {
lives -= 1;
livesText.text = lives.ToString();
Destroy(collision.collider.gameObject);
}
}
void Update() {
if (scoreValue >= 4) {
winTextObject.SetActive(true);
} {
livesText.text = "Lives: " + lives.ToString();
}
if (lives <= 0) {
loseTextObject.SetActive(true);
}
}
private void OnCollisionStay2D(Collision2D collision) {
if (collision.collider.tag == "Ground") {
if (Input.GetKey(KeyCode.W)) {
rd2d.AddForce(new Vector2(0, 3), ForceMode2D.Impulse);
}
}
if (Input.GetKey("escape")) {
Application.Quit();
}
if (scoreValue == 4) {
transform.position = new Vector2(64.0 f, -1.0 f);
}
}
}
您可以添加额外的布尔变量,这样它会输入if
只有一次。
private bool isGameOver;
Start()
您确保isGameOver = false
if (scoreValue == 4 && !isGameOver)
{
isGameOver = true;
transform.position = new Vector2(64.0f, -1.0f);
}
有了这个添加,您将只触发一次“传送”。
我认为您应该在您希望发生运输事件的地方放置一个标志。
bool isTransported = false;
然后在 Update() 中进行比较
if (scoreValue >= 4) isTransported == true;
if (isTransported) transform.position = new Vector2(64.0 f, -1.0 f);
如果您想通过以下方式进行另一次运输,则重置布尔值:
isTranported == false;
如果你想在你的游戏中做更多的交通事件,我也建议你。 您应该明确地将您的分数与一个值或一系列值进行比较。 否则,您的活动将无法正常工作。 例如,当得分 >=4 时,您希望您的角色传送到位置 A,当得分 >=10 时,您的角色移动到位置 B,则这里的条件重叠。 游戏将执行这两个事件,因为 >=10 也是 >=4。
通常,不是每帧轮询检查这些值,而是让您编写事件驱动的代码!
根本不需要额外的标志。
由于OnCollisionEnter2D
似乎实际上是改变两个值的唯一地方而不是例如
// NOT NEEDED AT ALL
// private void Update() { }
private void OnCollisionEnter2D(Collision2D collision)
{
// In general rather use "CompareTag" instead of string "=="
// While "==" silently fails in case of typos or non-existent tags
// "CompareTag" will throw an error making your debugging easier and is also slightly faster since it uses Hashes
if (collision.gameObject.CompareTag("Coin"))
{
Destroy(collision.gameObject);
scoreValue++;
scoreText.text = $"Score: {scoreValue}";
if(scoreValue == 4)
{
winTextObject.SetActive(true);
// in general never set the position via Transform when dealing with Rigidbodis!
rd2d.position = new Vector2(64.0 f, -1.0 f);
}
}
else if (collision.gameObject.CompareTag("Enemy"))
{
Destroy(collision.gameObject);
lives--;
livesText.text = $"Lives: {lives}";
if (lives <= 0)
{
loseTextObject.SetActive(true);
}
}
}
private void OnCollisionStay2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
if (Input.GetKey(KeyCode.W))
{
rd2d.AddForce(new Vector2(0, 3), ForceMode2D.Impulse);
}
}
if (Input.GetKey("escape"))
{
Application.Quit();
}
// no need to poll check the "lives" here either
}
您甚至可以更进一步地使用属性,这样您就可以将行为与字段的任何更改结合起来,甚至可以从外部设置它们而无需双重实现:
// This only stores the value (backing field) but you will never touch it directly ;)
private int _scoreValue;
// This now is a property that allows everyone to read the value
// but only this class to set it (for now)
// additionally every time you set the value it will update the display and react to the => 4 condition
public int scoreValue
{
get => _scoreValue;
private set
{
_scoreValue = value;
scoreText.text = $"Score: {_scoreValue}";
if(_scoreValue == 4)
{
winTextObject.SetActive(true);
// in general never set the position via Transform when dealing with Rigidbodis!
rd2d.position = new Vector2(64.0 f, -1.0 f);
}
}
}
// The same thing you can also make for the lives
private int _lives;
public int lives
{
get => _lives;
private set
{
_lives = value;
livesText.text = $"Lives: {_lives}";
if (_lives <= 0)
{
loseTextObject.SetActive(true);
}
}
}
所以现在你会简单地做
private void OnCollisionEnter2D(Collision2D collision)
{
// In general rather use "CompareTag" instead of string "=="
// While "==" silently fails in case of typos or non-existent tags
// "CompareTag" will throw an error making your debugging easier and is also slightly faster since it uses Hashes
if (collision.gameObject.CompareTag("Coin"))
{
Destroy(collision.gameObject);
scoreValue++;
}
else if (collision.gameObject.CompareTag("Enemy"))
{
Destroy(collision.gameObject);
lives--;
}
}
但是以后可以添加越来越多的方式来说明如何失去或获得分数和生命,而不必记住还要实现文本更新和条件检查。 你只能做这些曾经的属性中;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.