Destroying Array

时间: 2023-11-16 08:53:11 浏览: 113
To destroy an array in C, you can use the `free()` function to deallocate the memory occupied by the array. Here's an example: ```c #include <stdlib.h> int main() { int* arr = malloc(5 * sizeof(int)); // dynamically allocate memory for the array // Use the array here... // Destroy the array free(arr); arr = NULL; return 0; } ``` After calling `free(arr)`, the memory allocated for the array is released back to the system, and `arr` is set to `NULL` to avoid any potential access to the now-deallocated memory. Related questions: 1. How does the `free()` function work in C? 2. Can I destroy individual elements in an array without destroying the entire array? 3. What happens if I try to access a destroyed array in C?
阅读全文

相关推荐

是不是根据这个去修改,因为我只需要将我们官方提供的模型,进行jit.trace,r然后在编译,拿到编译后的模型,我再进行f1 score计算精度 # coding=utf-8 # Copyright 2021 Arm Limited and affiliates. # Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. # Copyright 2018 The Google AI Language Team Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import array import json import os import sys sys.path.insert( 0, os.path.join( os.getcwd(), "DeepLearningExamples", "PyTorch", "LanguageModeling", "BERT" ), ) sys.path.insert(0, os.getcwd()) try: from ray.util.actor_pool import ActorPool import ray from squad_QSL import get_squad_QSL from transformers import BertConfig, BertForQuestionAnswering import transformers import torch_tensorrt import torch import numpy as np import mlperf_loadgen as lg except ImportError: raise Exception("Error importing local modules") # Adjustable Parameters # Note. num_samples (called "test_query_count" in MLC) must be a multiple # of batch_size BATCH_SIZE = 16 @ray.remote(num_cpus=1, num_gpus=1) class TorchPredictor: def __init__(self, config_json, model_file, batch_size): print("init", os.getpid(), torch.cuda.device_count()) self.pid = os.getpid() self.dev_cnt = torch.cuda.device_count() config = BertConfig( attention_probs_dropout_prob=config_json["attention_probs_dropout_prob"], hidden_act=config_json["hidden_act"], hidden_dropout_prob=config_json["hidden_dropout_prob"], hidden_size=config_json["hidden_size"], initializer_range=config_json["initializer_range"], intermediate_size=config_json["intermediate_size"], max_position_embeddings=config_json["max_position_embeddings"], num_attention_heads=config_json["num_attention_heads"], num_hidden_layers=config_json["num_hidden_layers"], type_vocab_size=config_json["type_vocab_size"], vocab_size=config_json["vocab_size"], ) self.dev = torch.device("cuda") self.model = BertForQuestionAnswering(config) self.model.to(self.dev) self.model.eval() self.model.load_state_dict(torch.load(model_file), strict=False) # tensor rt batch_input_ids = torch.LongTensor( np.zeros( (batch_size, 384))).to( self.dev) traced_mlm_model = torch.jit.trace( self.model, [batch_input_ids, batch_input_ids, batch_input_ids], strict=False, ) self.trt_model = torch_tensorrt.compile( traced_mlm_model, inputs=[ torch_tensorrt.Input( shape=[ batch_size, 384], dtype=torch.int32), torch_tensorrt.Input( shape=[ batch_size, 384], dtype=torch.int32), torch_tensorrt.Input( shape=[ batch_size, 384], dtype=torch.int32), ], enabled_precisions={torch.float32, torch.float16}, workspace_size=2000000000, truncate_long_and_double=True, ) print("done loading") # Logic for inference on 1 batch of data. def forward(self, batch): input_ids = torch.from_numpy(batch["input_ids"]).to(self.dev) attention_mask = torch.from_numpy(batch["attention_mask"]).to(self.dev) token_type_ids = torch.from_numpy(batch["token_type_ids"]).to(self.dev) with torch.inference_mode(): # pytorch # model_output = self.model.forward(input_ids=input_ids, # attention_mask=attention_mask, # token_type_ids=token_type_ids) # start_scores = model_output.start_logits # end_scores = model_output.end_logits # tensor rt trt_output = self.trt_model( input_ids, attention_mask, token_type_ids) start_scores = trt_output["start_logits"] end_scores = trt_output["end_logits"] batch_ret = torch.stack( [start_scores, end_scores], axis=-1).cpu().numpy() return {"output": batch_ret} def ready(self): pass class BERT_Ray_SUT: def __init__(self, args): with open("bert_config.json") as f: config_json = json.load(f) model_file = os.environ.get( "ML_MODEL_FILE_WITH_PATH", "build/data/bert_tf_v1_1_large_fp32_384_v2/model.pytorch", ) print("Constructing SUT...") self.sut = lg.ConstructSUT(self.issue_queries, self.flush_queries) print("Finished constructing SUT.") self.qsl = get_squad_QSL(args.max_examples) try: ray.init(address="auto") except BaseException: print("WARN: Cannot connect to existing Ray cluster.") print("We are going to start a new RAY cluster, but pay attention that") print("the cluster contains only one node.") print( "If you want to use multiple nodes, please start the cluster manually via:" ) print("\tOn the head node, run ray start --head") print("\tOn other nodes, run ray start --address=<head node IP>:6379") ray.init() self.batch_size = BATCH_SIZE resources = ray.cluster_resources() num_gpus = int(resources.get("GPU", 0)) print(f"The cluster has {num_gpus} GPUs.") self.actor_list = [ TorchPredictor.remote(config_json, model_file, self.batch_size) for _ in range(num_gpus) ] self.pool = ActorPool(self.actor_list) samples = [] for i in range(self.qsl.count): sample = {} eval_features = self.qsl.get_features(i) sample["input_ids"] = np.array( eval_features.input_ids).astype( np.int32) sample["attention_mask"] = np.array(eval_features.input_mask).astype( np.int32 ) sample["token_type_ids"] = np.array(eval_features.segment_ids).astype( np.int32 ) samples.append(sample) self.samples = samples print("Waiting Actors init") for actor in self.actor_list: ray.get(actor.ready.remote()) print("BERT_Ray_SUT construct complete") def issue_queries(self, query_samples): if len(query_samples) % self.batch_size != 0: print("ERROR: batch size must be a multiple of the number of samples") sys.exit(1) batch_samples = [] i = 0 while i < len(query_samples): batch_sample = { "input_ids": np.array( [ self.samples[query_sample.index]["input_ids"] for query_sample in query_samples[i: i + self.batch_size] ] ), "attention_mask": np.array( [ self.samples[query_sample.index]["attention_mask"] for query_sample in query_samples[i: i + self.batch_size] ] ), "token_type_ids": np.array( [ self.samples[query_sample.index]["token_type_ids"] for query_sample in query_samples[i: i + self.batch_size] ] ), } batch_samples.append(batch_sample) i = i + self.batch_size # print("samples len", len(batch_samples)) batch_inference_results = list( self.pool.map_unordered( lambda a, v: a.forward.remote(v), batch_samples) ) cur_query_index = 0 for batch_inference_result in batch_inference_results: batch_inference_result = batch_inference_result["output"] for inference_result in batch_inference_result: response_array = array.array("B", inference_result.tobytes()) bi = response_array.buffer_info() response = lg.QuerySampleResponse( query_samples[cur_query_index].id, bi[0], bi[1] ) lg.QuerySamplesComplete([response]) cur_query_index += 1 def flush_queries(self): pass def __del__(self): print("Finished destroying SUT.") def get_ray_sut(args): return BERT_Ray_SUT(args)

ult-auth-plugin-2.4.0.jar!/com/alibaba/nacos/plugin/auth/impl/token/impl/JwtTokenManager.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.alibaba.nacos.plugin.auth.impl.token.impl.JwtTokenManager]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: the length of secret key must great than or equal 32 bytes; And the secret key must be encoded by base64.Please see https://nacos.io/zh-cn/docs/v2/guide/user/auth.html at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:306) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:287) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:209) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:710) ... 99 common frames omitted Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.alibaba.nacos.plugin.auth.impl.token.impl.JwtTokenManager]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: the length of secret key must great than or equal 32 bytes; And the secret key must be encoded by base64.Please see https://nacos.io/zh-cn/docs/v2/guide/user/auth.html at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:226) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:302) ... 112 common frames omitted Caused by: java.lang.IllegalArgumentException: the length of secret key must great than or equal 32 bytes; And the secret key must be encoded by base64.Please see https://nacos.io/zh-cn/docs/v2/guide/user/auth.html at com.alibaba.nacos.plugin.auth.impl.token.impl.JwtTokenManager.processProperties(JwtTokenManager.java:80) at com.alibaba.nacos.plugin.auth.impl.token.impl.JwtTokenManager.<init>(JwtTokenManager.java:66) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:213) ... 114 common frames omitted Caused by: java.lang.IllegalArgumentException: The specified key byte array is 128 bits which is not secure enough for any JWT HMAC-SHA algorithm. The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a size >= 256 bits (the key size must be greater than or equal to the hash output size). See https://tools.ietf.org/html/rfc7518#section-3.2 for more information. at com.alibaba.nacos.plugin.auth.impl.jwt.NacosJwtParser.<init>(NacosJwtParser.java:49) at com.alibaba.nacos.plugin.auth.impl.token.impl.JwtTokenManager.processProperties(JwtTokenManager.java:76) ... 120 common frames omitted 2025-06-23 15:26:44,333 WARN [ThreadPoolManager] Start destroying ThreadPool

/* * HeapTupleData is an in-memory data structure that points to a tuple. * * There are several ways in which this data structure is used: * * * Pointer to a tuple in a disk buffer: t_data points directly into the * buffer (which the code had better be holding a pin on, but this is not * reflected in HeapTupleData itself). * * * Pointer to nothing: t_data is NULL. This is used as a failure indication * in some functions. * * * Part of a palloc'd tuple: the HeapTupleData itself and the tuple * form a single palloc'd chunk. t_data points to the memory location * immediately following the HeapTupleData struct (at offset HEAPTUPLESIZE). * This is the output format of heap_form_tuple and related routines. * * * Separately allocated tuple: t_data points to a palloc'd chunk that * is not adjacent to the HeapTupleData. (This case is deprecated since * it's difficult to tell apart from case #1. It should be used only in * limited contexts where the code knows that case #1 will never apply.) * * * Separately allocated minimal tuple: t_data points MINIMAL_TUPLE_OFFSET * bytes before the start of a MinimalTuple. As with the previous case, * this can't be told apart from case #1 by inspection; code setting up * or destroying this representation has to know what it's doing. * * t_len should always be valid, except in the pointer-to-nothing case. * t_self and t_tableOid should be valid if the HeapTupleData points to * a disk buffer, or if it represents a copy of a tuple on disk. They * should be explicitly set invalid in manufactured tuples.

static int iServerSocket; static stNetAddr stClientAry[cmnDfn_WORKING_PTHREAD_NUMBER / 2]; //static pthread_t iServerThread; int UDPSvr_Run(IN int iPacketSize) { int iRet = -1; int iTaskID = 0; int iLoopNum; //int iClientSocket; char cBuffer[cmnDfn_BUFF_LEN]; struct sockaddr_in stClientAddr; socklen_t slClientLen = sizeof(stClientAddr); while (g_iExit == 0) { if((recvfrom(iServerSocket,cBuffer,cmnDfn_BUFF_LEN,0,(struct sockaddr *)&stClientAddr,&slClientLen)) < 0) { cmn_PrtError("Error in receiving data"); } for (iLoopNum = 0; iLoopNum < cmnDfn_WORKING_PTHREAD_NUMBER / 2; iLoopNum++) { if (stClientAry[iLoopNum].staddr.sin_addr.s_addr != stClientAddr.sin_addr.s_addr && stClientAry[iLoopNum].staddr.sin_port != stClientAddr.sin_port) { stClientAry[iLoopNum].iServerSocket = iServerSocket; stClientAry[iLoopNum].staddr = stClientAddr; stClientAry[iLoopNum].iByteNumber = iPacketSize; } else { continue; } if(ThreadPoolSubmit(UDPRcvTrd, &stClientAry[iLoopNum],&iTaskID) < 0) { cmn_PrtError("Error in submitting task to thread pool"); } if(ThreadPoolSubmit(UDPSndTrd, &stClientAry[iLoopNum],&iTaskID) < 0) { cmn_PrtError("Error in submitting task to thread pool"); } } } iRet = 0; _Exit: return iRet; } int UDPSvr_Create(void) { int iRet = -1; struct sockaddr_in stServerAddr; g_iExit = 0; iServerSocket = socket(AF_INET, SOCK_DGRAM, 0); if (iServerSocket < 0) { cmn_PrtError("Error in creating socket"); } memset(&stServerAddr, 0, sizeof(stServerAddr)); stServerAddr.sin_family = AF_INET; stServerAddr.sin_port = htons(8080); stServerAddr.sin_addr.s_addr = (INADDR_ANY); if(bind(iServerSocket, (struct sockaddr *)&stServerAddr, sizeof(stServerAddr)) < 0) { cmn_PrtError("Error in binding socket"); } if(ThreadPoolInit() < 0) { cmn_PrtError("Error in initializing thread pool"); } iRet = 0; _Exit: return iRet; } int UDPSvr_Destroy(void) { int iRet = -1; //g_iExit = -1; if(ThreadPoolDestroy() < 0) { cmn_PrtError("Error in destroying thread pool"); } if (iServerSocket != -1) { close(iServerSocket); iServerSocket = -1; } /*if(iServerThread != -1) { pthread_join(iServerThread, NULL); iServerThread = -1; }*/ iRet = 0; _Exit: return iRet; }检查代码是否有bug并给出解决方案

// @ts-nocheck class SweetalertSystem { constructor() { this.fieldRegistry = {}; this.modalRegistry = {}; // 添加模态类型注册表 this.nestedModalStack = []; // 添加嵌套模态栈 this.initCoreComponents(); // 初始化事件处理器映射 this.buttonHandlers = new Map(); this.addEntityButtons = null; } initCoreComponents() { // 注册核心字段类型 this.registerFieldType('text', { render: (config) => { return <label class="form-label">${config.label}${config.required ? '*' : ''}</label> <input type="text" class="form-control" name="${config.name}" value="${config.value || ''}" ${config.required ? 'required' : ''} placeholder="${config.placeholder || ''}"> ; } }); this.registerFieldType('select', { render: (config) => { const options = (config.options || []) .map(opt => <option value="${opt.value}" ${config.value == opt.value ? 'selected' : ''}>${opt.label}</option>) .join(''); return <label class="form-label">${config.label}${config.required ? '*' : ''}</label> <select class="form-select" name="${config.name}" ${config.required ? 'required' : ''}> <option value="">${config.placeholder || '请选择'}</option> ${options} </select> ${config.addButton ? <button class="btn btn-outline-secondary add-entity-btn" type="button" data-target-field="${config.name}"> ${config.addButton.label} </button> : ''} ; }, // 更新 afterRender 方法 afterRender: (element, config) => { if (config.select2) { const $select = $(element).find('select'); const swalContainer = Swal.getContainer(); this.safeInitSelect2($select, { theme: 'bootstrap', placeholder: config.placeholder || '请选择', allowClear: true, dropdownParent: swalContainer || document.body }); } } }); this.registerFieldType('number', { render: (config) => { return <label class="form-label">${config.label}${config.required ? '*' : ''}</label> <input type="number" class="form-control" name="${config.name}" value="${config.value || ''}" ${config.required ? 'required' : ''} step="${config.step || 1}" min="${config.min || 0}"> ; } }); this.registerFieldType('checkbox', { render: (config) => { return <input type="checkbox" class="form-check-input" name="${config.name}" id="${config.name}" ${config.value ? 'checked' : ''}> <label class="form-check-label" for="${config.name}">${config.label}</label> ; } }); } // 修改注册方法 - 接受对象而不是函数 registerFieldType(type, definition) { if (!definition.render || typeof definition.render !== 'function') { throw new Error(Field type '${type}' must have a render function); } this.fieldRegistry[type] = definition; } // === 字段渲染方法 === renderTextField(config) { return <label class="form-label">${config.label}${config.required ? '*' : ''}</label> <input type="text" class="form-control" name="${config.name}" value="${config.value || ''}" ${config.required ? 'required' : ''} placeholder="${config.placeholder || ''}"> ; } renderSelectField(config) { const options = (config.options || []) .map(opt => <option value="${opt.value}" ${config.value == opt.value ? 'selected' : ''}>${opt.label}</option>) .join(''); return <label class="form-label">${config.label}${config.required ? '*' : ''}</label> <select class="form-select" name="${config.name}" ${config.required ? 'required' : ''}> <option value="">${config.placeholder || '请选择'}</option> ${options} </select> ${config.addButton ? <button class="btn btn-outline-secondary add-entity-btn" type="button" data-target-field="${config.name}"> ${config.addButton.label} </button> : ''} ; } renderNumberField(config) { return <label class="form-label">${config.label}${config.required ? '*' : ''}</label> <input type="number" class="form-control" name="${config.name}" value="${config.value || ''}" ${config.required ? 'required' : ''} step="${config.step || 1}" min="${config.min || 0}"> ; } renderCheckboxField(config) { return <input type="checkbox" class="form-check-input" name="${config.name}" id="${config.name}" ${config.value ? 'checked' : ''}> <label class="form-check-label" for="${config.name}">${config.label}</label> ; } destroyAllSelect2() { const popup = Swal.getPopup(); if (popup) { // 使用更可靠的选择器 $(popup).find('select.select2-initialized').each(function() { const $select = $(this); try { // 安全销毁 if ($select.data('select2')) { $select.select2('destroy'); } } catch (error) { console.error('Error destroying Select2:', error); } // 移除标记 $select.removeClass('select2-initialized'); }); } } /** * 安全初始化 Select2 * @param {jQuery} $select - jQuery 选择器对象 * @param {Object} options - Select2 配置选项 */ safeInitSelect2($select, options) { // 如果全局禁用标志已设置,跳过初始化 if (window.disableSelect2) return; try { // 检查是否已经初始化 if ($select.data('select2')) { $select.select2('destroy'); } // 初始化 Select2 $select.select2(options); $select.addClass('select2-initialized'); return true; } catch (error) { console.error('Select2 initialization failed:', error); // 禁用后续尝试 window.disableSelect2 = true; return false; } } /** * 安全销毁 Select2 * @param {jQuery} $select - jQuery 选择器对象 */ safeDestroySelect2($select) { try { if ($select.data('select2')) { $select.select2('destroy'); } $select.removeClass('select2-initialized'); return true; } catch (error) { console.error('Select2 destruction failed:', error); return false; } }; // === 核心方法 ===// === 核心方法 === /** * 打开表单弹窗(支持多个新建按钮) * @param {Object} config - 配置对象 */ async openForm(config) { const { title, fields, onSubmit, onAddEntity } = config; // 生成表单HTML const formHTML = fields.map(fieldConfig => { if (!fieldConfig.type) return 'Missing field type'; const fieldType = this.fieldRegistry[fieldConfig.type]; if (!fieldType) return Field type '${fieldConfig.type}' not supported; return fieldType.render(fieldConfig); }).join(''); // 创建弹窗 return new Promise((resolve) => { Swal.fire({ title, html: <form>${formHTML}</form>, focusConfirm: false, showCancelButton: true, confirmButtonText: config.confirmButtonText || '保存', cancelButtonText: config.cancelButtonText || '取消', preConfirm: () => this.collectFormData(), didOpen: () => { // 确保弹窗完全打开后再绑定事件 this.setupMultiButtonHandlers(config, onAddEntity); }, willClose: () => { // 清理资源 this.cleanupMultiButtonHandlers(); } }).then((result) => { if (result.isConfirmed) { onSubmit(result.value); resolve(true); } else { resolve(false); } }); }); } collectFormData() { const data = {}; const popup = Swal.getPopup(); const form = popup.querySelector('form'); if (form) { const formData = new FormData(form); for (const [name, value] of formData.entries()) { // 处理多值字段 if (data[name]) { if (!Array.isArray(data[name])) { data[name] = [data[name]]; } data[name].push(value); } else { data[name] = value; } } } return data; } setupEventHandlers(config) { const popup = Swal.getPopup(); // 绑定添加按钮事件 popup.querySelectorAll('.add-entity-btn').forEach(btn => { btn.addEventListener('click', async () => { const targetField = btn.dataset.targetField; if (config.onAddEntity) { const newItem = await config.onAddEntity(targetField); if (newItem) { this.updateSelectField(popup, targetField, newItem); } } }); }); } // === 模态框注册方法 === registerModalType(name, config) { // 添加afterRender处理 const enhancedConfig = { ...config, afterRender: (config, container) => { // 初始化Select2 container.find('.select2-field').each(function() { const $select = $(this); $select.select2({ theme: 'bootstrap', placeholder: $select.attr('placeholder') || '请选择', allowClear: true, dropdownParent: $select.closest('.modal') }); }); // 调用原始afterRender(如果存在) if (config.afterRender) { config.afterRender(config, container); } } }; this.modalRegistry[name] = enhancedConfig; } // 注册实体表单 registerEntityForm(entityType, fields) { this.registerModalType(entityType, { template: <button type="button" class="btn-close" data-bs-dismiss="modal"></button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button> <button type="button" class="btn btn-primary" id="${entityType}Submit">保存</button> , render: (config, container) => { container.find(#${entityType}Title).text(config.title); let formHTML = ''; // 确保fields是数组 const fields = Array.isArray(config.fields) ? config.fields : []; fields.forEach(fieldConfig => { const fieldType = this.fieldRegistry[fieldConfig.type]; if (fieldType && fieldType.render) { formHTML += fieldType.render(fieldConfig); } }); container.find(#${entityType}Body).html(formHTML); }, getFormData: (container) => { const formData = {}; container.find('input, select, textarea').each(function() { const $el = $(this); const name = $el.attr('name'); if (!name) return; if ($el.attr('type') === 'checkbox') { formData[name] = $el.is(':checked'); } else { formData[name] = $el.val(); } }); return formData; }, bindEvents: (config, container, onSubmit) => { container.find(#${entityType}Submit).off('click').on('click', () => { const formData = this.getFormData(container); onSubmit(formData); }); } }); } // 打开模态框 open(modalType, config, callbacks = {}) { // 如果当前有激活的弹窗,先隐藏它 if (this.nestedModalStack.length > 0) { const currentModal = this.nestedModalStack[this.nestedModalStack.length - 1]; currentModal.hide(); } // 检查模态类型是否注册 if (!this.modalRegistry[modalType]) { console.error(未注册的模态类型: ${modalType}); return null; } const modalConfig = this.modalRegistry[modalType]; const modalId = ${modalType}Modal; let $modal = $(#${modalId}); // 如果模态框不存在则创建 if ($modal.length === 0) { $modal = $(modalConfig.template); $('body').append($modal); } // 清除之前的模态框实例 if ($modal.data('bs.modal')) { $modal.data('bs.modal').dispose(); } // 渲染模态内容 modalConfig.render(config, $modal); // 绑定事件 if (modalConfig.bindEvents) { modalConfig.bindEvents(config, $modal, callbacks.onSubmit || (() => {})); } // 创建模态实例 const modalInstance = new bootstrap.Modal($modal[0]); // 执行afterRender回调 if (modalConfig.afterRender) { modalConfig.afterRender(config, $modal); } // 初始化Select2 $modal.find('.select2-field').each(function() { const $select = $(this); $select.select2({ theme: 'bootstrap', placeholder: $select.attr('placeholder') || '请选择', allowClear: true, dropdownParent: $select.closest('.modal') }); }); // 显示弹窗 modalInstance.show(); // 将新弹窗加入栈 const modalObj = { hide: () => modalInstance.hide(), show: () => modalInstance.show(), getElement: () => $modal[0], config }; this.nestedModalStack.push(modalObj); // 在弹窗打开后绑定新建按钮事件 Swal.getPopup().querySelectorAll('.add-entity-btn')?.forEach(btn => { btn.addEventListener('click', async () => { const entityType = btn.dataset.entityType; const targetField = btn.dataset.targetField; if (callbacks.onAddEntity) { const newItem = await callbacks.onAddEntity(entityType, targetField); if (newItem) { updateSelectField(Swal.getPopup(), targetField, newItem); } } }); }); // 返回包含关闭方法的实例对象 return modalObj; } // 关闭当前弹窗并显示上一个 closeCurrentModal() { if (this.nestedModalStack.length > 0) { const currentModal = this.nestedModalStack.pop(); currentModal.hide(); // 如果有上一个弹窗,显示它 if (this.nestedModalStack.length > 0) { const prevModal = this.nestedModalStack[this.nestedModalStack.length - 1]; prevModal.show(); } } } // 获取表单数据 getFormData(container) { const formData = {}; container.find('input, select, textarea').each(function() { const $el = $(this); const name = $el.attr('name'); if (!name) return; if ($el.attr('type') === 'checkbox') { formData[name] = $el.is(':checked'); } else if ($el.attr('type') === 'radio') { if ($el.is(':checked')) { formData[name] = $el.val(); } } else { formData[name] = $el.val(); } }); return formData; } /** * 设置多个按钮的事件处理 * @param {Object} config - 配置对象 * @param {Function} onAddEntity - 添加实体的回调函数 */ setupMultiButtonHandlers(config, onAddEntity) { const popup = Swal.getPopup(); // 确保弹窗存在 if (!popup) { console.warn('弹窗不存在,无法绑定事件'); return; } // 移除旧的事件监听器(防止重复绑定) this.cleanupMultiButtonHandlers(); // 绑定所有添加按钮事件 this.addEntityButtons = Array.from(popup.querySelectorAll('.add-entity-btn')); this.addEntityButtons.forEach(btn => { const handler = async () => { const targetField = btn.dataset.targetField; const entityType = btn.dataset.entityType; if (onAddEntity) { const newItem = await onAddEntity(entityType, targetField); if (newItem) { this.updateSelectField(popup, targetField, newItem); } } }; btn.addEventListener('click', handler); // 保存处理器以便后续清理 this.buttonHandlers.set(btn, handler); }); } /** * 清理按钮事件处理器 */ cleanupMultiButtonHandlers() { if (this.addEntityButtons) { this.addEntityButtons.forEach(btn => { const handler = this.buttonHandlers.get(btn); if (handler) { btn.removeEventListener('click', handler); this.buttonHandlers.delete(btn); } }); this.addEntityButtons = null; } } /** * 更新下拉框选项 * @param {HTMLElement} popup - 弹窗元素 * @param {string} fieldName - 字段名 * @param {Object} newItem - 新选项 {value, label} */ updateSelectField(popup, fieldName, newItem) { // 确保弹窗仍然存在 if (!popup || !popup.isConnected) { console.warn('弹窗已关闭,无法更新字段'); return; } const select = popup.querySelector(select[name="${fieldName}"]); if (select) { // 添加新选项 const option = document.createElement('option'); option.value = newItem.value; option.textContent = newItem.label; option.selected = true; select.appendChild(option); // 如果使用Select2,刷新组件 if ($(select).hasClass('select2-hidden-accessible')) { $(select).trigger('change'); } } } } export default SweetalertSystem;

import rclpy from rclpy.node import Node from sensor_msgs.msg import CompressedImage from geometry_msgs.msg import Twist from cv_bridge import CvBridge import cv2 import numpy as np import time # 假设YoloNV12Inferencer类在test1_yolo_bin模块中 from test1_yolo_bin import YoloNV12Inferencer class LineAndObstacleNode(Node): def __init__(self): super().__init__('line_and_obstacle_node') self.bridge = CvBridge() self.subscription = self.create_subscription( CompressedImage, '/image', self.image_callback, 10) self.publisher_ = self.create_publisher(Twist, '/cmd_vel', 10) # YOLO 模型加载 try: self.inferencer = YoloNV12Inferencer('/root/dev_ws/3w/bin/yolov5s_672x672_nv12.bin') self.get_logger().info("✅ YOLO模型加载成功") except Exception as e: self.get_logger().error(f"YOLO加载失败: {e}") self.inferencer = None # 避障参数 self.focal_length = 550.0 self.image_cx = 320.0 self.target_height = 0.3 self.repulsion_range = 0.5 self.state = 'normal' # normal / avoiding_turn / avoiding_straight / realignment self.avoid_start_time = 0 self.obstacle_list = [] # 车道线检测参数 self.lost_lane_counter = 0 self.lost_lane_threshold = 5 self.current_frame = None self.last_valid_alpha = 0.0 # 状态超时参数 self.REALIGN_TIMEOUT = 1.5 # 回正阶段最大超时时间 self.AVOID_TURN_DURATION = 0.6 # 避障转向持续时间 self.timer = self.create_timer(0.1, self.control_loop) def image_callback(self, msg): try: img = self.bridge.compressed_imgmsg_to_cv2(msg, desired_encoding='bgr8') # 保存原始图像用于YOLO检测 self.raw_image = img.copy() # --- 巡线区域处理 --- h1, width = img.shape[:2] crop = img[int(h1 * 0.4):, :] self.current_frame = cv2.resize(crop, (160, 120)) # --- YOLO处理 --- if self.inferencer: detections = self.inferencer.infer(self.raw_image) self.obstacle_list = [] for class_id, score, (x1, y1, x2, y2) in detections: h = y2 - y1 if h <= 0: continue distance = (self.target_height * self.focal_length) / h cx = (x1 + x2) / 2 offset_y = (cx - self.image_cx) * distance / self.focal_length if class_id == 0: # 假设0是障碍物类别 self.obstacle_list.append((distance, offset_y)) except Exception as e: self.get_logger().error(f"图像处理错误: {e}") def detect_lane_line(self, frame): """检测车道线并返回速度、转向角和检测状态""" if frame is None: return 0.0, 0.0, False try: hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 黑色线条 HSV 阈值 lower_black = np.array([0, 0, 0]) upper_black = np.array([180, 255, 50]) black_mask = cv2.inRange(hsv, lower_black, upper_black) # 形态学操作增强检测 kernel = np.ones((5, 5), np.uint8) black_mask = cv2.morphologyEx(black_mask, cv2.MORPH_OPEN, kernel) black_mask = cv2.dilate(black_mask, kernel, iterations=2) # 检测区域高度 detection_band = 40 x_coords = np.where(black_mask[-detection_band:] == 255)[1] if len(x_coords) > 50: # 确保有足够的像素点 self.lost_lane_counter = 0 mean_x = np.mean(x_coords) h, w = frame.shape[:2] alpha = float(-(mean_x - w / 2) / (w / 2)) self.last_valid_alpha = alpha # 保存有效转向角 return 0.2, alpha, True else: self.lost_lane_counter += 1 if self.lost_lane_counter >= self.lost_lane_threshold: return 0.0, 0.0, False else: # 使用最后有效的转向角 return 0.10, self.last_valid_alpha, False except Exception as e: self.get_logger().error(f"车道线检测错误: {e}") return 0.0, 0.0, False def control_loop(self): now = time.time() elapsed_time = now - self.avoid_start_time # 障碍物检测(仅考虑前方0.5米内的障碍物) valid_obs = [o for o in self.obstacle_list if 0 < o[0] < self.repulsion_range and abs(o[1]) < 0.5] # 状态机实现 if self.state == 'avoiding_turn': # 右转避障阶段 if elapsed_time < self.AVOID_TURN_DURATION: self.publish_cmd(0.15, -0.8) # 右转避障 else: self.state = 'realignment' self.avoid_start_time = now self.get_logger().info("🔄 进入回正阶段") elif self.state == 'realignment': # 回正阶段(优先检测车道线) v, alpha, lane_detected = self.detect_lane_line(self.current_frame) if lane_detected: self.state = 'normal' self.get_logger().info("✅ 检测到车道线,恢复巡线") self.publish_cmd(v, alpha) elif elapsed_time > self.REALIGN_TIMEOUT: self.state = 'normal' self.get_logger().warn("⏱️ 回正超时,强制恢复巡线") else: # 缓慢直行并轻微右转寻找车道线 self.publish_cmd(0.1, -0.3) elif valid_obs and self.state == 'normal': # 检测到障碍物,开始避障. self.state = 'avoiding_turn' self.avoid_start_time = now self.get_logger().warn(f"🚧 检测到障碍物,距离={min(o[0] for o in valid_obs):.2f}m") else: # 正常巡线模式 v, alpha, lane_detected = self.detect_lane_line(self.current_frame) if lane_detected: self.publish_cmd(v, alpha) else: # 未检测到车道线时的安全策略 self.publish_cmd(0.05, self.last_valid_alpha) def publish_cmd(self, speed, steer): """发布控制指令,带平滑过渡""" msg = Twist() msg.linear.x = float(speed) msg.angular.z = float(steer) self.publisher_.publish(msg) def main(args=None): rclpy.init(args=args) node = LineAndObstacleNode() try: rclpy.spin(node) except KeyboardInterrupt: pass finally: node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() 在这个代码的基础上加

//---------------------------------------------- // NGUI: Next-Gen UI kit // Copyright © 2011-2015 Tasharen Entertainment //---------------------------------------------- using UnityEngine; using System; using System.Collections.Generic; using System.IO; using System.Reflection; /// /// Helper class containing generic functions used throughout the UI library. /// static public class NGUITools { static AudioListener mListener; static bool mLoaded = false; static float mGlobalVolume = 1f; /// /// Globally accessible volume affecting all sounds played via NGUITools.PlaySound(). /// static public float soundVolume { get { if (!mLoaded) { mLoaded = true; mGlobalVolume = PlayerPrefs.GetFloat("Sound", 1f); } return mGlobalVolume; } set { if (mGlobalVolume != value) { mLoaded = true; mGlobalVolume = value; PlayerPrefs.SetFloat("Sound", value); } } } /// /// Helper function -- whether the disk access is allowed. /// static public bool fileAccess { get { return Application.platform != RuntimePlatform.WindowsWebPlayer && Application.platform != RuntimePlatform.OSXWebPlayer; } } /// /// Play the specified audio clip. /// static public AudioSource PlaySound (AudioClip clip) { return PlaySound(clip, 1f, 1f); } /// /// Play the specified audio clip with the specified volume. /// static public AudioSource PlaySound (AudioClip clip, float volume) { return PlaySound(clip, volume, 1f); } static float mLastTimestamp = 0f; static AudioClip mLastClip; /// /// Play the specified audio clip with the specified volume and pitch. /// static public AudioSource PlaySound (AudioClip clip, float volume, float pitch) { float time = Time.time; if (mLastClip == clip && mLastTimestamp + 0.1f > time) return null; mLastClip = clip; mLastTimestamp = time; volume *= soundVolume; if (clip != null && volume > 0.01f) { if (mListener == null || !NGUITools.GetActive(mListener)) { AudioListener[] listeners = GameObject.FindObjectsOfType(typeof(AudioListener)) as AudioListener[]; if (listeners != null) { for (int i = 0; i < listeners.Length; ++i) { if (NGUITools.GetActive(listeners[i])) { mListener = listeners[i]; break; } } } if (mListener == null) { Camera cam = Camera.main; if (cam == null) cam = GameObject.FindObjectOfType(typeof(Camera)) as Camera; if (cam != null) mListener = cam.gameObject.AddComponent<AudioListener>(); } } if (mListener != null && mListener.enabled && NGUITools.GetActive(mListener.gameObject)) { #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 AudioSource source = mListener.audio; #else AudioSource source = mListener.GetComponent<AudioSource>(); #endif if (source == null) source = mListener.gameObject.AddComponent<AudioSource>(); #if !UNITY_FLASH source.priority = 50; source.pitch = pitch; #endif source.PlayOneShot(clip, volume); return source; } } return null; } /// /// New WWW call can fail if the crossdomain policy doesn't check out. Exceptions suck. It's much more elegant to check for null instead. /// // static public WWW OpenURL (string url) // { //#if UNITY_FLASH // Debug.LogError("WWW is not yet implemented in Flash"); // return null; //#else // WWW www = null; // try { www = new WWW(url); } // catch (System.Exception ex) { Debug.LogError(ex.Message); } // return www; //#endif // } // /// // /// New WWW call can fail if the crossdomain policy doesn't check out. Exceptions suck. It's much more elegant to check for null instead. // /// // static public WWW OpenURL (string url, WWWForm form) // { // if (form == null) return OpenURL(url); //#if UNITY_FLASH // Debug.LogError("WWW is not yet implemented in Flash"); // return null; //#else // WWW www = null; // try { www = new WWW(url, form); } // catch (System.Exception ex) { Debug.LogError(ex != null ? ex.Message : "<null>"); } // return www; //#endif // } /// /// Same as Random.Range, but the returned value is between min and max, inclusive. /// Unity's Random.Range is less than max instead, unless min == max. /// This means Range(0,1) produces 0 instead of 0 or 1. That's unacceptable. /// static public int RandomRange (int min, int max) { if (min == max) return min; return UnityEngine.Random.Range(min, max + 1); } /// /// Returns the hierarchy of the object in a human-readable format. /// static public string GetHierarchy (GameObject obj) { if (obj == null) return ""; string path = obj.name; while (obj.transform.parent != null) { obj = obj.transform.parent.gameObject; path = obj.name + "\\" + path; } return path; } /// /// Find all active objects of specified type. /// static public T[] FindActive<T> () where T : Component { return GameObject.FindObjectsOfType(typeof(T)) as T[]; } /// /// Find the camera responsible for drawing the objects on the specified layer. /// static public Camera FindCameraForLayer (int layer) { int layerMask = 1 << layer; Camera cam; for (int i = 0; i < UICamera.list.size; ++i) { cam = UICamera.list.buffer[i].cachedCamera; if (cam && (cam.cullingMask & layerMask) != 0) return cam; } cam = Camera.main; if (cam && (cam.cullingMask & layerMask) != 0) return cam; #if UNITY_4_3 || UNITY_FLASH Camera[] cameras = NGUITools.FindActive<Camera>(); for (int i = 0, imax = cameras.Length; i < imax; ++i) #else Camera[] cameras = new Camera[Camera.allCamerasCount]; int camerasFound = Camera.GetAllCameras(cameras); for (int i = 0; i < camerasFound; ++i) #endif { cam = cameras[i]; if (cam && cam.enabled && (cam.cullingMask & layerMask) != 0) return cam; } return null; } /// /// Add a collider to the game object containing one or more widgets. /// static public void AddWidgetCollider (GameObject go) { AddWidgetCollider(go, false); } /// /// Add a collider to the game object containing one or more widgets. /// static public void AddWidgetCollider (GameObject go, bool considerInactive) { if (go != null) { // 3D collider Collider col = go.GetComponent<Collider>(); BoxCollider box = col as BoxCollider; if (box != null) { UpdateWidgetCollider(box, considerInactive); return; } // Is there already another collider present? If so, do nothing. if (col != null) return; // 2D collider BoxCollider2D box2 = go.GetComponent<BoxCollider2D>(); if (box2 != null) { UpdateWidgetCollider(box2, considerInactive); return; } UICamera ui = UICamera.FindCameraForLayer(go.layer); if (ui != null && (ui.eventType == UICamera.EventType.World_2D || ui.eventType == UICamera.EventType.UI_2D)) { box2 = go.AddComponent<BoxCollider2D>(); box2.isTrigger = true; #if UNITY_EDITOR UnityEditor.Undo.RegisterCreatedObjectUndo(box2, "Add Collider"); #endif UIWidget widget = go.GetComponent<UIWidget>(); if (widget != null) widget.autoResizeBoxCollider = true; UpdateWidgetCollider(box2, considerInactive); return; } else { box = go.AddComponent<BoxCollider>(); #if UNITY_EDITOR UnityEditor.Undo.RegisterCreatedObjectUndo(box, "Add Collider"); #endif box.isTrigger = true; UIWidget widget = go.GetComponent<UIWidget>(); if (widget != null) widget.autoResizeBoxCollider = true; UpdateWidgetCollider(box, considerInactive); } } return; } /// /// Adjust the widget's collider based on the depth of the widgets, as well as the widget's dimensions. /// static public void UpdateWidgetCollider (GameObject go) { UpdateWidgetCollider(go, false); } /// /// Adjust the widget's collider based on the depth of the widgets, as well as the widget's dimensions. /// static public void UpdateWidgetCollider (GameObject go, bool considerInactive) { if (go != null) { BoxCollider bc = go.GetComponent<BoxCollider>(); if (bc != null) { UpdateWidgetCollider(bc, considerInactive); return; } BoxCollider2D box2 = go.GetComponent<BoxCollider2D>(); if (box2 != null) UpdateWidgetCollider(box2, considerInactive); } } /// /// Adjust the widget's collider based on the depth of the widgets, as well as the widget's dimensions. /// static public void UpdateWidgetCollider (BoxCollider box, bool considerInactive) { if (box != null) { GameObject go = box.gameObject; UIWidget w = go.GetComponent<UIWidget>(); if (w != null) { Vector4 dr = w.drawRegion; if (dr.x != 0f || dr.y != 0f || dr.z != 1f || dr.w != 1f) { Vector4 region = w.drawingDimensions; box.center = new Vector3((region.x + region.z) * 0.5f, (region.y + region.w) * 0.5f); box.size = new Vector3(region.z - region.x, region.w - region.y); } else { Vector3[] corners = w.localCorners; box.center = Vector3.Lerp(corners[0], corners[2], 0.5f); box.size = corners[2] - corners[0]; } } else { Bounds b = NGUIMath.CalculateRelativeWidgetBounds(go.transform, considerInactive); box.center = b.center; box.size = new Vector3(b.size.x, b.size.y, 0f); } #if UNITY_EDITOR NGUITools.SetDirty(box); #endif } } /// /// Adjust the widget's collider based on the depth of the widgets, as well as the widget's dimensions. /// static public void UpdateWidgetCollider (BoxCollider2D box, bool considerInactive) { if (box != null) { GameObject go = box.gameObject; UIWidget w = go.GetComponent<UIWidget>(); if (w != null) { Vector3[] corners = w.localCorners; #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 box.center = Vector3.Lerp(corners[0], corners[2], 0.5f); #else box.offset = Vector3.Lerp(corners[0], corners[2], 0.5f); #endif box.size = corners[2] - corners[0]; } else { Bounds b = NGUIMath.CalculateRelativeWidgetBounds(go.transform, considerInactive); #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 box.center = b.center; #else box.offset = b.center; #endif box.size = new Vector2(b.size.x, b.size.y); } #if UNITY_EDITOR NGUITools.SetDirty(box); #endif } } /// /// Helper function that returns the string name of the type. /// static public string GetTypeName<T> () { string s = typeof(T).ToString(); if (s.StartsWith("UI")) s = s.Substring(2); else if (s.StartsWith("UnityEngine.")) s = s.Substring(12); return s; } /// /// Helper function that returns the string name of the type. /// static public string GetTypeName (UnityEngine.Object obj) { if (obj == null) return "Null"; string s = obj.GetType().ToString(); if (s.StartsWith("UI")) s = s.Substring(2); else if (s.StartsWith("UnityEngine.")) s = s.Substring(12); return s; } /// /// Convenience method that works without warnings in both Unity 3 and 4. /// static public void RegisterUndo (UnityEngine.Object obj, string name) { #if UNITY_EDITOR UnityEditor.Undo.RecordObject(obj, name); NGUITools.SetDirty(obj); #endif } /// /// Convenience function that marks the specified object as dirty in the Unity Editor. /// static public void SetDirty (UnityEngine.Object obj) { #if UNITY_EDITOR if (obj) { //if (obj is Component) Debug.Log(NGUITools.GetHierarchy((obj as Component).gameObject), obj); //else if (obj is GameObject) Debug.Log(NGUITools.GetHierarchy(obj as GameObject), obj); //else Debug.Log("Hmm... " + obj.GetType(), obj); UnityEditor.EditorUtility.SetDirty(obj); } #endif } /// /// Add a new child game object. /// static public GameObject AddChild (GameObject parent) { return AddChild(parent, true); } /// /// Add a new child game object. /// static public GameObject AddChild (GameObject parent, bool undo) { GameObject go = new GameObject(); #if UNITY_EDITOR if (undo) UnityEditor.Undo.RegisterCreatedObjectUndo(go, "Create Object"); #endif if (parent != null) { Transform t = go.transform; t.parent = parent.transform; t.localPosition = Vector3.zero; t.localRotation = Quaternion.identity; t.localScale = Vector3.one; go.layer = parent.layer; } return go; } /// /// Instantiate an object and add it to the specified parent. /// static public GameObject AddChild (GameObject parent, GameObject prefab) { GameObject go = GameObject.Instantiate(prefab) as GameObject; #if UNITY_EDITOR UnityEditor.Undo.RegisterCreatedObjectUndo(go, "Create Object"); #endif if (go != null && parent != null) { Transform t = go.transform; t.parent = parent.transform; t.localPosition = Vector3.zero; t.localRotation = Quaternion.identity; t.localScale = Vector3.one; go.layer = parent.layer; } return go; } /// /// Calculate the game object's depth based on the widgets within, and also taking panel depth into consideration. /// static public int CalculateRaycastDepth (GameObject go) { UIWidget w = go.GetComponent<UIWidget>(); if (w != null) return w.raycastDepth; UIWidget[] widgets = go.GetComponentsInChildren<UIWidget>(); if (widgets.Length == 0) return 0; int depth = int.MaxValue; for (int i = 0, imax = widgets.Length; i < imax; ++i) { if (widgets[i].enabled) depth = Mathf.Min(depth, widgets[i].raycastDepth); } return depth; } /// /// Gathers all widgets and calculates the depth for the next widget. /// static public int CalculateNextDepth (GameObject go) { int depth = -1; UIWidget[] widgets = go.GetComponentsInChildren<UIWidget>(); for (int i = 0, imax = widgets.Length; i < imax; ++i) depth = Mathf.Max(depth, widgets[i].depth); return depth + 1; } /// /// Gathers all widgets and calculates the depth for the next widget. /// static public int CalculateNextDepth (GameObject go, bool ignoreChildrenWithColliders) { if (ignoreChildrenWithColliders) { int depth = -1; UIWidget[] widgets = go.GetComponentsInChildren<UIWidget>(); for (int i = 0, imax = widgets.Length; i < imax; ++i) { UIWidget w = widgets[i]; #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 if (w.cachedGameObject != go && (w.collider != null || w.GetComponent<Collider2D>() != null)) continue; #else if (w.cachedGameObject != go && (w.GetComponent<Collider>() != null || w.GetComponent<Collider2D>() != null)) continue; #endif depth = Mathf.Max(depth, w.depth); } return depth + 1; } return CalculateNextDepth(go); } /// /// Adjust the widgets' depth by the specified value. /// Returns '0' if nothing was adjusted, '1' if panels were adjusted, and '2' if widgets were adjusted. /// static public int AdjustDepth (GameObject go, int adjustment) { if (go != null) { UIPanel panel = go.GetComponent<UIPanel>(); if (panel != null) { UIPanel[] panels = go.GetComponentsInChildren<UIPanel>(true); for (int i = 0; i < panels.Length; ++i) { UIPanel p = panels[i]; #if UNITY_EDITOR RegisterUndo(p, "Depth Change"); #endif p.depth = p.depth + adjustment; } return 1; } else { panel = FindInParents<UIPanel>(go); if (panel == null) return 0; UIWidget[] widgets = go.GetComponentsInChildren<UIWidget>(true); for (int i = 0, imax = widgets.Length; i < imax; ++i) { UIWidget w = widgets[i]; if (w.panel != panel) continue; #if UNITY_EDITOR RegisterUndo(w, "Depth Change"); #endif w.depth = w.depth + adjustment; } return 2; } } return 0; } /// /// Bring all of the widgets on the specified object forward. /// static public void BringForward (GameObject go) { int val = AdjustDepth(go, 1000); if (val == 1) NormalizePanelDepths(); else if (val == 2) NormalizeWidgetDepths(); } /// /// Push all of the widgets on the specified object back, making them appear behind everything else. /// static public void PushBack (GameObject go) { int val = AdjustDepth(go, -1000); if (val == 1) NormalizePanelDepths(); else if (val == 2) NormalizeWidgetDepths(); } /// /// Normalize the depths of all the widgets and panels in the scene, making them start from 0 and remain in order. /// static public void NormalizeDepths () { NormalizeWidgetDepths(); NormalizePanelDepths(); } /// /// Normalize the depths of all the widgets in the scene, making them start from 0 and remain in order. /// static public void NormalizeWidgetDepths () { NormalizeWidgetDepths(FindActive<UIWidget>()); } /// /// Normalize the depths of all the widgets in the scene, making them start from 0 and remain in order. /// static public void NormalizeWidgetDepths (GameObject go) { NormalizeWidgetDepths(go.GetComponentsInChildren<UIWidget>()); } /// /// Normalize the depths of all the widgets in the scene, making them start from 0 and remain in order. /// static public void NormalizeWidgetDepths (UIWidget[] list) { int size = list.Length; if (size > 0) { Array.Sort(list, UIWidget.FullCompareFunc); int start = 0; int current = list[0].depth; for (int i = 0; i < size; ++i) { UIWidget w = list[i]; if (w.depth == current) { w.depth = start; } else { current = w.depth; w.depth = ++start; } } } } /// /// Normalize the depths of all the panels in the scene, making them start from 0 and remain in order. /// static public void NormalizePanelDepths () { UIPanel[] list = FindActive<UIPanel>(); int size = list.Length; if (size > 0) { Array.Sort(list, UIPanel.CompareFunc); int start = 0; int current = list[0].depth; for (int i = 0; i < size; ++i) { UIPanel p = list[i]; if (p.depth == current) { p.depth = start; } else { current = p.depth; p.depth = ++start; } } } } /// /// Create a new UI. /// static public UIPanel CreateUI (bool advanced3D) { return CreateUI(null, advanced3D, -1); } /// /// Create a new UI. /// static public UIPanel CreateUI (bool advanced3D, int layer) { return CreateUI(null, advanced3D, layer); } /// /// Create a new UI. /// static public UIPanel CreateUI (Transform trans, bool advanced3D, int layer) { // Find the existing UI Root UIRoot root = (trans != null) ? NGUITools.FindInParents<UIRoot>(trans.gameObject) : null; if (root == null && UIRoot.list.Count > 0) { foreach (UIRoot r in UIRoot.list) { if (r.gameObject.layer == layer) { root = r; break; } } } // Try to find an existing panel if (root == null) { for (int i = 0, imax = UIPanel.list.Count; i < imax; ++i) { UIPanel p = UIPanel.list[i]; GameObject go = p.gameObject; if (go.hideFlags == HideFlags.None && go.layer == layer) { trans.parent = p.transform; trans.localScale = Vector3.one; return p; } } } // If we are working with a different UI type, we need to treat it as a brand-new one instead if (root != null) { UICamera cam = root.GetComponentInChildren<UICamera>(); #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 if (cam != null && cam.camera.isOrthoGraphic == advanced3D) #else if (cam != null && cam.GetComponent<Camera>().orthographic == advanced3D) #endif { trans = null; root = null; } } // If no root found, create one if (root == null) { GameObject go = NGUITools.AddChild(null, false); root = go.AddComponent<UIRoot>(); // Automatically find the layers if none were specified if (layer == -1) layer = LayerMask.NameToLayer("UI"); if (layer == -1) layer = LayerMask.NameToLayer("2D UI"); go.layer = layer; if (advanced3D) { go.name = "UI Root (3D)"; root.scalingStyle = UIRoot.Scaling.Constrained; } else { go.name = "UI Root"; root.scalingStyle = UIRoot.Scaling.Flexible; } } // Find the first panel UIPanel panel = root.GetComponentInChildren<UIPanel>(); if (panel == null) { // Find other active cameras in the scene Camera[] cameras = NGUITools.FindActive<Camera>(); float depth = -1f; bool colorCleared = false; int mask = (1 << root.gameObject.layer); for (int i = 0; i < cameras.Length; ++i) { Camera c = cameras[i]; // If the color is being cleared, we won't need to if (c.clearFlags == CameraClearFlags.Color || c.clearFlags == CameraClearFlags.Skybox) colorCleared = true; // Choose the maximum depth depth = Mathf.Max(depth, c.depth); // Make sure this camera can't see the UI c.cullingMask = (c.cullingMask & (~mask)); } // Create a camera that will draw the UI Camera cam = NGUITools.AddChild<Camera>(root.gameObject, false); cam.gameObject.AddComponent<UICamera>(); cam.clearFlags = colorCleared ? CameraClearFlags.Depth : CameraClearFlags.Color; cam.backgroundColor = Color.grey; cam.cullingMask = mask; cam.depth = depth + 1f; if (advanced3D) { cam.nearClipPlane = 0.1f; cam.farClipPlane = 4f; cam.transform.localPosition = new Vector3(0f, 0f, -700f); } else { cam.orthographic = true; cam.orthographicSize = 1; cam.nearClipPlane = -10; cam.farClipPlane = 10; } // Make sure there is an audio listener present AudioListener[] listeners = NGUITools.FindActive<AudioListener>(); if (listeners == null || listeners.Length == 0) cam.gameObject.AddComponent<AudioListener>(); // Add a panel to the root panel = root.gameObject.AddComponent<UIPanel>(); #if UNITY_EDITOR UnityEditor.Selection.activeGameObject = panel.gameObject; #endif } if (trans != null) { // Find the root object while (trans.parent != null) trans = trans.parent; if (NGUITools.IsChild(trans, panel.transform)) { // Odd hierarchy -- can't reparent panel = trans.gameObject.AddComponent<UIPanel>(); } else { // Reparent this root object to be a child of the panel trans.parent = panel.transform; trans.localScale = Vector3.one; trans.localPosition = Vector3.zero; SetChildLayer(panel.cachedTransform, panel.cachedGameObject.layer); } } return panel; } /// /// Helper function that recursively sets all children with widgets' game objects layers to the specified value. /// static public void SetChildLayer (Transform t, int layer) { for (int i = 0; i < t.childCount; ++i) { Transform child = t.GetChild(i); child.gameObject.layer = layer; SetChildLayer(child, layer); } } /// /// Add a child object to the specified parent and attaches the specified script to it. /// static public T AddChild<T> (GameObject parent) where T : Component { GameObject go = AddChild(parent); go.name = GetTypeName<T>(); return go.AddComponent<T>(); } /// /// Add a child object to the specified parent and attaches the specified script to it. /// static public T AddChild<T> (GameObject parent, bool undo) where T : Component { GameObject go = AddChild(parent, undo); go.name = GetTypeName<T>(); return go.AddComponent<T>(); } /// /// Add a new widget of specified type. /// static public T AddWidget<T> (GameObject go) where T : UIWidget { int depth = CalculateNextDepth(go); // Create the widget and place it above other widgets T widget = AddChild<T>(go); widget.width = 100; widget.height = 100; widget.depth = depth; return widget; } /// /// Add a new widget of specified type. /// static public T AddWidget<T> (GameObject go, int depth) where T : UIWidget { // Create the widget and place it above other widgets T widget = AddChild<T>(go); widget.width = 100; widget.height = 100; widget.depth = depth; return widget; } /// /// Add a sprite appropriate for the specified atlas sprite. /// It will be sliced if the sprite has an inner rect, and a regular sprite otherwise. /// static public UISprite AddSprite (GameObject go, UIAtlas atlas, string spriteName) { UISpriteData sp = (atlas != null) ? atlas.GetSprite(spriteName) : null; UISprite sprite = AddWidget<UISprite>(go); sprite.type = (sp == null || !sp.hasBorder) ? UISprite.Type.Simple : UISprite.Type.Sliced; sprite.atlas = atlas; sprite.spriteName = spriteName; return sprite; } /// /// Get the rootmost object of the specified game object. /// static public GameObject GetRoot (GameObject go) { Transform t = go.transform; for (; ; ) { Transform parent = t.parent; if (parent == null) break; t = parent; } return t.gameObject; } /// /// Finds the specified component on the game object or one of its parents. /// static public T FindInParents<T> (GameObject go) where T : Component { if (go == null) return null; // Commented out because apparently it causes Unity 4.5.3 to lag horribly: // http://www.tasharen.com/forum/index.php?topic=10882.0 //#if UNITY_4_3 #if UNITY_FLASH object comp = go.GetComponent<T>(); #else T comp = go.GetComponent<T>(); #endif if (comp == null) { Transform t = go.transform.parent; while (t != null && comp == null) { comp = t.gameObject.GetComponent<T>(); t = t.parent; } } #if UNITY_FLASH return (T)comp; #else return comp; #endif //#else // return go.GetComponentInParent<T>(); //#endif } /// /// Finds the specified component on the game object or one of its parents. /// static public T FindInParents<T> (Transform trans) where T : Component { if (trans == null) return null; #if UNITY_4_3 #if UNITY_FLASH object comp = trans.GetComponent<T>(); #else T comp = trans.GetComponent<T>(); #endif if (comp == null) { Transform t = trans.transform.parent; while (t != null && comp == null) { comp = t.gameObject.GetComponent<T>(); t = t.parent; } } #if UNITY_FLASH return (T)comp; #else return comp; #endif #else return trans.GetComponentInParent<T>(); #endif } /// /// Destroy the specified object, immediately if in edit mode. /// static public void Destroy (UnityEngine.Object obj) { if (obj != null) { if (obj is Transform) obj = (obj as Transform).gameObject; if (Application.isPlaying) { if (obj is GameObject) { GameObject go = obj as GameObject; go.transform.parent = null; } UnityEngine.Object.Destroy(obj); } else UnityEngine.Object.DestroyImmediate(obj); } } /// /// Destroy the specified object immediately, unless not in the editor, in which case the regular Destroy is used instead. /// static public void DestroyImmediate (UnityEngine.Object obj) { if (obj != null) { if (Application.isEditor) UnityEngine.Object.DestroyImmediate(obj); else UnityEngine.Object.Destroy(obj); } } /// /// Call the specified function on all objects in the scene. /// static public void Broadcast (string funcName) { GameObject[] gos = GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[]; for (int i = 0, imax = gos.Length; i < imax; ++i) gos[i].SendMessage(funcName, SendMessageOptions.DontRequireReceiver); } /// /// Call the specified function on all objects in the scene. /// static public void Broadcast (string funcName, object param) { GameObject[] gos = GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[]; for (int i = 0, imax = gos.Length; i < imax; ++i) gos[i].SendMessage(funcName, param, SendMessageOptions.DontRequireReceiver); } /// /// Determines whether the 'parent' contains a 'child' in its hierarchy. /// static public bool IsChild (Transform parent, Transform child) { if (parent == null || child == null) return false; while (child != null) { if (child == parent) return true; child = child.parent; } return false; } /// /// Activate the specified object and all of its children. /// static void Activate (Transform t) { Activate(t, false); } /// /// Activate the specified object and all of its children. /// static void Activate (Transform t, bool compatibilityMode) { SetActiveSelf(t.gameObject, true); if (compatibilityMode) { // If there is even a single enabled child, then we're using a Unity 4.0-based nested active state scheme. for (int i = 0, imax = t.childCount; i < imax; ++i) { Transform child = t.GetChild(i); if (child.gameObject.activeSelf) return; } // If this point is reached, then all the children are disabled, so we must be using a Unity 3.5-based active state scheme. for (int i = 0, imax = t.childCount; i < imax; ++i) { Transform child = t.GetChild(i); Activate(child, true); } } } /// /// Deactivate the specified object and all of its children. /// static void Deactivate (Transform t) { SetActiveSelf(t.gameObject, false); } /// /// SetActiveRecursively enables children before parents. This is a problem when a widget gets re-enabled /// and it tries to find a panel on its parent. /// static public void SetActive (GameObject go, bool state) { SetActive(go, state, true); } /// /// SetActiveRecursively enables children before parents. This is a problem when a widget gets re-enabled /// and it tries to find a panel on its parent. /// static public void SetActive (GameObject go, bool state, bool compatibilityMode) { if (go) { if (state) { Activate(go.transform, compatibilityMode); #if UNITY_EDITOR if (Application.isPlaying) #endif CallCreatePanel(go.transform); } else Deactivate(go.transform); } } /// /// Ensure that all widgets have had their panels created, forcing the update right away rather than on the following frame. /// [System.Diagnostics.DebuggerHidden] [System.Diagnostics.DebuggerStepThrough] static void CallCreatePanel (Transform t) { UIWidget w = t.GetComponent<UIWidget>(); if (w != null) w.CreatePanel(); for (int i = 0, imax = t.childCount; i < imax; ++i) CallCreatePanel(t.GetChild(i)); } /// /// Activate or deactivate children of the specified game object without changing the active state of the object itself. /// static public void SetActiveChildren (GameObject go, bool state) { Transform t = go.transform; if (state) { for (int i = 0, imax = t.childCount; i < imax; ++i) { Transform child = t.GetChild(i); Activate(child); } } else { for (int i = 0, imax = t.childCount; i < imax; ++i) { Transform child = t.GetChild(i); Deactivate(child); } } } /// /// Helper function that returns whether the specified MonoBehaviour is active. /// [System.Obsolete("Use NGUITools.GetActive instead")] static public bool IsActive (Behaviour mb) { return mb != null && mb.enabled && mb.gameObject.activeInHierarchy; } /// /// Helper function that returns whether the specified MonoBehaviour is active. /// [System.Diagnostics.DebuggerHidden] [System.Diagnostics.DebuggerStepThrough] static public bool GetActive (Behaviour mb) { return mb && mb.enabled && mb.gameObject.activeInHierarchy; } /// /// Unity4 has changed GameObject.active to GameObject.activeself. /// [System.Diagnostics.DebuggerHidden] [System.Diagnostics.DebuggerStepThrough] static public bool GetActive (GameObject go) { return go && go.activeInHierarchy; } /// /// Unity4 has changed GameObject.active to GameObject.SetActive. /// [System.Diagnostics.DebuggerHidden] [System.Diagnostics.DebuggerStepThrough] static public void SetActiveSelf (GameObject go, bool state) { go.SetActive(state); } /// /// Recursively set the game object's layer. /// static public void SetLayer (GameObject go, int layer) { go.layer = layer; Transform t = go.transform; for (int i = 0, imax = t.childCount; i < imax; ++i) { Transform child = t.GetChild(i); SetLayer(child.gameObject, layer); } } /// /// Helper function used to make the vector use integer numbers. /// static public Vector3 Round (Vector3 v) { v.x = Mathf.Round(v.x); v.y = Mathf.Round(v.y); v.z = Mathf.Round(v.z); return v; } /// /// Make the specified selection pixel-perfect. /// static public void MakePixelPerfect (Transform t) { UIWidget w = t.GetComponent<UIWidget>(); if (w != null) w.MakePixelPerfect(); if (t.GetComponent<UIAnchor>() == null && t.GetComponent<UIRoot>() == null) { #if UNITY_EDITOR RegisterUndo(t, "Make Pixel-Perfect"); #endif t.localPosition = Round(t.localPosition); t.localScale = Round(t.localScale); } // Recurse into children for (int i = 0, imax = t.childCount; i < imax; ++i) MakePixelPerfect(t.GetChild(i)); } /// /// Save the specified binary data into the specified file. /// static public bool Save (string fileName, byte[] bytes) { #if UNITY_WEBPLAYER || UNITY_FLASH || UNITY_METRO || UNITY_WP8 || UNITY_WP_8_1 return false; #else if (!NGUITools.fileAccess) return false; string path = ""; if (bytes == null) { if (File.Exists(path)) File.Delete(path); return true; } FileStream file = null; try { file = File.Create(path); } catch (System.Exception ex) { Debug.LogError(ex.Message); return false; } file.Write(bytes, 0, bytes.Length); file.Close(); return true; #endif } /// /// Load all binary data from the specified file. /// static public byte[] Load (string fileName) { #if UNITY_WEBPLAYER || UNITY_FLASH || UNITY_METRO || UNITY_WP8 || UNITY_WP_8_1 return null; #else if (!NGUITools.fileAccess) return null; string path = ""; if (File.Exists(path)) { return File.ReadAllBytes(path); } return null; #endif } /// /// Pre-multiply shaders result in a black outline if this operation is done in the shader. It's better to do it outside. /// static public Color ApplyPMA (Color c) { if (c.a != 1f) { c.r *= c.a; c.g *= c.a; c.b *= c.a; } return c; } /// /// Inform all widgets underneath the specified object that the parent has changed. /// static public void MarkParentAsChanged (GameObject go) { UIRect[] rects = go.GetComponentsInChildren<UIRect>(); for (int i = 0, imax = rects.Length; i < imax; ++i) rects[i].ParentHasChanged(); } /// /// Access to the clipboard via undocumented APIs. /// static public string clipboard { get { TextEditor te = new TextEditor(); te.Paste(); return te.content.text; } set { TextEditor te = new TextEditor(); te.content = new GUIContent(value); te.OnFocus(); te.Copy(); } } [System.Obsolete("Use NGUIText.EncodeColor instead")] static public string EncodeColor (Color c) { return NGUIText.EncodeColor24(c); } [System.Obsolete("Use NGUIText.ParseColor instead")] static public Color ParseColor (string text, int offset) { return NGUIText.ParseColor24(text, offset); } [System.Obsolete("Use NGUIText.StripSymbols instead")] static public string StripSymbols (string text) { return NGUIText.StripSymbols(text); } /// /// Extension for the game object that checks to see if the component already exists before adding a new one. /// If the component is already present it will be returned instead. /// static public T AddMissingComponent<T> (this GameObject go) where T : Component { #if UNITY_FLASH object comp = go.GetComponent<T>(); #else T comp = go.GetComponent<T>(); #endif if (comp == null) { #if UNITY_EDITOR if (!Application.isPlaying) RegisterUndo(go, "Add " + typeof(T)); #endif comp = go.AddComponent<T>(); } #if UNITY_FLASH return (T)comp; #else return comp; #endif } // Temporary variable to avoid GC allocation static Vector3[] mSides = new Vector3[4]; /// /// Get sides relative to the specified camera. The order is left, top, right, bottom. /// static public Vector3[] GetSides (this Camera cam) { return cam.GetSides(Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f), null); } /// /// Get sides relative to the specified camera. The order is left, top, right, bottom. /// static public Vector3[] GetSides (this Camera cam, float depth) { return cam.GetSides(depth, null); } /// /// Get sides relative to the specified camera. The order is left, top, right, bottom. /// static public Vector3[] GetSides (this Camera cam, Transform relativeTo) { return cam.GetSides(Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f), relativeTo); } /// /// Get sides relative to the specified camera. The order is left, top, right, bottom. /// static public Vector3[] GetSides (this Camera cam, float depth, Transform relativeTo) { #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 if (cam.isOrthoGraphic) #else if (cam.orthographic) #endif { float os = cam.orthographicSize; float x0 = -os; float x1 = os; float y0 = -os; float y1 = os; Rect rect = cam.rect; Vector2 size = screenSize; float aspect = size.x / size.y; aspect *= rect.width / rect.height; x0 *= aspect; x1 *= aspect; // We want to ignore the scale, as scale doesn't affect the camera's view region in Unity Transform t = cam.transform; Quaternion rot = t.rotation; Vector3 pos = t.position; int w = Mathf.RoundToInt(size.x); int h = Mathf.RoundToInt(size.y); if ((w & 1) == 1) pos.x -= 1f / size.x; if ((h & 1) == 1) pos.y += 1f / size.y; mSides[0] = rot * (new Vector3(x0, 0f, depth)) + pos; mSides[1] = rot * (new Vector3(0f, y1, depth)) + pos; mSides[2] = rot * (new Vector3(x1, 0f, depth)) + pos; mSides[3] = rot * (new Vector3(0f, y0, depth)) + pos; } else { mSides[0] = cam.ViewportToWorldPoint(new Vector3(0f, 0.5f, depth)); mSides[1] = cam.ViewportToWorldPoint(new Vector3(0.5f, 1f, depth)); mSides[2] = cam.ViewportToWorldPoint(new Vector3(1f, 0.5f, depth)); mSides[3] = cam.ViewportToWorldPoint(new Vector3(0.5f, 0f, depth)); } if (relativeTo != null) { for (int i = 0; i < 4; ++i) mSides[i] = relativeTo.InverseTransformPoint(mSides[i]); } return mSides; } /// /// Get the camera's world-space corners. The order is bottom-left, top-left, top-right, bottom-right. /// static public Vector3[] GetWorldCorners (this Camera cam) { float depth = Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f); return cam.GetWorldCorners(depth, null); } /// /// Get the camera's world-space corners. The order is bottom-left, top-left, top-right, bottom-right. /// static public Vector3[] GetWorldCorners (this Camera cam, float depth) { return cam.GetWorldCorners(depth, null); } /// /// Get the camera's world-space corners. The order is bottom-left, top-left, top-right, bottom-right. /// static public Vector3[] GetWorldCorners (this Camera cam, Transform relativeTo) { return cam.GetWorldCorners(Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f), relativeTo); } /// /// Get the camera's world-space corners. The order is bottom-left, top-left, top-right, bottom-right. /// static public Vector3[] GetWorldCorners (this Camera cam, float depth, Transform relativeTo) { #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 if (cam.isOrthoGraphic) #else if (cam.orthographic) #endif { float os = cam.orthographicSize; float x0 = -os; float x1 = os; float y0 = -os; float y1 = os; Rect rect = cam.rect; Vector2 size = screenSize; float aspect = size.x / size.y; aspect *= rect.width / rect.height; x0 *= aspect; x1 *= aspect; // We want to ignore the scale, as scale doesn't affect the camera's view region in Unity Transform t = cam.transform; Quaternion rot = t.rotation; Vector3 pos = t.position; mSides[0] = rot * (new Vector3(x0, y0, depth)) + pos; mSides[1] = rot * (new Vector3(x0, y1, depth)) + pos; mSides[2] = rot * (new Vector3(x1, y1, depth)) + pos; mSides[3] = rot * (new Vector3(x1, y0, depth)) + pos; } else { mSides[0] = cam.ViewportToWorldPoint(new Vector3(0f, 0f, depth)); mSides[1] = cam.ViewportToWorldPoint(new Vector3(0f, 1f, depth)); mSides[2] = cam.ViewportToWorldPoint(new Vector3(1f, 1f, depth)); mSides[3] = cam.ViewportToWorldPoint(new Vector3(1f, 0f, depth)); } if (relativeTo != null) { for (int i = 0; i < 4; ++i) mSides[i] = relativeTo.InverseTransformPoint(mSides[i]); } return mSides; } /// /// Convenience function that converts Class + Function combo into Class.Function representation. /// static public string GetFuncName (object obj, string method) { if (obj == null) return "<null>"; string type = obj.GetType().ToString(); int period = type.LastIndexOf('/'); if (period > 0) type = type.Substring(period + 1); return string.IsNullOrEmpty(method) ? type : type + "/" + method; } #if UNITY_EDITOR || !UNITY_FLASH /// /// Execute the specified function on the target game object. /// static public void Execute<T> (GameObject go, string funcName) where T : Component { T[] comps = go.GetComponents<T>(); foreach (T comp in comps) { #if !UNITY_EDITOR && (UNITY_WEBPLAYER || UNITY_FLASH || UNITY_METRO || UNITY_WP8 || UNITY_WP_8_1) comp.SendMessage(funcName, SendMessageOptions.DontRequireReceiver); #else MethodInfo method = comp.GetType().GetMethod(funcName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) method.Invoke(comp, null); #endif } } /// /// Execute the specified function on the target game object and all of its children. /// static public void ExecuteAll<T> (GameObject root, string funcName) where T : Component { Execute<T>(root, funcName); Transform t = root.transform; for (int i = 0, imax = t.childCount; i < imax; ++i) ExecuteAll<T>(t.GetChild(i).gameObject, funcName); } /// /// Immediately start, update, and create all the draw calls from newly instantiated UI. /// This is useful if you plan on doing something like immediately taking a screenshot then destroying the UI. /// static public void ImmediatelyCreateDrawCalls (GameObject root) { ExecuteAll<UIWidget>(root, "Start"); ExecuteAll<UIPanel>(root, "Start"); ExecuteAll<UIWidget>(root, "Update"); ExecuteAll<UIPanel>(root, "Update"); ExecuteAll<UIPanel>(root, "LateUpdate"); } #endif #if UNITY_EDITOR static int mSizeFrame = -1; static System.Reflection.MethodInfo s_GetSizeOfMainGameView; static Vector2 mGameSize = Vector2.one; /// /// Size of the game view cannot be retrieved from Screen.width and Screen.height when the game view is hidden. /// static public Vector2 screenSize { get { int frame = Time.frameCount; if (mSizeFrame != frame || !Application.isPlaying) { mSizeFrame = frame; if (s_GetSizeOfMainGameView == null) { System.Type type = System.Type.GetType("UnityEditor.GameView,UnityEditor"); s_GetSizeOfMainGameView = type.GetMethod("GetSizeOfMainGameView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); } mGameSize = (Vector2)s_GetSizeOfMainGameView.Invoke(null, null); } return mGameSize; } } #else /// /// Size of the game view cannot be retrieved from Screen.width and Screen.height when the game view is hidden. /// static public Vector2 screenSize { get { return new Vector2(Screen.width, Screen.height); } } #endif } Assets/NGUI/Scripts/Internal/NGUITools.cs(57,51): error CS0619: UnityEngine.RuntimePlatform.WindowsWebPlayer' is obsolete: WebPlayer export is no longer supported in Unity 5.4+.'

大家在看

recommend-type

台大李宏毅机器学习课件

台大李宏毅老师机器学习课程课件,全部ppt,官网下载整理
recommend-type

WF5803-WF100D系列通用驱动

WF5803/WF100D驱动代码及资料,包含IIC、三线SPI、四线SPI驱动代码
recommend-type

微调垂直领域的模型,直接提取ocr识别后的字段信息.zip

个人深耕AI大模型应用领域积累的成果,希望对您有所帮助。有大模型账号、环境问题、AI大模型技术应用落地方案等相关问题,欢迎详聊,能为您解决问题是我的荣幸! 个人深耕AI大模型应用领域积累的成果,希望对您有所帮助。有大模型账号、环境问题、AI大模型技术应用落地方案等相关问题,欢迎详聊,能为您解决问题是我的荣幸! 个人深耕AI大模型应用领域积累的成果,希望对您有所帮助。有大模型账号、环境问题、AI大模型技术应用落地方案等相关问题,欢迎详聊,能为您解决问题是我的荣幸! 个人深耕AI大模型应用领域积累的成果,希望对您有所帮助。有大模型账号、环境问题、AI大模型技术应用落地方案等相关问题,欢迎详聊,能为您解决问题是我的荣幸! 个人深耕AI大模型应用领域积累的成果,希望对您有所帮助。有大模型账号、环境问题、AI大模型技术应用落地方案等相关问题,欢迎详聊,能为您解决问题是我的荣幸! 个人深耕AI大模型应用领域积累的成果,希望对您有所帮助。有大模型账号、环境问题、AI大模型技术应用落地方案等相关问题,欢迎详聊,能为您解决问题是我的荣幸!
recommend-type

智能空调遥控器调试软件

实现普通空调的智能管理,红外学习功能软件
recommend-type

MATLAB在振动信号处理中的应用

MATLAB在振动信号处理中的应用,对振动试验和振动测试所获得的数据进行加工。

最新推荐

recommend-type

项目材料、分包、项目经理比选管理流程.docx

项目材料、分包、项目经理比选管理流程.docx
recommend-type

该项目是基于JavaWeb开发的网上商城购物系统,主要实现了购物车、结算和订单管理的功能,适合Java Web初学者学习使用 (该项目还处于完善阶段,今后会不定时进行更新)

资源下载链接为: https://pan.quark.cn/s/a3bd6adf8f4f 该项目是基于JavaWeb开发的网上商城购物系统,主要实现了购物车、结算和订单管理的功能,适合Java Web初学者学习使用。(该项目还处于完善阶段,今后会不定时进行更新)(最新、最全版本!打开链接下载即可用!)
recommend-type

实验室的极化码编码译码仿真程序,在BSC、BEC、AWGN信道条件下都有仿真

实验室的极化码编码译码仿真程序,在BSC、BEC、AWGN信道条件下都有。使用密度进化法和巴氏参数估计信道,仿真性能非常好。 在Matlab下应用非常方便,支持多组仿真。配有应用说明,非常好用。希望能给大家带来帮助。
recommend-type

Blu-ray.vbs工具 可以补全蓝光ISO缺失目录

Blu-ray.vbs可以检测蓝光目录的完整性,并自动补全
recommend-type

新版旁站监理记录表.doc

新版旁站监理记录表.doc
recommend-type

解决无法获取网络图片问题,提供PNG素材下载

根据提供的文件信息,我们可以确定知识点主要集中在网络图片获取、素材下载以及特定格式PNG图片的使用和命名规则上。 首先,我们来探讨“无法获取网络图片”这一问题。在互联网环境中,获取网络图片的过程通常涉及几个关键技术点:HTTP/HTTPS协议、网络请求处理、图片资源的定位与下载、以及浏览器或者应用程序对图片的缓存和处理。在这一过程中可能会遇到的问题有网络连接问题、目标服务器配置错误、资源访问权限受限、图片资源不存在或已被移除、跨域访问限制(CORS)、以及客户端代码错误等。 对于“素材下载 PNG素材 网页素材”,我们需要了解PNG图片的特性以及素材下载的相关技术。PNG(Portable Network Graphics)是一种无损数据压缩的位图图形格式,它支持索引、灰度、RGB三种颜色模式以及alpha通道透明度。PNG格式广泛用于网络图片下载,因为它提供了优秀的压缩性能且没有版权限制。在网页设计中,PNG图片因其高保真的特性,可以作为网页背景、图标和按钮的素材。素材下载通常是设计师或者开发人员通过搜索引擎、专门的素材网站或者内容分发网络(CDN)来获取所需的图片、音频、视频等资源。 紧接着,“无法获取网络图片”这一标签指向了一个普遍的技术问题,即客户端在尝试从互联网上下载图片资源时遭遇的失败。这可能发生在使用Web浏览器、桌面应用程序、移动应用或者任何其它形式的客户端软件上。问题的原因可能包括客户端网络设置问题、防火墙限制、代理服务器配置、DNS解析错误等。 最后,观察压缩包子文件的文件名称列表,我们可以看到三个不同的文件名:“无法获取网络@3x.png”、“无法获取网络@2x.png”以及“无法获取网络.png”。这些名称暗示了这些图片可能被用作网页开发中的Retina显示技术,其中“@2x”和“@3x”分别指代在普通分辨率显示器和高分辨率显示器(比如Retina显示屏)上使用的图片资源。数字“2”和“3”通常表示图片的DPI(每英寸点数)倍数,意味着在屏幕上以更高的像素密度显示,以达到更好的视觉效果。 综合上述分析,可以总结以下知识点: 1. 网络图片获取的过程及其可能遇到的问题和技术要点。 2. PNG图片格式的技术特性和其在网页素材中的应用。 3. 网页素材下载的过程、途径和可能出现的问题。 4. Retina显示技术及其在图片资源命名中的应用。 5. 通过文件名称识别图片用途和显示需求。 以上就是从给定文件信息中提取的知识点,希望对解决网络图片获取、素材下载和素材管理等问题提供帮助。
recommend-type

【西门子PLC固件升级全攻略】:20分钟快速掌握固件更新流程

# 摘要 随着工业自动化的发展,可编程逻辑控制器(PLC)作为核心部件,其固件升级成为了提高系统性能、确保安全性和引入新功能的重要手段。本文详细介绍了PLC固件升级的整个过程,从准备工作、理论知识、实战操作到升级后的验证与维护,全面阐述了固件升级的关键步骤和注意事项。通过分析固件升级对系统性能的影响、检查硬件兼容性、准备合适的更新环境,本文旨在为工程师提供一套系统的固件升级指
recommend-type

Transformer做短期时序销量预测可行吗

<think>我们正在讨论Transformer模型在短期时间序列销量预测中的应用及效果评估。根据用户的问题,我们需要分析Transformer模型在短期销量预测中的可行性和效果。参考引用中提到了ARIMA模型和迭代方法(如DeepAR、DSSM、ConvTrans等),这些可以作为对比的基准。首先,Transformer模型最初是为自然语言处理设计的,但其自注意力机制能够捕捉序列中的长期依赖关系,因此也被应用于时间序列预测。在短期预测中,虽然传统方法(如ARIMA)可能因为简单而高效,但Transformer在处理非线性关系和多个相关时间序列方面可能更有优势。效果评估方面,我们可以参考引用[
recommend-type

华为SVN连接失败解决方案及SVNDrv驱动更新指南

标题中提到的是解决华为SVN连接不上问题的SVNDrv驱动文件压缩包,这里面涉及的知识点主要包括华为的SVN工具SecoClient、网络适配器配置、以及驱动文件的操作。下面将详细解释这些知识点: 1. SVN工具SecoClient: SecoClient是华为开发的一个客户端软件,用于连接和管理SVN服务器,SVN(Subversion)是一个开源的版本控制系统,广泛用于计算机软件的版本管理和代码控制。SecoClient作为客户端,一般需要安装在用户的电脑上,用来提交、更新、查看和管理源代码。 2. Win10上面连接不上的问题及返回码超时: 用户在使用SecoClient时遇到的连接不上问题,提示“接受返回码超时”,这通常是指客户端尝试与SVN服务器进行通信时,在设定的时间内没有得到有效的响应。返回码超时问题可能由多种原因导致,例如网络连接不稳定、防火墙设置、SVN服务器响应慢、或者是客户端与服务器之间的配置不正确。 3. 网络适配器配置: 网络适配器是电脑硬件中负责数据通信的部分。在本问题中,具体的操作为禁用网络适配器中的“SVN Adapter V1.0”,这一操作可能会影响到SecoClient的网络连接,特别是如果SVN Adapter是一个虚拟的网络适配器或者专门用于SecoClient连接的适配器时。 4. 驱动文件SVNDrv.sys的处理: 驱动文件(SVNDrv.sys)是操作系统用来控制硬件和软件资源的一个软件程序,对于SVN工具来说,这个驱动文件可能是用来协助SecoClient与网络适配器进行通信的。如果在连接SVN时遇到问题,解决方案中提到的删除旧的驱动文件并复制新的文件进去,可能是为了修复驱动文件损坏或更新驱动程序。 具体操作步骤为: - 打开“设备管理器”,找到网络适配器部分。 - 在列表中找到“SVN Adapter V1.0”,右键选择“禁用”。 - 导航到系统盘符下的“C:\Windows\System32\drivers”目录。 - 在该目录中找到并删除“SVNDrv.sys”文件。 - 将新下载的“SVNDrv.sys”文件复制到该目录下。 - 最后回到设备管理器,右键点击“SVN Adapter V1.0”,选择“启用”。 5. 标签中的知识点: - SecoClient:华为提供的用于连接和管理SVN服务器的客户端工具。 - SVNAdapter:可能指的是SecoClient在电脑上配置的一个虚拟网络适配器,用于连接到SVN服务器。 - 返回码超时:连接过程中出现的错误提示,表明在预定时间未能完成操作。 【压缩包子文件的文件名称列表】中的“解决华为SVN连接不上问题SVNDrv驱动文件.zip”则表明该压缩包内包含的是用于解决上述问题的相关文件,即新的SVNDrv.sys驱动文件。 综上所述,本知识点的详细解释不仅涵盖了与华为SecoClient工具相关的操作和配置,还包括了网络适配器和驱动文件的基本理解和处理方法。对于遇到类似问题的IT专业人士或普通用户来说,了解这些操作可以有效地解决SVN连接问题,确保软件开发和版本控制工作的顺利进行。
recommend-type

【西门子PLC新手必备手册】:一文掌握硬件安装与配置技巧

# 摘要 本文旨在全面介绍西门子PLC(可编程逻辑控制器)的相关知识与应用,包括硬件安装、配置实践、基础编程技巧、高级功能应用及系统维护与升级。首先,概述了PLC的基本概念与硬件组件,并详细讲解了硬件安装的理论与实践技巧。接着,深