制造气锁(多扇门,多个杠杆,可重复使用,统一,C#)

问题描述 投票:0回答:1

对于我的上一个大学项目,我正在制作一个小型2D Unity游戏。在那里,我想创建一个气锁:两个门,至少有两个按钮/杠杆可以打开它们。使用第一杆打开第一扇门,两扇门都开始关闭,但使用下一个杠杆关闭了您身后的门,而另一扇门将另一扇门关闭。

上次我编码的东西大约在2018年左右,我以前从未碰过C#。游戏中已经有两个脚本(请参见下文;不是我制作的),但是在级别开始时它与两个特定的门有关(因此引用了“真空”)。我想制作可重复使用的新脚本,对于我喜欢和需要的尽可能多的实例。旧脚本不可重复使用,显然依靠“全局”布尔值,因此,如果我重复使用它,它可以在我不想要的其他地方打开/关闭门。

那么,当我从头开始时,我将如何编码此问题?

Lever.cs

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

public class Lever : MonoBehaviour 
{
    private static bool leverStatus = false;
    private static bool canOpen = false;
    private static GameObject[] leverDoors;

    public AudioClip audioClip;
    private AudioController audioController;

    private GameObject vacuum;
    private PlayerMovementController playerMovement;

    private void Start()
    {
        audioControler = GameObject.Find("SFX_Controler").GetComponent<AudioController>();
        leverDoors = GameObject.FindGameObjectsWithTag("Lever-Door");
        vacuum = GameObject.FindGameObjectWithTag("Vacuum");
        playerMovement = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerMovementController>();
    }

    private void Update()
    {
        checkDoors();

        if( canOpen)
        {
            FindObjectOfType<UIHandler>().showUseInfo();

            if (Input.GetAxisRaw("Interact") != 0)
            {
                changeStatus();
                StartCoroutine(changeStatus());
            }
        }
    }

    private void checkDoors()
    {
        foreach(GameObject g in leverDoors)
        {
            if (g.GetComponent<LeverDoor>().neededLeverStatus == leverStatus)
            {
                g.SetActive(false);
            }
            else 
            {
                g.SetActive(true);
            }
        }
    }

    IEnumerator changeStatus()
    {
        audioController.playSFX(audioClip);
        playerMovement.interruptMovement(true);
        canOpen = false;
        yield return new WaitForSeconds(0.5f);
        audioController.playSFX(vacuum.GetComponent<Vacuum>().audioClip);
        yield return new WaitForSeconds(1.2f);

        if (leverStatus)
        {
            leverStatus = false;
            vacuum.transform.localScale = new Vector2(1, 1);
        }
        else
        {
            leverStatus = true;
            vacuum.transform.localScale = new Vector2(2.5f, 1);
        }

        playerMovement.interruptMovement(false);
        canOpen = true;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            canOpen = true;
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            canOpen = false;
            FindObjectOfType<UIHandler>().disableUseInfo();
        }
    }
}

LeverDoor.cs

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

public class LeverDoor : MonoBehaviour  
{
    [SerializeField]
    public bool neededLeverStatus;
    
    // Update is called once per frame
    void Update () 
    {
        gameObject.SetActive(true);
    }
}

您的脚本是完全可用的,只需要进行一些调整即可!我将其放置在脚本的下方,该脚本与现有的
LeverDoor.cs
c# unity-game-engine
1个回答
0
投票
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Lever : MonoBehaviour { //[SerializeField] lets private variables be seen in the inspector private bool leverStatus = false; // The status of the lever (opened of closed) private bool canOpen = false; // If the lever can be opened [SerializeField] private GameObject leverDoor; // The door that the lever opens public AudioClip audioClip; // The sound of the lever [SerializeField] private AudioController audioController; // Reference to the audio controller script [SerializeField] private PlayerMovementController playerMovement; // Reference to the player movement script private void Update() { checkDoor(); if(canOpen) // If the player can interact with the lever { FindObjectOfType<UIHandler>().showUseInfo(); // Show the use info on the screen if (Input.GetAxisRaw("Interact") != 0) // If the player presses the interact button { StartCoroutine(changeStatus()); // Change the status of the lever } } } private void checkDoor() // Check if the door should be open or closed { if (g.GetComponent<LeverDoor>().neededLeverStatus == leverStatus) { g.SetActive(false); } else { g.SetActive(true); } } // Change the status of the lever IEnumerator changeStatus() { audioController.playSFX(audioClip); // Play the sound of the lever playerMovement.interruptMovement(true); // Stop the player from moving canOpen = false; // The player can't interact with the lever anymore yield return new WaitForSeconds(0.5f); // Wait for the sound to finish playing //audioController.playSFX(vacuum.GetComponent<Vacuum>().audioClip); if (leverStatus) // If the lever is up, put it down { leverStatus = false; // Add something that happens when the lever is down } else // If the lever is down, put it up { leverStatus = true; // Add something that happens when the lever is up } playerMovement.interruptMovement(false); // Let the player move again canOpen = true; // The player can interact with the lever again } // If the player enters the trigger area, the player can interact with the lever private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.tag == "Player") { canOpen = true; } } // If the player leaves the trigger area, the player can't interact with the lever anymore private void OnTriggerExit2D(Collider2D collision) { if (collision.gameObject.tag == "Player") { canOpen = false; FindObjectOfType<UIHandler>().disableUseInfo(); // Hide the use info on the screen } } }

最佳运气=d


最新问题
© www.soinside.com 2019 - 2025. All rights reserved.