利用NEO与Unity制作游戏(第2部分)"
往事随风760
发表于 2022-12-5 17:35:42
153
0
0
NEOLux提供了一些方便的方法,可以用于将你的游戏连接到官方的测试网或者是主网。% v4 ^; g8 X; h- Z o1 V' I. o7 K
. \) ]4 ^7 E" J
但在本教程中,我们会搭建自己的私有网络。这个过车是非常简单的,一旦你克服了最初的障碍(我会引导你),你会发现这比使用测试网络更加简单。例如,尽管填写用于测试的GAS或者Tokens的申请表格可能不是世界上最困难的任务,但我发现就这样一点点小摩擦,往往会扼杀我继续的热情和动力。( _8 J% i- F8 e
; `; Z+ \3 E- [6 Y. O: k
你也可以在本地运行你自己的私有网络,不过在本教程中,我们将设置自己的服务器。这会使得团队工作或者构建工作这类事情更加简单直接。我将使用DigitalOcean。因为根据我的经验,他们具有良好的性价比。
) B ?; G) a# d
免责声明:我不是一个后端/服务器开发者,我猜“中等”水平的人应该会喜欢使用命令行工具。对于那些知道自己在做什么的人来说,这些内容应该很容易。如果你了解Linux和Docker的话,可以直接从DockerHub安装NEOPrivateNet并使用DockerCompose运行NEOSCAN。对于其他那些或多或少是我这种水平的人来说,接下来的内容应该还是相当简单直接的。/ D2 k7 f8 m% C& h( |2 t: j
如果你还没有DigitalOcean账户的话,就去创建一个。然后使用以下选项创建一个Droplet。+ x2 e8 ]% V. }! b5 R7 c. c
使用16.X或者18.X版本的Ubuntu
使用中配应该就足够了–你可以在配置中自行尝试,并在评论中告诉我你的试验的结果5 i& E* l( \/ c6 I0 f
_2 e- Z9 _) d) f
SSH登入到你新建的Droplet并安装docker。如果你按照DigitalOcean提供的指南进行操作的话,这个过程将非常简单:https://www.digitalocean.com/com ... ker-on-ubuntu-18-04/ w Q2 U' s! m5 u1 q
! W, }1 Z% l4 d
注意:在执行最开始的一步,向系统添加官方Docker库的GPG键这步操作时,我遇到了点小问题。我只是简单地跑了两次命令,然后一切都很顺利。4 R9 b+ e- Z, ]. `1 T; F. ~$ ]* X
5 t% f( Y4 m3 o
然后安装docker组件。同样地,安装说明非常的简单。只需要确保你看的是针对Linux系统的说明就行。
: n$ a @, l( f. {, ?: s. [
安装私有网络和NEOSCAN% p4 _: G5 ?+ d6 ?, v& M6 E8 C) d
运行和安装我们自己的私有网络,这是最为困难的一步,好在CityofZion的人帮我们很好的做到了这一点。你可以点击这个链接查看他们的全部说明指导。同样地,SSH登录到你的Droplet,基本上我们只需要输入几个命令就行:6 \1 N1 L, ^/ c7 i" U! P
首先,从hub上下载docker镜像:
( I/ K9 M+ A- n7 H
dockerpullcityofzion/neo-privatenet
…下载NEOSCAN…5 O8 _2 u! U, ]9 ~1 [# `, a
' F% h# K4 l3 {+ g) U: l' @
wgethttps://raw.githubusercontent.co ... /docker-compose.yml
; M0 v9 ]" T* c7 d0 u4 k; \
…并运行privnet…
docker-compose-fdocker-compose-neoscan.ymlup& I) x6 U( s3 C+ b# q8 a
# E7 n3 Q. N8 V1 A6 ^% }+ N+ N% }0 H
让它运行起来,然后转到http:your-droplet-ip-address:4000查看NEOSCAN的运行情况:
回到Unity( @ t3 z+ \7 V5 z6 V
) ]/ Z8 m( z. C' v, N0 n
我不想在本教程中深入探讨自己的开发风格,不过我要做的一件事就是将UniRx插件导入Unity中。UniRx是对.NETReactiveExtensions的重新实现,它针对Unity做了优化处理,而且能很好地兼容iOSIL2CPP。不必过于复杂的实现,它可以简化一些管理NEO和UI的代码。
' m" B4 ]$ ^" ~1 K, \
在资产(Assets)–>脚本(Scripts)下创建另一个名为NEOManager的脚本,并复制+粘贴以下代码:
0 Q) Y7 T+ q. S6 A2 |" ?" A
usingSystem.Collections;
1 r. n4 X: h: b& }% G W: I0 P
usingUnityEngine;: E0 E+ d* g$ n& S( b
usingSystem;0 w2 l+ }( c4 y/ Y6 Y/ E1 x+ _
usingUniRx;0 v8 g7 M9 x$ [% X& u
usingNeo.Lux.Core;. D4 y- Q- E7 z2 p5 {# q
usingNeo.Lux.Cryptography;
usingUnityEngine.UI;
/ B8 c- X: U0 s& n/ B
publicclassNEOManager:MonoBehaviour
{
+ s5 n( }& Q2 q# l! H% y3 R$ r0 f
publicNeoAPIAPI;
& D; ^* w9 b; g9 b" G% [) ]! \9 i
[SerializeField]privatestringRpcIP;: i. i5 e; }& ]8 q- M8 E: X
publicconststringAssetSymbol="GAS";& M+ ^2 O0 ^' h
( [0 s: Q/ ~, L+ i5 n+ D3 ?
[HideInInspector]
/ ~( c6 i: {( q! L6 T; C3 c! U
publicKeyPairReactivePropertyPlayerKeyPair=newKeyPairReactiveProperty();7 J0 R4 B7 Y, d6 _* k3 l+ N4 \
/ u, l6 x! q4 ~3 M. v
[SerializeField]privateTextaddressText;9 ~, Q* A# G8 w+ H$ r1 O
. [6 B: L: I" L: J+ t. Z, L
[SerializeField]privateTextbalanceText;: L5 s5 T g; _" \4 i1 F
publicDecimalGASBalance;
0 m4 p9 c; E |( L4 A
privatevoidOnEnable()5 P z8 y' N% ]
{! w { I; U2 p0 m2 ]
PlayerKeyPair.Value=KeyPair.FromWIF("KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr");* I7 ^* z$ N# C1 c; ]
#ifUNITY_EDITOR
//this.API=newLocalRPCNode(30333,"http://localhost"); {/ [$ d3 Y( r+ @3 {
* D3 w% z9 g x `8 a* B
this.API=newCustomRPC(30333,4000,"http://"+RpcIP);- g5 N+ n& o$ g4 h, m5 v1 t
, v# T/ _8 ~: }" w N" U
#else1 t9 _8 @: E8 F0 ^( A. T
5 Z1 Q- N# `$ O1 P+ b# x6 c
//this.API=NeoRPC.ForTestNet();4 A6 p* j! f. _+ z5 |+ G
% ?6 g" R( g3 e8 \' d# {( T. z. U
this.API=newCustomRPC(30333,4000,"http://"+RpcIP);
9 Y8 O5 S1 N2 B8 [7 p
#endif! j9 [8 O0 d0 F. v
6 X6 T; {1 {) W @7 R2 S, }% W
this.PlayerKeyPair.DistinctUntilChanged().Where(kp=>kp!=null).Subscribe(keyPair=>$ ^) n6 f/ F7 } }2 H# C
{
this.addressText.text="Address:"+keyPair.address; m/ s7 S! g9 e" m$ [( z2 m6 Z
: P; \5 W- ?9 ^0 c# K
this.balanceText.text="Balance:Pleasewait,syncingbalance...";9 j1 P- }( O; I( y' `) n# j
StartCoroutine(SyncBalance());6 [: B( h' E$ ~6 @7 C# h7 @3 k+ e
8 m K A. L+ _, \/ O) f% T$ Q
}).AddTo(this);7 C4 b6 M' S# [8 u& L
' ?+ Q5 [, c8 M+ q
}* R( T2 {! v* A# o6 a4 q
privateIEnumeratorSyncBalance()
8 W. k. A! u7 t: q, E
{9 V, F' |* X# G- y8 g! O" r
yieldreturnnull;# }' w3 N9 Y) D
varbalances=this.API.GetAssetBalancesOf(this.PlayerKeyPair.Value);
: i* u- k& L; z- I
this.GASBalance=balances.ContainsKey(AssetSymbol)?balances[AssetSymbol]:0;/ @ b, o) B; Z# s; K, ]( v
2 d( N8 j1 [! N# a5 M: g5 o3 I
this.balanceText.text="Balance:"+GASBalance.Value.ToString()+""+AssetSymbol;% R+ t, Y5 k( `4 Q" c4 ]
# y! x7 ^5 E5 c/ P! x" E
}
}
4 Z* O( |% n$ k. |) D* t
[Serializable]
publicclassKeyPairReactiveProperty:ReactiveProperty
/ |6 m/ f& G9 C5 [; z9 ]+ S1 `1 a
{
publicKeyPairReactiveProperty(){}
( ?$ n, \! g7 h: ~+ `9 |8 Z
publicKeyPairReactiveProperty(KeyPairinitialValue):base(initialValue){}
. ?/ b- W% W3 T* O) N
}8 z1 g$ y. E8 e
保存脚本然后返回主场景。创建一个空的游戏对象(GameObject),将其命名为NEO,然后创建一个该NEO对象的空的游戏子对象(childGameObject),并将其命名为NEOManager,并将NEOManager脚本添加到这个NEO对象中。在检查器(inspector)中的RpcIP字段旁边输入你的Droplet的IP地址。9 |: {. H k- j" l- G( i$ N
接下来,我们将创建一些UI元素并将它们连接到检查器中,这样在连接到主网的时候,我们就可以看到余额的更新。
5 W. b; _ C; e v
创建UI画布并向其中添加两个子文本元素,然后单击并将它们的引用拖动到NEOManager的“(AddressText)”和“(BalanceText)”字段。! b8 E, V; S9 B- ^& B2 I! N Y4 T
5 _$ i6 @3 V$ c# ~2 b
单击播放(Play)按钮然后查看地址和余额的更新情况。$ L" U9 W$ l- \% k8 G4 ]/ o
+ n9 @- _( z6 C! E
我们当前使用的是在安装私有网络时自动生成的测试账号。在下一部分中,我们会进行一些设置,以便我们的玩家可以输入他们自己的私钥然后开始与NEO区块链进行交互。
成为第一个吐槽的人