一座堤的博客
type: channel
link: https://www.yizuodi.cn/
description: 为者常成 行者常至
items: Per Aspera ad Astra
items: Unity3d UI系统 UI 效果制作（拓展篇）
items: Unity3d游戏智能 坦克对战游戏AI设计
items: Unity3dUI系统 UI 效果制作
items: Unity3d粒子系统 汽车尾气模拟
items: Unity3d模型与动画 智能巡逻兵游戏
items: 基于Unity3D 编写简单的自定义组件
items: 基于Unity3D引擎构建简单的游戏场景
items: 使用中国银行长城跨境通国际借记卡购汇与消费
items: 基于Unity3D的物体抛物线运动实现

Per Aspera ad Astra
type: item
date: 2024-03-18T15:10:51+08:00

Unity3d UI系统 UI 效果制作（拓展篇）
type: item
date: 2023-03-23T15:34:00+08:00
description: 在之前的这一篇博客文章中(www.yizuodi.cn/archives/129)，我们进行了UI 效果制作。在另一篇文章中(www.yizuodi.cn/archives/119)，我们制作了一款智能巡逻兵游戏。本篇文章，我们做了一个简单的用户登录实现，来尝试让我们的智能巡逻兵游戏变成一款网络游戏。为什么要做“用户登录”的部分？对于我们之前的智能巡逻兵游戏中玩家得分的设计，我个人的想法是将得分和通关用时综合考虑。我们分析，得分为躲避得分（成功甩掉计一分）。任务点是随机刷新的，而较难完成的任务点会导致玩家“用时增加，得分增加”概率提升。所以我们可以将游戏得分和通关用时加权求和得到一个分数（类似与很多游戏的“段位分”），来作为玩家游戏成果的评估。“巡逻兵游戏”是一个单机游戏，那么我们怎么通过所谓“段位分”给予玩家满足感呢？我个人的想法是提供一个全球游戏榜单（我制作了一个示例game.233521.xyz）。为此，我们需要一个为玩家提供一个账号系统，需要一个服务端来让所有玩家可以提交他们的游戏结果。我们的设计1.在游戏中，我们有一个登录的UI，玩家点击按钮可以唤起浏览器打开网页进行登录（可拓展微信扫码登录等）。2.登录成功后可以获取到一个一次性登录令牌，玩家复制后在游戏中粘贴，点击登录按钮。若令牌有效即可成功登入。实现效果展示游戏中的登录的UI如下：唤起浏览器打开的登录页面如下(demo)：登录后玩家获取令牌：本人的“3D游戏编程与设计”系列合集，请访问：https://www.yizuodi.cn/category/3DGame/

Unity3d游戏智能 坦克对战游戏AI设计
type: item
date: 2022-11-15T22:39:00+08:00
description: 本文内容为坦克对战游戏AI设计。我们构建 AI 对战坦克有几点目标：· 使用“感知-思考-行为”模型，建模 AI 坦克· 场景中要放置一些障碍阻挡对手视线· 坦克要放置一个矩阵包围盒触发器，保证 AI 坦克能使用射线探测对手方位· AI 坦克必须在有目标条件下使用导航，并能绕过障碍。· 实现人机对战我们使用了资源Tanks! Tutorial（Unity资源商店链接）。接下来我们构建AI对战坦克。游戏设计玩家操纵红色坦克，可以通过WASD按键移动坦克，按空格键发射弹药攻击。地图中有一些蓝色的AI坦克，当玩家出现在AI坦克的视野中，它们就会跟踪玩家并向玩家发射弹药。每辆坦克都有自己的血量值，受到攻击坦克血量会下降，当血量值将为0以下，则坦克被击毁。如果玩家的坦克被击毁则游戏失败，如果玩家击毁了所有的AI坦克则游戏胜利。对于“感知-思考-行为”模型——AI坦克会感知周围是否有玩家存在，进行思考:1.没有玩家，那么就进行行动巡逻。2.有玩家，那么就进行行动追捕。继续进行感知：1.若玩家进入AI坦克的射击范围，则进行行动射击。2.若玩家没有进入AI坦克的射击范围，则继续进行行动追捕。游戏展示场景布置我们先简单布置场景：NavMesh是unity提供的导航寻路功能。我们先将地图设置为“navigation static”，然后选中，选择最顶部的窗口-AI-导航。在Navigation窗口给地图中的各个对象设置walkable或者not walkable等，然后进行bake烘培，得到描述游戏对象可行走的表面的数据结构Navigation Mesh。可通过这些三角网格计算其中任意两点之间的最短路径用于游戏对象的导航，作为“感知-思考-行为”模型中的“感知”。然后我们制作三种预制件——敌方（AI）坦克、玩家坦克和炮弹。脚本编写我们考虑游戏的双方：AI坦克和玩家坦克的共性——都有血量。因而我们可以先定义一个共同的基类Tank如下：public class Tank : MonoBehaviour { private float hp; // 血量 public float getHp() // 获取血量 { return hp; // 返回血量 } public void setHp(float hp) // 设置血量 { this.hp = hp; // 设置血量 } }然后对于坦克的一些事件，我们有接口类IUserAction，包含坦克前进、后退、转向、射击和游戏状态获取：public interface IUserAction { void moveForward(); void moveBack(); void turn(float offsetX); void shoot(); bool isGameOver(); }我们有一个场景控制器SceneController来掌控全局。因此对于玩家的坦克PlayerTank，我们只需要在其发现自己血量低于零时，销毁自己并发布相应事件共控制器处理即可：public class PlayerTank : Tank { public delegate void destroy(); public static event destroy destroyEvent; void Start (){ setHp(1000f); } void Update (){ if(getHp() <= 0){ this.gameObject.SetActive(false); if (destroyEvent != null) destroyEvent(); } } }而对于AI坦克，我们有“思考”。如果其在自己附近没有发现玩家，则进行巡逻。若发现了玩家则开始追捕；一旦追捕使得玩家出现在其一定范围内（射程内），则其开炮射击。这一系列就是对应“行动”。using UnityEngine.AI; public class AITank : Tank { public delegate void recycle(GameObject tank); // 回收事件委托 public static event recycle recycleEvent; // 回收事件 private Vector3 target; // 目标点 private bool gameover; // 游戏结束状态 private static Vector3[] points = { new Vector3(37.6f,0,0), new Vector3(40.9f,0,39), new Vector3(13.4f, 0, 39), new Vector3(13.4f, 0, 21), new Vector3(0,0,0), new Vecto…

Unity3dUI系统 UI 效果制作
type: item
date: 2022-11-15T22:37:00+08:00
description: 本文主要涉及UI效果制作——UGUI实现Quest Log公告牌效果。进入 NGUI 官方网站，有以下效果• Inventory 背包系统• Quest Log 公告牌• Scroll View 选择板注：以上例子需要使用 Unity web player， 仅支持以下操作系统与浏览器，参见官方下载• Windows 版 IE11• Mac OS X 10.7 Safari注：出现界面需要等待较长时间，让它慢慢加载NGUI提供的示例如下图：而UGUI是由unity官方提供的UI工具套件。参考它们的区别：https://www.jianshu.com/p/5891e28aa766场景布置我们可以通过创建UI-面板创建一个panel（面板），其根目录为canvas（画布）。然后我们在panel中创建一个文本，作为公告栏的标题；在panel中添加一个ScollView（滚动视图）作为公告栏的主要内容部分；在panel中添加一个button（按钮）作为公告栏“关闭”按钮。略作调整后效果如图（这里我们使用了2D Casual UI资源包）：滚动视图的完善上面我们的UI界面中，只有滚动视图，里面还没有详细的内容，我们继续为其添加详细的内容。我们先在Viewport的Content中加入组件“Vertical Layout Group”，设置勾选“控制子对象大小-宽度”和“子力拓展-宽度”，其他不勾选。然后我们在Content下创建三个Button（命名为Button1，Button2，Button3）和三个Text（命名为Text1，Text2，Text3）。在Button的检查器中，我们将导航设置为None。我们需要为按钮加上脚本，使其被点击时，对应的文本展示/不展示。脚本extend内容如下：using UnityEngine.UI; public class extend : MonoBehaviour { public Text text; // 控制的Text对象 private int frame = 20; // 动画帧数 void Start() { Button btn = this.gameObject.GetComponent (); // 获取Button对象 btn.onClick.AddListener(TaskOnClick); // 添加点击事件 text.gameObject.SetActive(false); // 初始化时隐藏Text } IEnumerator FoldAndUnfold(bool isFold) { Vector2 fold = new Vector2(0, 120); // 折叠状态 Vector2 unfold = new Vector2(-90, 0); // 展开状态 Vector2 target = isFold ? fold : unfold; for (int i = 0; i < frame; i++) // 逐帧执行动画 { target.x += (isFold ? -90f : 90f) / frame; // 旋转角度逐帧增加或减少 target.y += (isFold ? -120f : 120f) / frame; // Text高度逐帧增加或减少 text.transform.rotation = Quaternion.Euler(target.x, 0, 0); // 设置旋转角度 text.rectTransform.sizeDelta = new Vector2(text.rectTransform.sizeDelta.x, target.y); // 设置Text高度 if (i == 0 || i == frame - 1) // 第一帧和最后一帧控制Text的显示状态 { if(isFold){ text.gameObject.SetActive(false); } else{ text.gameObject.SetActive(true); } } yield return null; } } void TaskOnClick() { if (text.gameObject.activeSelf) // 判断Text是否显示 { StartCoroutine(FoldAndUnfold(true)); // 执行折叠动画 } else { StartCoroutine(FoldAndUnfold(false)); // 执行展开动画 } } }这样我们就成功实现了与NGUI中例子类似的效果。效果展示本人的“3D游戏编程与设计”系列合集，请访问：https://www.yizuodi.cn/category/3DGame/

Unity3d粒子系统 汽车尾气模拟
type: item
date: 2022-11-15T10:15:00+08:00
description: 本文使用官方资源 Vehicle 的 car， 使用 Smoke 粒子系统模拟启动发动、运行、故障等场景效果，完善“汽车尾气”模拟场景布置我们需要先导入Unity3D 官方资源包Standard Assets，该资源包已经不再内置，而且资源商店也没有，我提供一份附在这里。Standard Assets.unitypackage（68.4M）网上找来的资源包导入后，可能会有一些问题，可参考：https://blog.csdn.net/Sakuya__/article/details/113815974我们导入资源包后，先在场景中放置一个3D平面对象（plane），然后在资源包中找到Vehicle 的 car的预制，拖入场景中，效果如下图：粒子效果模拟根据要求，我们模拟启动发动、运行、故障三种场景的尾气效果。预制的Car里面的Particles里有一个Smoke粒子系统ParticleBurnoutSmoke。我们的粒子系统叫做start、run和damage。在检查器中，粒子系统有很多设置选项，我们可以根据自己的需要选择。由于Standard Assets资源包内置了一些材质，我们可以在粒子系统的渲染器（render）-材质（material）选项中选用，从而让粒子有不同的形状。为了展示不同的尾气效果，我们编写脚本CarStatus加到Car这个游戏对象上，功能为按下键盘上的数字选择尾气的效果（数字1-4）。public class CarStatus : MonoBehaviour { // 定义需要切换的粒子效果 public ParticleSystem[] particleSystems; // 当前粒子效果的索引 public int currentIndex = 0; void Start() { particleSystems = new ParticleSystem[4]; particleSystems[0] = transform.Find("Particles/ParticleBurnoutSmoke").GetComponent<ParticleSystem>(); particleSystems[1] = transform.Find("Particles/start").GetComponent<ParticleSystem>(); particleSystems[2] = transform.Find("Particles/run").GetComponent<ParticleSystem>(); particleSystems[3] = transform.Find("Particles/damage").GetComponent<ParticleSystem>(); // 将所有粒子效果关闭 for (int i = 0; i < particleSystems.Length; i++) { particleSystems[i].Stop(); } } void Update() { // 当按下键盘对应数字键时，切换粒子效果 if (Input.GetKeyDown(KeyCode.Alpha1)) { // 将当前粒子效果关闭 particleSystems[currentIndex].Stop(); // 将当前粒子效果索引设置为0 currentIndex = 0; // 将当前粒子效果打开 particleSystems[currentIndex].Play(); } else if (Input.GetKeyDown(KeyCode.Alpha2)) { particleSystems[currentIndex].Stop(); currentIndex = 1; particleSystems[currentIndex].Play(); } else if (Input.GetKeyDown(KeyCode.Alpha3)) { particleSystems[currentIndex].Stop(); currentIndex = 2; particleSystems[currentIndex].Play(); } else if (Input.GetKeyDown(KeyCode.Alpha4)) { particleSystems[currentIndex].Stop(); currentIndex = 3; particleSystems[currentIndex].Play(); } } }为了方便观察，我们把之前项目中CameraMove脚本也拿来稍作修改，附加到主摄像头上。public class CameraMove : MonoBehaviour { public…

Unity3d模型与动画 智能巡逻兵游戏
type: item
date: 2022-11-15T10:11:00+08:00
description: 游戏设计： • 创建一个地图和若干巡逻兵(使用动画)；• 每个巡逻兵走一个3~5个边的凸多边型，位置数据是相对地址。即每次确定下一个目标位置，用自己当前位置为原点计算； • 巡逻兵碰撞到障碍物，则会自动选下一个点为目标； • 巡逻兵在设定范围内感知到玩家，会自动追击玩家； • 失去玩家目标后，继续巡逻； • 计分：玩家每次甩掉一个巡逻兵计一分，与巡逻兵碰撞游戏结束； 程序设计： • 使用订阅与发布模式传消息• 工厂模式生产巡逻兵游戏设计基于上面的几点，我们设计这样一个游戏场景：1.我们的地图有3×3共计9块区域，不同区域间有部分连通，每个区域有一个巡逻兵。2.地图上会随机生成一些任务点，作为玩家需要到达的目标位置，这些任务点需要玩家全部到达且未被巡逻兵碰撞到方为获胜。3.每到达一个任务点时为甩掉巡逻兵一次，计一分。4.每次游戏任务点位置随机分布在地图上，但总的任务点数量一定。5.玩家初始位置为地图区域的中心位置。游戏展示游戏操作演示1-游戏各项操作（11.7M）游戏操作演示2-失败（1.17M）游戏操作演示3-完成（0.9M）游戏预制制作基于上面的要求与设计，可以先为我们的游戏场景创建4个预制：地图、玩家、“任务点”、巡逻兵。地图我使用了Low Poly v2资源包进行预制制作。玩家和巡逻兵我基于SoldierFree资源包中的预制制作，我们为两个预制添加Rigidbody和Capsule Collider来实现玩家与巡逻兵的碰撞。对于巡逻兵的预制，我们添加了两个脚本，一个脚本用于记录巡逻兵对象的一些信息，另一个脚本用于处理玩家与巡逻兵相撞后的情况。另外我们添加了一块方形的碰撞器（设置为触发器）来探测玩家，并添加了相应的脚本来使得有玩家进入/离开该方形区域时，巡逻兵开始/停止追捕玩家。我们使用了Animator组件，通过控制器来使得对应的对象做出相应的动画行为。它是使用状态机来管理运动的，我们在脚本中可以设置状态的改变，从而对应有对象（玩家或巡逻兵）的动画表现。然后我们将玩家对象和巡逻兵对象对应的控制器加到预制上。“任务点”目前是简单的用红色圆球来代替（其碰撞体积也为圆球）。这样我们就拥有了一些游戏的基本元素。脚本编写我们的实现要求是：订阅与发布模式传消息和工厂模式生产巡逻兵。我们先给出主摄像机上附加脚本CameraMove，从而我们可以在移动玩家游戏对象时伴随镜头的移动。public class CameraMove : MonoBehaviour { public GameObject follow; // 跟随的对象 public float speed = 5f; // 相机跟随的速度 Vector3 offset; // 相机与物体相对偏移位置 void Start() { offset = transform.position - follow.transform.position; } void FixedUpdate() { Vector3 target = follow.transform.position + offset; // 计算目标位置 transform.position = Vector3.Lerp(transform.position, target, speed * Time.deltaTime); // 摄像机自身位置到目标位置平滑过渡 } }对于我们的巡逻兵，我们有一个脚本PatrolData附加其上，用于保存它的一些信息public class PatrolData : MonoBehaviour { public int block; // 巡逻兵所在区域编号 public bool follow_player = false; // 是否正在追逐玩家 public int player_block = -1; // 此时玩家所在区域编号 public GameObject player; // 玩家游戏对象 public Vector3 start_position; // 巡逻兵初始位置 }接着我们给出几个预制中与碰撞相关的脚本（里面使用了控制器等部分后续给出）。首先对于场景，我们对9块区域都附加上PlaneCollide脚本，以更新玩家所在的区域信息。public class PlaneCollide : MonoBehaviour { public int block = 0; FirstSceneController sceneController; private void Start() { sceneController = SSDirector.GetInstance().CurrentScenceController as FirstSceneController…

基于Unity3D 编写简单的自定义组件
type: item
date: 2022-10-16T08:09:00+08:00
description: 本文参考官方手册(https://docs.unity3d.com/ScriptReference/Editor.html)，编写一个简单的自定义Component(组件)，用自定义组件定义几种飞碟，编辑并赋予飞碟一些属性，做成预制首先我们可以定义飞碟的一些共有的属性，脚本DiskData：public class DiskData : MonoBehaviour { public int score = 1; // 射击命中得分 public Color color = Color.white; // 颜色 public Vector3 direction; // 初始的位置 public Vector3 scale = new Vector3(1 ,0.25f ,1); // 大小 }我们把它绑定到飞碟上，在检查器中可以看到几项属性：继续参考Unity的文档：https://docs.unity3d.com/cn/current/ScriptReference/Editor.html可知需要我们新建一个继承Editor的脚本类MyDiskEditor，让我们有一个使用 IMGUI 和多重选择的自定义检视面板。如下：using UnityEngine; using UnityEditor; using System.Collections; [CustomEditor(typeof(DiskData))] [CanEditMultipleObjects] public class MyDEditor : Editor { SerializedProperty score; // 分数 SerializedProperty color; // 颜色 SerializedProperty scale; // 大小 void OnEnable() { // 序列化属性 score = serializedObject.FindProperty("score"); color = serializedObject.FindProperty("color"); scale = serializedObject.FindProperty("scale"); } public override void OnInspectorGUI() { serializedObject.Update(); // 更新序列化属性 EditorGUILayout.IntSlider(score, 0, 5, new GUIContent("score")); // 分数 if (!score.hasMultipleDifferentValues) { ProgressBar(score.intValue / 5f, "score"); // 进度条 } EditorGUILayout.PropertyField(color); // 颜色 EditorGUILayout.PropertyField(scale); // 大小 serializedObject.ApplyModifiedProperties(); // 应用修改 } private void ProgressBar(float value, string label) { Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField"); // 进度条的位置 EditorGUI.ProgressBar(rect, value, label); // 进度条 EditorGUILayout.Space(); // 空行 } }然后我们制作5款不同的飞碟，它们的大小、颜色不同，击中后得分亦不同：下面分别是第1个和第5个飞碟的情况：本人的“3D游戏编程与设计”系列合集，请访问：https://www.yizuodi.cn/category/3DGame/

基于Unity3D引擎构建简单的游戏场景
type: item
date: 2022-10-09T14:32:00+08:00
description: 本文主要基于资源商店中获取到的Fantasy Skybox FREE资源包，进行游戏场景构建，并为场景设计地形（有树木和草地等元素）首先我们从资源商店获取到Fantasy Skybox FREE资源包：https://assetstore.unity.com/packages/2d/textures-materials/sky/fantasy-skybox-free-18353然后在我们的项目中导入资源包（在包管理器中找到它，下载并导入）。导入完成后，我们在 窗口-渲染-光照 选项中，选择环境，选择天空盒材质以应用上述资源包中的材质。然后，我们在组件中找到上述资源包的SampleTerrain并添加，让我们的场景中有地形的存在，添加成功后效果如下：Unity Editor包含的地形(Terrain)功能，可以让我们添加地形，并对地形进行一些操作（地形升降、添加花草等），文档内容可见：https://docs.unity3d.com/cn/current/Manual/script-Terrain.html根据上述描述，在Fantasy Skybox FREE内置SampleTerrain的地形基础上，我们使用其“绘制细节”，里面的细节包含了两种草和一种花，可供我们直接使用，我们为场景添加后效果如下：另外，我们可能还需要一些树，Unity为我们提供了树编辑器(Tree Editor)，用于在编辑器内直接设计树。可见文档：https://docs.unity3d.com/cn/current/Manual/class-Tree.html在 游戏对象-3D对象-树 中，我们可以创建树，依据文档的指引，我们可以有一棵如下的树：我们为它的树枝和树叶加一些材质，就形成了一棵完整的树：添加到游戏里面，效果如下：当然，我们自行制作的树可能还不够美观，如果不喜欢的话，我们还可以选用资源商店中提供的资源包。比如使用Mobile Tree Package(https://assetstore.unity.com/packages/3d/vegetation/trees/mobile-tree-package-18866)资源包中的树，效果如下：这样，我们就构建了简单的游戏场景。本人的“3D游戏编程与设计”系列合集，请访问：https://www.yizuodi.cn/category/3DGame/

使用中国银行长城跨境通国际借记卡购汇与消费
type: item
date: 2022-10-08T18:10:00+08:00
description: 背景介绍作为普通的穷学生，有时候我们会需要进行境外消费（海淘等），但是许多境外的平台不支持卡组织为中国银联的银行卡（有时候也不支持Paypal），需要我们使用卡组织为万事达（MasterCard）或者VISA的银行卡。而通常我们可办理到的外币卡（或双币卡）都是信用卡，一方面学生很难办理到信用卡（允许学生办理的信用卡一般也为0额度，且为银联卡），另一方面办理信用卡会被查征信。为了解决我们的需求，这里就要介绍本文的主角——长城跨境通国际借记卡是中国银行（四大国有银行之一）发行的 VISA / MasterCard 多币种外标借记卡。不设申请门槛，支持网上申请和线下申请，适合学生等不具备申请信用卡条件的人员。温馨提示：1.Paypal支持绑定银联卡，在银行卡开启境外消费功能的前提下可进行外币消费（例如建行，可检索关键字：建行 app 开启境外境外交易功能），消费会以汇率折算为人民币扣除银行卡余额，无需使用外币卡绑定paypal即可支付外币账单。（请注意结算时使用Paypal的汇率还是银行的汇率，二者相差较大，详情请google之）2.办理中国银行长城跨境通国际借记卡，强烈建议拥有一张中国银行的一类卡。这是因为使用手机银行购汇需要使用本人的一类卡，否则则需要在线下柜台进行购汇，相比会及其的麻烦。（需要注意，目前一类卡较难办理）3.接上条，该卡不包含人民币账户，需要使用本人其他中国银行银行卡（银联卡）购汇后，通过手机银行转账功能转到该卡中。（国内外汇仅支持本人同名银行卡互转）如何申请此借记卡这不是本文的主要内容，请参考此链接。（更多卡片介绍、申卡用卡注意事项也请多多阅读此文）博主申请的是“中银万事达非人哉白泽借记卡”，通过上海分行公众号渠道申请。此卡非预制卡（卡片申请成功后卡片上会有你本人姓名拼音），申请通过后制卡需要等待若干时间。收到卡片后请到中行网点线下激活，如遇网点不配合激活，可到其他网点激活。如何购汇首先介绍几个要点：1.我国的外汇管制规定，每人每年拥有等值50000美元的便利化额度。（超出此值需要提供相关证明材料以进行购汇）2.购汇时有外汇和外钞可选，一般消费选择外汇即可（外钞会更贵）。3.境内个人外汇账户只能向本人同名账户转账（网上银行、手机银行上即可完成）。4.什么是银行买入价、银行卖出价？此价格是基于银行的立场上讲的，银行卖出价即银行卖给我们的价格，银行买入价即银行从我们这里买入的价格。银行卖出价比银行买入价要高，所以购买外汇后，结汇时可能会导致资金损失。中国银行的结汇购汇交易时间为北京时间每日7：00-23：00，请在此时间内进行结汇购汇操作。我们可以通过中国银行手机app或者“中行跨境GO”app进行结汇购汇操作（均需要绑定中国银行一类卡）。我们以手机银行为例，具体购汇流程：1.登录手机银行，搜索结汇购汇（或在首页点击“更多”，找到结汇购汇并点击），选择要购买的外币，可查看其价格走势。（初次购汇可能需要开通投资理财功能，请根据页面提示操作）2.在上述页面点击“买外币”。3.需要花费半分钟阅读“个人购汇申请书”，方能继续操作。（每次购汇均需要此步骤）4.选择购汇使用的银行卡，检查币种，钞汇选项选择“外汇”，输入想要购买的外币金额，检查预计花费的人民币金额。5.购汇用途请按照实际用途如实选择，一般我们的用途都是“海外购物”。6.确认后一般即购汇成功，你的中国银行一类卡中就已经拥有了刚刚购买金额的外币。购汇完成后，我们需要将外币从我们的一类卡转到跨境通卡中，操作如下：1.登录手机银行，首页选择转账，点击“我的账户”，选择自己的长城跨境通卡。2.更改币种为自己购得的外币币种（跨境通卡无人民币账户，请不要转人民币到此卡），然后输入金额，点击下一步。3.点击确认后，即完成将外币从我们的一类卡转到跨境通卡。此时在手机银行首页的账户管理中，便可以看到我们跨境通卡的余额中有该外币。消费实例——使用长城跨境通卡在Google Domain购买域名在Google Domain，我们可以选择新土耳其里拉结算，从而可以花费约合40-50人民币购买9年的6-9位纯数字的.xyz域名。首先访问Google Domain，使用自己的Google账号登录。然后更改自己所在国家为土耳其，以在支付时使用土耳其里拉结算。然后在左侧菜单选择“结算”，在管理结算方式-在付款中心管理您的付款资料和付款方式，点击右侧的“管理”，跳转到Google Pay的网页版。点击“付款方式”，再点击“添加付款方式”，输入借记卡号、到期时间、银行卡验证码CVC（请注意保护，等同于支付密码）、持卡人姓名、账单地址（可填写自己的实际地址）。成功添加付款方式后，在Google Domain的左侧菜单选择“获取新域名”，检索到自己喜欢的域名并加入购物车。请选择“是，添加到购物车”。然后…

基于Unity3D的物体抛物线运动实现
type: item
date: 2022-10-05T21:31:00+08:00
description: 本文主要涉及基于Unity3D的物体的抛物线运动实现。方法 1：直接修改对象的Transform属性using System.Collections; using System.Collections.Generic; using UnityEngine; public class Move : MonoBehaviour { void Start(){} void Update() { this.transform.position += Vector3.right * Time.deltaTime * 3; this.transform.position += Vector3.down * Time.deltaTime * 3; } }方法 2：使用向量Vector3的方法我们将对象的最新位置用Vector3向量来表示，然后将这个向量赋给对象。下面我们让对象水平方向匀速，垂直方向受重力（模拟）影响下落。using System.Collections; using System.Collections.Generic; using UnityEngine; public class Move : MonoBehaviour { float accumulateTime = 0; void Start(){} void Update() { accumulateTime += Time.deltaTime; //水平方向匀速运动 float x = 5 * accumulateTime; //垂直方向重力加速度下落运动 float y = 30 - 9.8f * 0.5f * Mathf.Pow(accumulateTime, 2); Vector3 pos = new Vector3(x, y, 0); if (pos.y >= 0) { transform.position = pos; } } }方法 3：通过Rigidbody组件移动物体Rigidbody组件可以让对象受物理引擎的控制。我们可以开启重力作用，并赋予物体一个水平速度，从而实现抛物线运动。using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(Rigidbody))] public class Move : MonoBehaviour { private Rigidbody rigidbody; private Vector3 initSpeed; void Start() { rigidbody = this.GetComponent<Rigidbody> (); initSpeed = new Vector3 (3, 0, 0); rigidbody.velocity = initSpeed; } void Update(){} }方法 4：通过CharacterController组件移动物体CharacterController，即角色控制器，我们可以用其提供的Move方法来实现抛物线运动。using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(CharacterController))] public class Move : MonoBehaviour { private CharacterController cc; private Vector3 speed; void Start() { cc = this.GetComponent<CharacterController> (); speed = new Vector3 (5, 0, 0); } void Update() { speed += 3 * Time.deltaTime * Vector3.down; cc.Move (speed * Time.deltaTime); } }本人的“3D游戏编程与设计”系列合集，请访问：https://www.yizuodi.cn/category/3DGame/