BUAA-Soft-2024-Summer / Soft-Summer-2024

北航软件学院 2024 夏《程序设计实践》 小学期仓库
11 stars 1 forks source link

Unity GameObject desplay wrong. #2

Closed Tengpaz closed 2 months ago

Tengpaz commented 2 months ago

Unity游戏对象显示Bug

环境工具

问题阐述

image

如图GameObject EndBed子物体DownArrow初始未运行时为禁用状态

image

同时子物体Bed中的代码EndNotify Script Component均初始时为禁用状态

运行预期效果为角色接触床EndBed物体后上方不会显示提示箭头DownArrow

实际运行图片

物体接触EndBed物体时

image

此时Hierarchy栏内DownArrow物体变为Active状态

物体离开EndBed物体时

image

此时Hierarchy栏内DownArrow物体变为Not Active即禁用状态

补充信息

image

图示物体DownArrow物体的Inspector栏信息

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Notify : MonoBehaviour
{
    [SerializeField] private GameObject Arrow;

    private void Start()
    {
        Arrow.SetActive(false);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            Arrow.SetActive(true);
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            Arrow.SetActive(false);
        }
    }
}

此为代码Notify代码内容

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class End : MonoBehaviour
{
    [SerializeField] private GameObject Player;

    private bool InBed = false;
    private Animator animator;
    private string[] worldName = { "Menu", "Green", "White", "Red", "MainScene" };

    private void Start()
    {
        gameObject.GetComponent<End>().enabled = false;
        animator = GetComponent<Animator>();
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            InBed = true;
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            InBed = false;
        }
    }

    private void Update()
    {
        if (InBed)
        {
            if (Input.GetKeyUp("down") && Player.activeInHierarchy == true)
            {
                FallAsleep();
            }
        }
    }

    private void FallAsleep()
    {
        Player.SetActive(false);
        transform.parent.GetChild(1).gameObject.SetActive(false);
        animator.SetBool("IsSleep", true);
    }

    private void transfer()
    {
        SceneManager.LoadScene(4);
    }
}

此为代码End的代码内容

解决需求

使得无论角色是否触碰物体EndBed,上方箭头初始时都不会Active

Tengpaz commented 2 months ago

补充信息

图片所示两状态下组件Notify均为Not Enable状态

Ferpakenameyea commented 2 months ago

我很抱歉,不过这个问题的描述以及代码看起来实在让人困惑,如果您只是需要一个指引箭头,您应当只是书写一个类来直接控制Arrow是否为Active

如果您的需求仅仅是让箭头初始时不会Active,你可以在控制显示的类中加入判断玩家是否有离开过碰撞箱,如果玩家从未离开碰撞箱,就不要让自己显示。或者在初始状态下不要让玩家和碰撞箱重叠。

并且我建议您重构一下自己的代码,现在的显示逻辑有些过于紧耦且复杂。

很抱歉我不能完全解决您的问题。如果您需要更多帮助,可以单独联系我。

Ferpakenameyea commented 2 months ago

对于简单的碰撞箱重叠检测,您可以使用如下代码的方法:

void CheckBoundsOverlap(Collider otherCollider)
{
    Collider myCollider = GetComponent<Collider>();

    if (myCollider.bounds.Intersects(otherCollider.bounds))
    {
        // Do something...
        Debug.Log("Bounds overlap with " + otherCollider.gameObject.name);
    }
}
Tengpaz commented 2 months ago

感谢学长提供的代码!碰撞箱重叠目前还不会所以处理比较复杂www还有问题我单独找学长您,谢谢助教!!