首页 > 解决方案 > 如果在开始游戏时父对象首先不活动,我如何注册事件?

问题描述

剧本 :

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

public class SecurityKeypadSystem : MonoBehaviour
{
    [Header("References")]
    // rather let this class control the display text
    [SerializeField] private TextMesh _text;

    [Header("Settings")]
    // also rather let this class control the length of a code
    [SerializeField] private int _codeLength = 8;

    [Header("Debugging")]
    [SerializeField] private GameObject[] _keyPadNumbers;
    [SerializeField] private List<int> _code = new List<int>();

    // This will be invoked once the code length has reached the target length
    public event Action<int> OnCodeComplete;

    // Start is called before the first frame update
    private void Start()
    {
        _keyPadNumbers = GameObject.FindGameObjectsWithTag("Keypad");

        // register a callback to each key that handles the numbers
        foreach (var keyPadNumber in _keyPadNumbers)
        {
            // It is save to remove an event even if it hasn't been added yet
            // this makes sure it is only added exactly once
            // only adding this here for the case you later have to move this again to Update for some reason ;)
            var securityKeypadKeys = keyPadNumber.GetComponent<SecurityKeypadKeys>();
            securityKeypadKeys.onKeyPressed -= HandleKeyPressed;
            securityKeypadKeys.onKeyPressed += HandleKeyPressed;
            securityKeypadKeys.onKeyPressed += SecurityKeypadKeys_onKeyPressed;
        }
    }

    private void SecurityKeypadKeys_onKeyPressed(int value)
    {
        string gethere = "";
    }

    private void OnDestroy()
    {
        // just for completeness you should always remove callbacks as soon as they are not needed anymore
        // in order to avoid any exceptions
        foreach (var keyPadNumber in _keyPadNumbers)
        {
            var securityKeypadKeys = keyPadNumber.GetComponent<SecurityKeypadKeys>();
            securityKeypadKeys.onKeyPressed -= HandleKeyPressed;
        }
    }

    // this is called when a keypad key was pressed
    private void HandleKeyPressed(int value)
    {
        // add the value to the list
        _code.Add(value);

        _text.text += value.ToString();

        // Check if the code has reached the target length
        // if not do nothing
        if (_code.Count < _codeLength) return;

        // if it reached the length combine all numbers into one int
        var exponent = _code.Count;
        float finalCode = 0;
        foreach (var digit in _code)
        {
            finalCode =digit * Mathf.Pow(10, exponent);
            exponent--;
        }

        // invoke the callback event
        OnCodeComplete?.Invoke((int)finalCode);

        // and reset the code
        ResetCode();
    }

    // Maybe you later want an option to clear the code field from the outside as well
    public void ResetCode()
    {
        _code.Clear();
        _text.text = "";
    }

    // also clear the input if this gets disabled
    private void OnDisable()
    {
        ResetCode();
    }
}

在开始内我正在制作这条线:

_keyPadNumbers = GameObject.FindGameObjectsWithTag("Keypad");

但这会返回 0,因为当我运行游戏时,带有“键盘”标签的 GameObjects 尚未激活,但它们在游戏后期会变得活跃。

这是附有此脚本的 GameObject 和未激活的 Key Cubes 游戏对象的屏幕截图:

保安系统

标签: c#unity3d

解决方案


推荐阅读