利用NEO与Unity制作游戏(第2部分)"
往事随风760
发表于 2022-12-5 17:35:42
118
0
0
- T$ `* w+ `9 ?2 p+ o
NEOLux提供了一些方便的方法,可以用于将你的游戏连接到官方的测试网或者是主网。
) X* d$ b8 { g; c, j
但在本教程中,我们会搭建自己的私有网络。这个过车是非常简单的,一旦你克服了最初的障碍(我会引导你),你会发现这比使用测试网络更加简单。例如,尽管填写用于测试的GAS或者Tokens的申请表格可能不是世界上最困难的任务,但我发现就这样一点点小摩擦,往往会扼杀我继续的热情和动力。
* s1 O$ @ t. B' H7 q
你也可以在本地运行你自己的私有网络,不过在本教程中,我们将设置自己的服务器。这会使得团队工作或者构建工作这类事情更加简单直接。我将使用DigitalOcean。因为根据我的经验,他们具有良好的性价比。
' R" j, {1 N7 e: Z H
免责声明:我不是一个后端/服务器开发者,我猜“中等”水平的人应该会喜欢使用命令行工具。对于那些知道自己在做什么的人来说,这些内容应该很容易。如果你了解Linux和Docker的话,可以直接从DockerHub安装NEOPrivateNet并使用DockerCompose运行NEOSCAN。对于其他那些或多或少是我这种水平的人来说,接下来的内容应该还是相当简单直接的。1 c2 l' H# j4 `
如果你还没有DigitalOcean账户的话,就去创建一个。然后使用以下选项创建一个Droplet。
3 j. i3 n( B" f% D: r& \
使用16.X或者18.X版本的Ubuntu4 X: Y, O; Q; }; K! q
使用中配应该就足够了–你可以在配置中自行尝试,并在评论中告诉我你的试验的结果' N% g! O' B( ~+ _7 V
SSH登入到你新建的Droplet并安装docker。如果你按照DigitalOcean提供的指南进行操作的话,这个过程将非常简单:https://www.digitalocean.com/com ... ker-on-ubuntu-18-04: n! P" B) a3 L; q" K1 X7 a* k
1 S/ W" I, Q: K2 \. F: G
注意:在执行最开始的一步,向系统添加官方Docker库的GPG键这步操作时,我遇到了点小问题。我只是简单地跑了两次命令,然后一切都很顺利。
然后安装docker组件。同样地,安装说明非常的简单。只需要确保你看的是针对Linux系统的说明就行。( L7 t0 |$ p8 K9 L2 ^
& A. }2 ]2 _, |
安装私有网络和NEOSCAN/ d" G% A; Y$ E ^
/ V ?8 b, A- W9 D, |& h
运行和安装我们自己的私有网络,这是最为困难的一步,好在CityofZion的人帮我们很好的做到了这一点。你可以点击这个链接查看他们的全部说明指导。同样地,SSH登录到你的Droplet,基本上我们只需要输入几个命令就行:
; i$ M" b# R/ I/ ]& Q
首先,从hub上下载docker镜像:- e# `0 u- F+ ]' `+ e7 }
dockerpullcityofzion/neo-privatenet
…下载NEOSCAN…9 y K! u+ b5 v6 D( ^
wgethttps://raw.githubusercontent.co ... /docker-compose.yml b. A% B$ y n9 o& _5 U9 i: Z
4 L4 H" Z' O% W+ `9 N
…并运行privnet…: M. P4 g1 X3 T% `3 {5 M) W
0 I6 H7 a9 ?" L
docker-compose-fdocker-compose-neoscan.ymlup8 K# p) P2 R7 X* s7 G
让它运行起来,然后转到http:your-droplet-ip-address:4000查看NEOSCAN的运行情况:0 G" d/ u9 E) f0 R
, B0 l3 x) [% y" \
回到Unity
( k, y% j& d( |% C' f
我不想在本教程中深入探讨自己的开发风格,不过我要做的一件事就是将UniRx插件导入Unity中。UniRx是对.NETReactiveExtensions的重新实现,它针对Unity做了优化处理,而且能很好地兼容iOSIL2CPP。不必过于复杂的实现,它可以简化一些管理NEO和UI的代码。
在资产(Assets)–>脚本(Scripts)下创建另一个名为NEOManager的脚本,并复制+粘贴以下代码:
usingSystem.Collections;
- c* x# a% v7 H- ^; \
usingUnityEngine;
usingSystem;
) ~- H: `" i6 w- o
usingUniRx;+ }$ ~3 p6 }) | g9 E
, w9 \; x: h# D: R9 W
usingNeo.Lux.Core;, S' A; D' k/ N2 v, V
usingNeo.Lux.Cryptography;
7 z/ W0 U" N) n: a9 c7 `0 J1 U
usingUnityEngine.UI;
; A) J' D. [" H9 N7 d8 L$ c
publicclassNEOManager:MonoBehaviour; z2 ~- y5 i1 x4 x$ ^+ D( |7 E
* X1 { ]# {! u) F7 y$ N
{
publicNeoAPIAPI;" R; g; e5 X0 F6 y
4 l7 `. X+ x- R' t
[SerializeField]privatestringRpcIP;
publicconststringAssetSymbol="GAS";
, ]" W( E2 V: i3 ]' x6 }7 a5 e0 y
[HideInInspector]
publicKeyPairReactivePropertyPlayerKeyPair=newKeyPairReactiveProperty();2 Q% D4 I" n% I: F
* Y2 i; c) |; t- Y! a7 W4 ^$ s
[SerializeField]privateTextaddressText;
" q3 I# u, n1 ^, ^! j$ B8 [
[SerializeField]privateTextbalanceText;, A$ Z, n$ K6 P
( [9 \: _" Z b8 i+ x3 i% k
publicDecimalGASBalance;# W8 H. T* Z+ m) W
& Z- ]: r1 N; l/ n0 ~
privatevoidOnEnable()
4 F1 H- Q- v2 J0 ^' S0 s5 c& L0 A' M, Z
{
PlayerKeyPair.Value=KeyPair.FromWIF("KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr");$ `& }6 n& o) k' |2 E$ p( P3 e* {$ _
#ifUNITY_EDITOR5 u0 @) g8 V% w
8 p T+ M9 A5 I( `, i4 B6 f$ \
//this.API=newLocalRPCNode(30333,"http://localhost");
' Z, x& N/ p3 S+ E/ s
this.API=newCustomRPC(30333,4000,"http://"+RpcIP);
, [7 F: J- D/ _. l0 f7 z
#else
( A G& X0 h' d4 Z; M; ~
//this.API=NeoRPC.ForTestNet();
" [7 T! M2 R# x: ?7 w+ B8 b* u; S3 J
this.API=newCustomRPC(30333,4000,"http://"+RpcIP);! d1 a* Y5 L/ ?) v" D
/ v l$ [* }; Z$ x! ~1 q4 d
#endif/ D1 M0 n8 ~/ S a1 B+ n! ?
- R: K- q' Q3 U
this.PlayerKeyPair.DistinctUntilChanged().Where(kp=>kp!=null).Subscribe(keyPair=>
{
this.addressText.text="Address:"+keyPair.address;4 X3 Q2 B# N0 R9 N
/ {, ]3 X/ t5 e+ D {7 }
this.balanceText.text="Balance:Pleasewait,syncingbalance...";
1 B8 B5 r; Z/ j
StartCoroutine(SyncBalance());6 y6 h& w0 N3 P7 v$ z @. s; K' U
}).AddTo(this);
# R$ s8 d/ b. ~2 m* M
}
3 A' }7 O6 x* B4 N1 u& x3 p7 I
privateIEnumeratorSyncBalance()$ T/ z. I( T( M
S4 ~' n* y% H- S3 B- c' y
{
yieldreturnnull;
varbalances=this.API.GetAssetBalancesOf(this.PlayerKeyPair.Value);
this.GASBalance=balances.ContainsKey(AssetSymbol)?balances[AssetSymbol]:0;, A7 J" G/ t. P
2 m% J" |& G4 _4 B6 u
this.balanceText.text="Balance:"+GASBalance.Value.ToString()+""+AssetSymbol;
}( ^. R; Y- M4 F1 f
}8 T) j& ~7 u% f+ Z7 D9 l& V
0 c' i8 y3 {) F5 [
[Serializable]
publicclassKeyPairReactiveProperty:ReactiveProperty
{# ?# } l4 B8 H: S O% v# q% o! R$ H* d
. \9 N* L& s! \6 B
publicKeyPairReactiveProperty(){}1 w% Y( B& U3 h. f
: C' S2 M1 g; E5 f: U. v3 Z- |
publicKeyPairReactiveProperty(KeyPairinitialValue):base(initialValue){}
$ w w! T9 E( c2 @
}& s% U9 Q8 T# Q) y
% ] T, Z& T" i' @
保存脚本然后返回主场景。创建一个空的游戏对象(GameObject),将其命名为NEO,然后创建一个该NEO对象的空的游戏子对象(childGameObject),并将其命名为NEOManager,并将NEOManager脚本添加到这个NEO对象中。在检查器(inspector)中的RpcIP字段旁边输入你的Droplet的IP地址。" j2 m1 A, w& v* M @3 \# y1 t
2 c0 x7 e( d% P, O2 e% q
接下来,我们将创建一些UI元素并将它们连接到检查器中,这样在连接到主网的时候,我们就可以看到余额的更新。
9 c2 P, z9 L7 w# Z+ ?
创建UI画布并向其中添加两个子文本元素,然后单击并将它们的引用拖动到NEOManager的“(AddressText)”和“(BalanceText)”字段。
单击播放(Play)按钮然后查看地址和余额的更新情况。8 W0 b$ }3 [2 L8 S! H' {
- E& G3 z9 J# I
我们当前使用的是在安装私有网络时自动生成的测试账号。在下一部分中,我们会进行一些设置,以便我们的玩家可以输入他们自己的私钥然后开始与NEO区块链进行交互。
成为第一个吐槽的人