Unity - 动作被调用两次 - OnTriggerEnter、OnClick,一切?
Unity - Actions Being Called Twice - OnTriggerEnter, OnClick, EVERYTHING?
所以我正在创建一个绵羊计数器游戏,昨天,当我上床睡觉时,一切都运行良好。今天,当我打开 Unity 做一些收尾工作时,我所做的一切都被调用了两次...
因此,当我单击开始按钮时,它会调用两次开始游戏,然后当我的羊撞到障碍物时,它会调用两次 OnTriggerEnter。我知道我做错了什么或发生了什么,我宁愿不必重新启动整个项目...
Console Log
计数器脚本
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class Counter : MonoBehaviour
{
public TMP_Text savedText;
public TMP_Text deadText;
private int savedCount = 0;
private int deadCount = 0;
private void Start()
{
savedCount = 0;
deadCount = 0;
}
public void AddSavedSheep()
{
savedCount++;
savedText.text = "Saved: " + savedCount;
}
public void AddDeadSheep()
{
deadCount++;
deadText.text = "Dead: " + deadCount;
}
}
羊文
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SheepControls : MonoBehaviour
{
private Rigidbody rb;
[Header("Movement")]
[Tooltip("How fast to move GameObject Forward.")]
public float forwardSpeed = 4.0f;
[Tooltip("Apply this much force to Rigidbody.")]
public float jumpForce = 5.0f;
private float groundY;
[Space]
[SerializeField] private bool jumping;
[SerializeField] private bool isDestroyed;
[SerializeField] private bool isSaved;
public ParticleSystem explosionParticles;
private Counter counter;
void Start()
{
rb = GetComponent<Rigidbody>();
groundY = (transform.position.y)+0.02f;
counter = FindObjectOfType<Counter>();
}
void Update()
{
transform.Translate(forwardSpeed * Time.deltaTime * Vector3.forward);
if (Input.GetKeyDown(KeyCode.Space) && !jumping)
{
if(transform.position.y < groundY)
{
Jump();
}
}
jumping = false;
}
private void Jump()
{
jumping = true;
rb.AddForce(Vector3.up * jumpForce);
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("ExplosiveWire"))
{
if (isDestroyed) return;
else
{
Debug.Log("Hit Wire");
isDestroyed = true;
Destroy(gameObject);
Instantiate(explosionParticles, transform.position,
explosionParticles.transform.rotation);
}
counter.AddDeadSheep();
}
if (other.CompareTag("Goal"))
{
if (isSaved) return;
else
{
Debug.Log("Reached Goal");
isSaved = true;
Destroy(gameObject);
}
counter.AddSavedSheep();
}
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Sheep"))
{
Physics.IgnoreCollision(this.GetComponent<Collider>(),
collision.gameObject.GetComponent<Collider>());
}
}
}
GameManager 脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public bool isGameActive;
public GameObject titleScreen;
public GameObject sheepControllerPrefab;
public void StartGame(int difficulty)
{
titleScreen.SetActive(false);
isGameActive = true;
InvokeRepeating(nameof(SpawnSheepWave), 2.0f, 2.0f);
}
public void Restart()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
public void SpawnSheepWave()
{
Instantiate(sheepControllerPrefab, transform.position,
transform.rotation);
}
}
启动按钮脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DifficultyButton : MonoBehaviour
{
private Button button;
private GameManager gameManager;
[Header("Difficulty Level")]
[Tooltip("The spawn rate will be divided by this number.")]
public int difficulty;
void Start()
{
gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
button = GetComponent<Button>();
button.onClick.AddListener(SetDifficulty);
}
public void SetDifficulty()
{
Debug.Log(gameObject.name + " was clicked.");
gameManager.StartGame(difficulty);
}
}
所以,它实际上是将分数加了两次,所以最初我想也许我需要做一个 isDestroyed 或 isSaved 检查并将其添加到脚本中,但似乎没有什么可以阻止它加分两次,或者我认为我点击了开始按钮两次。
Double increment of the score
我觉得我的代码很好,我只是不知道它发生了什么以及为什么它要调用两次。您认为有解决方案吗,或者我可能只需要在新项目中重新创建游戏?
当盒子碰撞器进入触发器时尝试禁用它是否可以解决问题?
羊身上只有一个BoxCollider,围栏上只有一个BoxCollider,球门上只有一个BoxCollider。它们都有刚体并且调用正确,它们一次只发生两次。
感谢你们提供的任何帮助!
我还尝试在 if 语句之前或之后移动增量步骤,看看它是否会做任何不同的事情,但我得到了相同的结果。
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("ExplosiveWire"))
{
if (isDestroyed) return;
else
{
Debug.Log("Hit Wire");
isDestroyed = true;
Destroy(gameObject);
Instantiate(explosionParticles, transform.position,
explosionParticles.transform.rotation);
counter.AddDeadSheep();
}
}
if (other.CompareTag("Goal"))
{
if (isSaved) return;
else
{
Debug.Log("Reached Goal");
isSaved = true;
Destroy(gameObject);
counter.AddSavedSheep();
}
}
}
[编辑]
添加了附加到游戏对象的脚本图像。
Scripts Attached to Game Objects
每次点击您的难度按钮时都会调用开始。其中已经 运行。所以你会得到 2。在开始按钮检查器中查看选项
所以我正在创建一个绵羊计数器游戏,昨天,当我上床睡觉时,一切都运行良好。今天,当我打开 Unity 做一些收尾工作时,我所做的一切都被调用了两次...
因此,当我单击开始按钮时,它会调用两次开始游戏,然后当我的羊撞到障碍物时,它会调用两次 OnTriggerEnter。我知道我做错了什么或发生了什么,我宁愿不必重新启动整个项目...
Console Log
计数器脚本
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class Counter : MonoBehaviour
{
public TMP_Text savedText;
public TMP_Text deadText;
private int savedCount = 0;
private int deadCount = 0;
private void Start()
{
savedCount = 0;
deadCount = 0;
}
public void AddSavedSheep()
{
savedCount++;
savedText.text = "Saved: " + savedCount;
}
public void AddDeadSheep()
{
deadCount++;
deadText.text = "Dead: " + deadCount;
}
}
羊文
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SheepControls : MonoBehaviour
{
private Rigidbody rb;
[Header("Movement")]
[Tooltip("How fast to move GameObject Forward.")]
public float forwardSpeed = 4.0f;
[Tooltip("Apply this much force to Rigidbody.")]
public float jumpForce = 5.0f;
private float groundY;
[Space]
[SerializeField] private bool jumping;
[SerializeField] private bool isDestroyed;
[SerializeField] private bool isSaved;
public ParticleSystem explosionParticles;
private Counter counter;
void Start()
{
rb = GetComponent<Rigidbody>();
groundY = (transform.position.y)+0.02f;
counter = FindObjectOfType<Counter>();
}
void Update()
{
transform.Translate(forwardSpeed * Time.deltaTime * Vector3.forward);
if (Input.GetKeyDown(KeyCode.Space) && !jumping)
{
if(transform.position.y < groundY)
{
Jump();
}
}
jumping = false;
}
private void Jump()
{
jumping = true;
rb.AddForce(Vector3.up * jumpForce);
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("ExplosiveWire"))
{
if (isDestroyed) return;
else
{
Debug.Log("Hit Wire");
isDestroyed = true;
Destroy(gameObject);
Instantiate(explosionParticles, transform.position,
explosionParticles.transform.rotation);
}
counter.AddDeadSheep();
}
if (other.CompareTag("Goal"))
{
if (isSaved) return;
else
{
Debug.Log("Reached Goal");
isSaved = true;
Destroy(gameObject);
}
counter.AddSavedSheep();
}
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Sheep"))
{
Physics.IgnoreCollision(this.GetComponent<Collider>(),
collision.gameObject.GetComponent<Collider>());
}
}
}
GameManager 脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public bool isGameActive;
public GameObject titleScreen;
public GameObject sheepControllerPrefab;
public void StartGame(int difficulty)
{
titleScreen.SetActive(false);
isGameActive = true;
InvokeRepeating(nameof(SpawnSheepWave), 2.0f, 2.0f);
}
public void Restart()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
public void SpawnSheepWave()
{
Instantiate(sheepControllerPrefab, transform.position,
transform.rotation);
}
}
启动按钮脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DifficultyButton : MonoBehaviour
{
private Button button;
private GameManager gameManager;
[Header("Difficulty Level")]
[Tooltip("The spawn rate will be divided by this number.")]
public int difficulty;
void Start()
{
gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
button = GetComponent<Button>();
button.onClick.AddListener(SetDifficulty);
}
public void SetDifficulty()
{
Debug.Log(gameObject.name + " was clicked.");
gameManager.StartGame(difficulty);
}
}
所以,它实际上是将分数加了两次,所以最初我想也许我需要做一个 isDestroyed 或 isSaved 检查并将其添加到脚本中,但似乎没有什么可以阻止它加分两次,或者我认为我点击了开始按钮两次。
Double increment of the score
我觉得我的代码很好,我只是不知道它发生了什么以及为什么它要调用两次。您认为有解决方案吗,或者我可能只需要在新项目中重新创建游戏?
当盒子碰撞器进入触发器时尝试禁用它是否可以解决问题?
羊身上只有一个BoxCollider,围栏上只有一个BoxCollider,球门上只有一个BoxCollider。它们都有刚体并且调用正确,它们一次只发生两次。
感谢你们提供的任何帮助!
我还尝试在 if 语句之前或之后移动增量步骤,看看它是否会做任何不同的事情,但我得到了相同的结果。
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("ExplosiveWire"))
{
if (isDestroyed) return;
else
{
Debug.Log("Hit Wire");
isDestroyed = true;
Destroy(gameObject);
Instantiate(explosionParticles, transform.position,
explosionParticles.transform.rotation);
counter.AddDeadSheep();
}
}
if (other.CompareTag("Goal"))
{
if (isSaved) return;
else
{
Debug.Log("Reached Goal");
isSaved = true;
Destroy(gameObject);
counter.AddSavedSheep();
}
}
}
[编辑] 添加了附加到游戏对象的脚本图像。 Scripts Attached to Game Objects
每次点击您的难度按钮时都会调用开始。其中已经 运行。所以你会得到 2。在开始按钮检查器中查看选项