好的,所以我有这个项目,我正在处理它实际上是在 Unity2D 中创建的功能中的马里奥克隆。出于某种原因,它调用了 OnTrigger/OnCollision 方法三次(正如它中继调试消息设置为在 OnCollision 或 OnTrigger 被调用三次时中继的事实所示,即使它只应该执行一次(见附图)) ,即使我不是为此而写的。我的代码如下(不好意思乱七八糟,我还是C#和Unity2D的新手)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class playerMovement : MonoBehaviour
{
public float moveSpeed;
private float moveDirection;
public float jumpForce;
[SerializeField] private bool isJumping = false;
private Rigidbody2D rb;
private bool facingRight = true;
public Transform ceilingCheck;
public Transform groundCheck;
public LayerMask groundObjects;
public bool isGrounded;
public float checkRadius;
public GameObject camera;
public AudioSource audioSource;
public AudioClip otherClip;
public float score;
public TextMeshProUGUI scoreCount;
public float health;
public TextMeshProUGUI lifeCount;
public GameObject[] enemy;
public GameObject deathBarrier;
public GameObject nPC;
public GameObject youHaveSoMuchToLiveFor;
public GameObject youCannotEscape;
public bool talking;
public bool bossTimerStart;
//nabs stuff before start so there's no lag and so you don't have to nab it yourself
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
// Start is called before the first frame update
void Start()
{
enemy = GetComponentsInParent<GameObject>(tag == "Enemy");
}
// Update is called once per frame
void Update()
{
//get inputs
ProcessInputs();
//flip
Animate();
StartCoroutine(DoThings());
scoreCount.text = "Score: " + score;
lifeCount.text = "Health: " + health;
if (Input.GetKeyDown(KeyCode.RightShift))
{
moveSpeed = 3;
}
if (Input.GetKeyUp(KeyCode.RightShift))
{
moveSpeed = 8;
}
if (Input.GetKeyDown(KeyCode.LeftShift))
{
moveSpeed = 3;
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
moveSpeed = 8;
}
}
private void FixedUpdate()
{
//move
if (!talking)
{
Move();
}
isGrounded = Physics2D.OverlapCircle(groundCheck.position, checkRadius, groundObjects);
}
private void ProcessInputs()
{
moveDirection = Input.GetAxis("Horizontal");
if (Input.GetButtonDown("Jump") && isGrounded)
{
isJumping = true;
}
}
public IEnumerator DoThings()
{
while (talking)
{
rb.velocity = Vector2.zero;
yield return null;
}
}
private void Move()
{
rb.velocity = new Vector2(moveDirection * moveSpeed, rb.velocity.y);
if (isJumping)
{
rb.AddForce(new Vector2(0f, jumpForce));
}
isJumping = false;
}
private void FlipCharacter()
{
facingRight = !facingRight;
transform.Rotate(0f, 180f, 0f);
}
private void Animate()
{
//flip
if (moveDirection > 0 && !facingRight)
{
FlipCharacter();
}
if (moveDirection < 0 && facingRight)
{
FlipCharacter();
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Coin")
{
score += 10;
Destroy(other.gameObject);
}
if (other.tag == "Npc")
{
nPC.gameObject.SetActive(true);
}
if (other.tag == "House")
{
youHaveSoMuchToLiveFor.gameObject.SetActive(true);
talking = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.tag == "Npc")
{
nPC.gameObject.SetActive(false);
}
if (other.tag == "House")
{
youHaveSoMuchToLiveFor.gameObject.SetActive(false);
}
if (other.gameObject.tag == "BossArea")
{
Debug.Log("uHOH CUTSCENE TIME WOOOOOO");
Destroy(other.gameObject);
youCannotEscape.gameObject.SetActive(true);
}
}
private void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "EnemyLeft")
{
Debug.Log("scream but right");
rb.AddForce(new Vector2(5000f, 200f));
if (health > 0)
{
Debug.Log("apparently let's check this");
health -= 1;
}
if (health <= 0)
{
StartCoroutine(Woooo());
StartCoroutine(YouGonDie());
}
}
if (other.gameObject.tag == "EnemyRight")
{
Debug.Log("scream but left");
rb.AddForce(new Vector2(-5000f, 200f));
if (health > 0)
{
health -= 1;
}
if (health <= 0)
{
StartCoroutine(Woooo());
StartCoroutine(YouGonDie());
}
}
if (other.gameObject.tag == "Bullet")
{
Debug.Log("oopsie you got shot UwU");
if (health > 0)
{
health -= 1;
}
if (health <= 0)
{
StartCoroutine(Woooo());
StartCoroutine(YouGonDie());
}
}
if (other.gameObject.tag == "EnemyTop")
{
Debug.Log("bonk");
Destroy(other.transform.parent.gameObject);
score += 5;
}
if (other.gameObject == deathBarrier)
{
StartCoroutine(YouFellLol());
}
IEnumerator Woooo()
{
Debug.Log("istg i think this game is an elaborate moistcritikal reference, truly what i've been waiting for, yeah baby");
yield return new WaitForSecondsRealtime(1.2f);
Destroy(gameObject);
}
IEnumerator YouGonDie()
{
AudioSource.PlayClipAtPoint(otherClip, new Vector3(0, 0, 0));
yield return new WaitForSecondsRealtime(0.001f);
}
IEnumerator YouFellLol()
{
Debug.Log("Hey stinky! You fell uwu");
yield return new WaitForSecondsRealtime(0.001f);
Destroy(gameObject);
}
}
public void TalkingWith()
{
talking = true;
}
public void StopTalkingWith()
{
talking = false;
}
}
它只是在我添加了一个功能后才开始这样做,在该功能中与某些对象交互时,玩家停止移动直到交互结束(用于 NPC 交互和过场动画)。我原以为它只会打电话一次。相反,它调用了三次。