Uma biblioteca para permitir a gravação de scripts de unidade no código nativo: c, c ++, montagem.
Este projeto tem como objetivo fornecer uma alternativa viável ao C#. Os scripts no C ++ não são adequados para todas as partes de todos os projetos, mas agora é uma opção.
Alterar uma linha de código C# exige que você faça uma nova construção do jogo. Os tempos de construção do Android típicos tendem a ser de pelo menos 10 minutos porque o IL2CPP precisa ser executado e, em seguida, uma enorme quantidade de C ++ deve ser compilada.
Usando C ++, podemos compilar o jogo como um plug -in C ++ em cerca de 1 segundo, trocar o plug -in no APK e instalar imediatamente e executar o jogo imediatamente. Esse é um enorme impulso de produtividade!
C ++ compila muito mais rapidamente que C#. Construções incrementais quando apenas um arquivo muda- as construções mais comuns- podem ser 15x mais rápidas do que com C#. A compilação mais rápida aumenta com o tempo aos ganhos de produtividade. Os tempos de iteração mais rápidos tornam mais fácil permanecer no "fluxo" da programação.
O coletor de lixo da Unity é obrigatório e tem muitos problemas. É lento, corre na linha principal, coleta todo o lixo de uma só vez, fragmenta a pilha e nunca encolher a pilha. Portanto, seu jogo experimentará "problemas de quadro" e, eventualmente, você ficará sem memória e falha.
É difícil manter uma quantidade significativa de esforço para contornar o GC e o código resultante é difícil de manter e desacelerar. Isso inclui técnicas como pools de objetos, que essencialmente tornam o manual de gerenciamento de memória. Você também precisa evitar tipos de valor de boxe, como int , para gerenciar tipos como object , não usar loops foreach em algumas situações e vários outros gotchas.
O C ++ não possui coletor de lixo necessário e apresenta gerenciamento automático opcional de memória por meio de tipos de "ponteiro inteligente" como Shared_Ptr. Oferece excelentes alternativas ao coletor de lixo primitivo da Unity.
Embora o uso de algumas APIs .NET ainda envolva a criação de lixo, o problema está contido apenas para as APIs, em vez de ser um problema difundido para todo o seu código.
Ao usar o C ++ diretamente, você ganha controle completo sobre o código que a CPU executará. É muito mais fácil gerar código ideal com um compilador C ++ do que com um compilador C#, IL2CPP e, finalmente, um compilador C ++. Corte o intermediário e você pode aproveitar a Intrinsics ou a montagem do compilador para escrever diretamente o código da máquina usando recursos poderosos da CPU, como a criptografia SIMD e Hardware AES para obter ganhos maciços de desempenho.
O C ++ é um idioma muito maior que o C# e alguns desenvolvedores preferem ter mais ferramentas à sua disposição. Aqui estão algumas diferenças:
Embora o IL2CPP transforme C# em C ++ já, ele gera muita sobrecarga. Há muitas surpresas se você ler o C ++ gerado. Por exemplo, há uma sobrecarga para qualquer função usando uma variável estática e dois ponteiros extras são armazenados no início de todas as classes. O mesmo vale para todos os tipos de recursos, como sizeof() , verificações nulas obrigatórias e assim por diante. Em vez disso, você pode escrever C ++ diretamente e não precisar contornar o IL2CPP.
O C ++ é o idioma padrão para videogames, além de muitos outros campos. Ao programar em C ++, você pode transferir mais facilmente suas habilidades e codificar para e para projetos que não sejam de unidade. Por exemplo, você pode evitar o bloqueio usando o mesmo idioma (C ++) que você usaria nos motores Unreal ou Lumberyard.
GameObject go;
Transform transform = go.GetTransform();
Vector3 position(1.0f, 2.0f, 3.0f);
transform.SetPosition(position);
MonoBehaviour em c ++ void MyScript::Start()
{
String message("MyScript has started");
Debug::Log(message);
}
#if TARGET_OS_ANDROID )O núcleo deste projeto é um gerador de código. Ele gera código C# e C ++ chamado "encadernas" que disponibilizam as APIs C# para o código do jogo C ++. Ele suporta uma ampla gama de recursos de linguagem:
classstructenumAction )decimalget e set como obj.x )get e set como obj[x] )add e remove os delegados)int para object e visto versa)out e refObserve que o gerador de código ainda não suporta:
Array , string e object (por exemplo, GetHashCode )params implícitos (também conhecido como "var args") passa Para configurar o gerador de código, abra Unity/Assets/NativeScriptTypes.json e observe os exemplos existentes. Adicione este arquivo para expor mais APIs C# do Unity, .Net ou DLLs personalizados ao seu código C ++.
Para executar o gerador de código, escolha NativeScript > Generate Bindings do editor de unidades.
Quase todos os projetos terão uma vitória líquida de desempenho, reduzindo a coleta de lixo, eliminando a sobrecarga do IL2CPP e o acesso a intrínsecos e montagem do compilador. Chamadas de C ++ em C# incorrem apenas uma penalidade de desempenho menor. No caso raro de que quase todo o seu código são chamadas para APIs .NET, você pode experimentar uma perda de desempenho líquida.
Artigo de teste e benchmarks
Artigo de otimizações
Quando o script em C ++, C# é usado apenas como uma camada de "ligação" para que a unidade possa chamar as funções C ++ e as funções C ++ podem chamar a API da Unity. Um gerador de código é usado para gerar a maioria dessas ligações de acordo com as necessidades do seu projeto.
Todo o seu código, além de algumas ligações, existirá em um único plug -in C ++ "nativo". Ao alterar seu código C ++, você criará este plug -in e depois jogará o jogo no editor ou em uma compilação implantada (por exemplo, para um dispositivo Android). Não haverá nenhum código C# para a unidade compilar, a menos que você execute o gerador de código, que não é frequente.
O fluxo de trabalho C# padrão se parece com o seguinte:
Com C ++, o fluxo de trabalho se parece com o seguinte:
Unity/Assets para o diretório de Assets do seu projeto de unidadeNativeScriptTypes.json e especifique quais partes da unidade, .NET e APIs DLL personalizadas para as quais você deseja acesso a partir de C ++.Unity/Assets/CppSource/Game/Game.cpp e Unity/Assets/CppSource/Game/Game.h para criar seu jogo. Algum código de exemplo é fornecido, mas fique à vontade para excluí -lo. Você pode adicionar mais arquivos de origem C ++ ( .cpp ) e cabeçalho ( .h ) aqui à medida que seu jogo cresce./Applications/Utilitiescd /path/to/your/build/directorycmake -G MyGenerator -DCMAKE_TOOLCHAIN_FILE=/path/to/your/project/CppSource/iOS.cmake /path/to/your/project/CppSource . Substitua MyGenerator pelo gerador de sua escolha. Para ver as opções, execute cmake --help e observe a lista na parte inferior. As opções comuns incluem "Unix Makefiles" para construir a partir da linha de comando ou "Xcode" para usar o IDE da Apple.make se você escolheu Unix Makefiles como seu gerador ou aberto NativeScript.xcodeproj e clique em Product > Build se você escolher o Xcode. /Applications/Utilitiescd /path/to/your/build/directorycmake -G "MyGenerator" -DEDITOR=TRUE /path/to/your/project/CppSource . Substitua MyGenerator pelo gerador de sua escolha. Para ver as opções, execute cmake --help e observe a lista na parte inferior. As opções comuns incluem "Unix Makefiles" para construir a partir da linha de comando ou "Xcode" para usar o IDE da Apple. Remover -DEDITOR=TRUE para construções independentes.make se você escolheu Unix Makefiles como seu gerador ou aberto NativeScript.xcodeproj e clique em Product > Build se você escolher o Xcode. cd /path/to/your/build/directorycmake -G "Visual Studio VERSION YEAR Win64" -DEDITOR=TRUE /path/to/your/project/CppSource . Substitua VERSION e YEAR pela versão do Visual Studio que você deseja usar. Para ver as opções, execute cmake --help e observe a lista na parte inferior. Por exemplo, use "Visual Studio 15 2017 Win64" para o Visual Studio 2017. Qualquer versão, incluindo a comunidade, funciona muito bem. Remover -DEDITOR=TRUE para construções independentes. Se você estiver usando o Visual Studio 2019, execute cmake -G "Visual Studio 16" -A "x64" -DEDITOR=TRUE /path/to/your/project/CppSource .NativeScript.sln e clique em Build > Build Solution . cd /path/to/your/build/directorycmake -G "MyGenerator" -DEDITOR=TRUE /path/to/your/project/CppSource . Substitua MyGenerator pelo gerador de sua escolha. Para ver as opções, execute cmake --help e observe a lista na parte inferior. A escolha mais comum é "Unix Makefiles" para construir a partir da linha de comando, mas também existem opções de IDE. Remover -DEDITOR=TRUE para construções independentes.make se você escolheu Unix Makefiles como seu gerador. cd /path/to/your/build/directorycmake -G MyGenerator -DANDROID_NDK=/path/to/android/ndk /path/to/your/project/CppSource . Substitua MyGenerator pelo gerador de sua escolha. Para ver as opções, execute cmake --help e observe a lista na parte inferior. Para fazer uma construção para qualquer plataforma que não seja Android, omite a parte -DANDROID_NDK=/path/to/android/ndk .make se você escolheu Unix Makefiles como seu gerador. Para atualizar para uma nova versão deste projeto, substitua o diretório de Assets/NativeScript do seu projeto de unidade com o diretório Unity/Assets/NativeScript deste projeto e execute novamente o gerador de código.
Artigos do autor descrevendo o desenvolvimento deste projeto.
Jackson Dunstan
Sinta -se à vontade para bifurcar e enviar solicitações de tração ou simplesmente enviar um problema para recursos ou correções de bugs.
Todo o código é licenciado MIT, o que significa que geralmente pode ser facilmente usado em aplicativos comerciais e não comerciais.
Toda a escrita é CC licenciada por 4.0, o que significa que ela pode ser usada desde que a atribuição seja fornecida.