热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

微软Hololens学院教程-Holograms101:IntroductionwithDevice【微软教程已经更新,本文是老版本】

这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https:developer.microsoft.comEN-USWINDOWSHOLOGRAPHICho

这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/holograms_101

这篇文章将通过一个完整的实例来了解设备的核心特性,包括凝视,手势,声音输入和空间声音与空间映射。
先决条件

1.一个 Windows 10 PC 并安装有相应的软件tools installed..
2. 开发者模式的HoloLensconfigured for development. .

项目文件

1.下载此项目所需文件files。

2.将其保存在桌面或者其他易于找到的位置, 保持文件名为 Origami.

章节 1.“Holo”world 

目标
     1设置Unity。
     2制作全息对象。
     3看到你做的全息对象。
教程
  • 打开 Unity.
  • 选择 Open.
  • 选择本地项目 Origami 文件夹
  • 选择 Origami 点击 .
  • 由于 Origami项目中不含有场景, 需要将默认的场景保存成项目场景: 打开File / Save Scene As.
  • 将新场景命名为 Origami 然后点击保存按钮.

设置主相机

  • Hierarchy 面板中, 选择Main Camera.
  • Inspector 设置 transform position 为 0,0,0.
  • 找到Clear Flags 属性, 打开下拉列表将 Skybox 改为Solid color.
  • 点击 Background 的颜色选择器.
  • 设置 R, G, B,  A 都为 0.

配置场景

  1. Hierarchy 面板中, 点击Create -》 Create Empty.
  2. 右击 新GameObject 为它重新命名为 OrigamiCollection.
  3. 在 Project 面板中选择Holograms 文件夹,并双击打开:
  4. 拖拽Stage 到 Hierarchy面板中 ,使其成为 OrigamiCollection的子对象.
  5. 同理拖拽Sphere1
  6. 同理拖拽 Sphere2
  7. 删除Hierarchy 面板中的Directional Light
  8. Holograms 文件夹中, 拖拽 Lights 到Hierarchy面板中.
  9. Hierarchy中, 选中 OrigamiCollection.
  10. Inspector面板中, 设置其transform position 为0, -0.5, 2.0.
  11. 点击Play 按钮 来预览你的全息对象.
  12. 你会在你的预览窗口看到你的Origami 对象.
  13. 再次点击 Play 按钮停止预览模式.

将项目从 Unity 导出到Visual Studio

  • 在Unity中选择File > Build Settings.
  •  在Platform 列表下选择 Windows Store 然后点击Switch Platform.
  • 设置 SDK 为 Universal 10 ,设置 Build Type 为D3D.
  • 勾选 Unity C# Projects.
  • 点击 Add Open Scenes 来添加场景.
  • 点击 Build.
  • 创建一个新的文件夹命名为 "App".
  • 单击 App 文件夹.
  •  选中此文件夹.
  • Unity发布完成后, 一个新的 File Explorer 窗口将出现.
  • 打开 App 文件夹.
  • 双击打开Origami.sln.
  • 在 Visual Studio上部工具栏中, 将 Debug 设置为 Release ,将 ARM 变为 X86.
  • 点击 Device button旁边的箭头, 然后选择 Remote Device.
    • 设置 Address 为你的hololens的 IP 地址 . 如果你不知道你的设备的IP 地址, 开启hololens,选择 Settings > Network & Internet > Advanced Options 查看或者询问 Cortana "Hey Cortana, What's my IP address?"
    • 将 Authentication Mode 设置为 Universal.
    • 点击 Select
  • 点击 Debug > Start Without debugging 或者点击 Ctrl + F5. 如果这是你第一次发布应用到hololens, 你需要配对,具体需要输入设备的PIN码,在设置-》update-》for developers-》paired devices中查看。 pair it with Visual Studio.
  •  然后Origami项目开始发布部署到你的设备上并运行 .
  • 请戴上你的hololens来欣赏你发布的全息应用吧.

章节 2.Gaze 凝视
这一章将介绍hololens交互的三大方式的第一种,凝视

目标

  • 使用一个光标来可视化你的凝视点.

说明

  • 回到 Unity 项目, 如果 Build Settings 窗口还开着请把它关掉 .
  • Project 面板中选择Holograms文件夹.
  • 拖拽 Cursor 对象 到 Hierarchy 面板 的根节点下.
  •  双击Cursor 对象近距离查看、.
  • 在 Project 面板下右击Scripts 文件夹.
  •  点击Create sub-menu.
  •  选择C# Script.
  •  给脚本命名 WorldCursor
  •  选择 Hierarchy  面板中的Cursor 对象.
  • 拖拽 WorldCursor 脚本到 Inspector 面板中.
  • 双击WorldCursor 脚本用 Visual Studio打开.
  •  复制粘贴以下代码到WorldCursor.cs 然后保存.
WorldCursor.cs
using UnityEngine;

public class WorldCursor : MonoBehaviour
{
private MeshRenderer meshRenderer;

// Use this for initialization
void Start()
{
// Grab the mesh renderer that's on the same object as this script.
meshRenderer = this.gameObject.GetComponentInChildren();
}

// Update is called once per frame
void Update()
{
// Do a raycast into the world based on the user's
// head position and orientation.
var headPosition = Camera.main.transform.position;
var gazeDirection = Camera.main.transform.forward;

RaycastHit hitInfo;

if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
{
// If the raycast hit a hologram...
// Display the cursor mesh.
meshRenderer.enabled = true;

// Move the cursor to the point where the raycast hit.
this.transform.position = hitInfo.point;

// Rotate the cursor to hug the surface of the hologram.
this.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
}
else
{
// If the raycast did not hit a hologram, hide the cursor mesh.
meshRenderer.enabled = false;
}
}
}
WorldCursor
  •  从新发布APP,通过File > Build Settings.从文件>构建设置重建应用程序。
  •   返回到以前用于部署到HoloLens的Visual Studio解决方案
  • 出现提示时,选择“重新加载所有”。
  • 单击调试 - >开始无调试或按Ctrl + F5。
  • 现在看看场景,注意光标如何与对象的形状进行交互。

章节 3.手势

 这一章,将添加手势支持,当用户选择场景中的纸球时,通过Unity设置有物理重力的纸球会掉落。

目标

  • 通过手势控制场景中的全息对象.

说明

  •  在Scripts 文件夹, 创建一个新的脚本并命名为 GazeGestureManager.
  •  拖拽GazeGestureManager 脚本到Hierarchy面板中的 OrigamiCollection 对象上  .
  • 用VS打开GazeGestureManager 脚本,将以下代码粘贴其中:
GazeGestureManager.cs
using UnityEngine;
using UnityEngine.VR.WSA.Input;

public class GazeGestureManager : MonoBehaviour
{
public static GazeGestureManager Instance { get; private set; }

// Represents the hologram that is currently being gazed at.
public GameObject FocusedObject { get; private set; }

GestureRecognizer recognizer;

// Use this for initialization
void Awake()
{
Instance
= this;

// Set up a GestureRecognizer to detect Select gestures.
recognizer = new GestureRecognizer();
recognizer.TappedEvent
+= (source, tapCount, ray) =>
{
// Send an OnSelect message to the focused object and its ancestors.
if (FocusedObject != null)
{
FocusedObject.SendMessageUpwards(
"OnSelect");
}
};
recognizer.StartCapturingGestures();
}

// Update is called once per frame
void Update()
{
// Figure out which hologram is focused this frame.
GameObject oldFocusObject = FocusedObject;

// Do a raycast into the world based on the user's
// head position and orientation.
var headPosition = Camera.main.transform.position;
var gazeDirection = Camera.main.transform.forward;

RaycastHit hitInfo;
if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
{
// If the raycast hit a hologram, use that as the focused object.
FocusedObject = hitInfo.collider.gameObject;
}
else
{
// If the raycast did not hit a hologram, clear the focused object.
FocusedObject = null;
}

// If the focused object changed this frame,
// start detecting fresh gestures again.
if (FocusedObject != oldFocusObject)
{
recognizer.CancelGestures();
recognizer.StartCapturingGestures();
}
}
}
GazeGestureManager
  •  在Scripts 文件夹下创建一个新的脚本命名为 SphereCommands.
  •  展开Hierarchy面板中的OrigamiCollection 对象.
  •  拖拽SphereCommands 脚本到 Sphere1 对象上.
  •  拖拽SphereCommands 脚本到 Sphere2 对象上.
  • 用VS打开这个脚本并编辑,将以下代码复制粘贴到其中:
SphereCommands.cs
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
// Called by GazeGestureManager when the user performs a Select gesture
void OnSelect()
{
// If the sphere has no Rigidbody component, add one to enable physics.
if (!this.GetComponent())
{
var rigidbody = this.gameObject.AddComponent();
rigidbody.collisionDetectionMode
= CollisionDetectionMode.Continuous;
}
}
}
SphereCommands
  • 再一次导出,发布部署 app 到你的 HoloLens.
  • 看着一个球.
  • 使用手势点击观看其下落效果.

章节 4.语音

这一章将添加两个语音指令,“Reset world”来返回初始场景状态,“Drop sphere”使得球体下落。

目标

  • 添加语音指令.
  • 创建一个对语音指令做出反应的全息对象.

说明

  •  在Scripts 文件夹下, 创建一个新的脚本并命名为 SpeechManager.
  •  拖拽SpeechManager 脚本到 OrigamiCollection 对象上
  •  用VS打开SpeechManager 脚本.
  • 复制粘贴以下代码到 SpeechManager.cs 中然后保存:
SpeechManager.cs
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.Speech;

public class SpeechManager : MonoBehaviour
{
KeywordRecognizer keywordRecognizer
= null;
Dictionary
<string, System.Action> keywords = new Dictionary<string, System.Action>();

// Use this for initialization
void Start()
{
keywords.Add(
"Reset world", () =>
{
// Call the OnReset method on every descendant object.
this.BroadcastMessage("OnReset");
});

keywords.Add(
"Drop Sphere", () =>
{
var focusObject = GazeGestureManager.Instance.FocusedObject;
if (focusObject != null)
{
// Call the OnDrop method on just the focused object.
focusObject.SendMessage("OnDrop");
}
});

// Tell the KeywordRecognizer about our keywords.
keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());

// Register a callback for the KeywordRecognizer and start recognizing!
keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
keywordRecognizer.Start();
}

private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
{
System.Action keywordAction;
if (keywords.TryGetValue(args.text, out keywordAction))
{
keywordAction.Invoke();
}
}
}
SpeechManager
  •  用VS打开SphereCommands 脚本.
  • 更新为如下代码:
SphereCommands.cs
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
Vector3 originalPosition;

// Use this for initialization
void Start()
{
// Grab the original local position of the sphere when the app starts.
originalPosition = this.transform.localPosition;
}

// Called by GazeGestureManager when the user performs a Select gesture
void OnSelect()
{
// If the sphere has no Rigidbody component, add one to enable physics.
if (!this.GetComponent())
{
var rigidbody = this.gameObject.AddComponent();
rigidbody.collisionDetectionMode
= CollisionDetectionMode.Continuous;
}
}

// Called by SpeechManager when the user says the "Reset world" command
void OnReset()
{
// If the sphere has a Rigidbody component, remove it to disable physics.
var rigidbody = this.GetComponent();
if (rigidbody != null)
{
DestroyImmediate(rigidbody);
}

// Put the sphere back into its original local position.
this.transform.localPosition = originalPosition;
}

// Called by SpeechManager when the user says the "Drop sphere" command
void OnDrop()
{
// Just do the same logic as a Select gesture.
OnSelect();
}
}
SphereCommands
  • 从新导出发布部署APP到 HoloLens.
  •  看着其中一个球,说"Drop Sphere".
  •  说"Reset World" 使他们回到初始的位置.

章节 5.空间声音

这一章,我们会为APP添加音乐,在特定操作上触发声音效果,我们将使用spatial sound特性给声音一个3D空间位置。

目标

  • 在你的世界中听见全息对象.

说明

  •  在Unity 选择 Edit > Project Settings > Audio
  • 在右侧的 Inspector 面板中, 找到 Spatializer Plugin 设置然后选择 MS HRTF Spatializer.
  • 在 Project 面板下从Holograms文件夹, 拖拽 Ambience 对象到 到 Hierarchy 面板下的OrigamiCollection 对象上.
  •  选择OrigamiCollection  对象,在右侧的Inspector面板 中找到Audio Source 组件. 改变以下属性值:
    • 选择 Spatialize property.
    •  选择Play On Awake.
    •  将Spatial Blend 改成 3D
    •  选择Loop property.
    • 展开 3D Sound Settings,  在Doppler Level 输入0.1.
    •  设置Volume RolloffCustom Rolloff.
  •  在Scripts 文件夹下, 创建一个新的脚本并命名为 SphereSounds.
  •  拖拽SphereSounds 脚本到 Sphere1Sphere2 对象上.
  •  用VS打开SphereSounds 脚本, 更新为以下代码并保存.
SphereSounds.cs
using UnityEngine;

public class SphereSounds : MonoBehaviour
{
AudioSource audioSource
= null;
AudioClip impactClip
= null;
AudioClip rollingClip
= null;

bool rolling = false;

void Start()
{
// Add an AudioSource component and set up some defaults
audioSource = gameObject.AddComponent();
audioSource.playOnAwake
= false;
audioSource.spatialize
= true;
audioSource.spatialBlend
= 1.0f;
audioSource.dopplerLevel
= 0.0f;
audioSource.rolloffMode
= AudioRolloffMode.Custom;

// Load the Sphere sounds from the Resources folder
impactClip = Resources.Load("Impact");
rollingClip
= Resources.Load("Rolling");
}

// Occurs when this object starts colliding with another object
void OnCollisionEnter(Collision collision)
{
// Play an impact sound if the sphere impacts strongly enough.
if (collision.relativeVelocity.magnitude >= 0.1f)
{
audioSource.clip
= impactClip;
audioSource.Play();
}
}

// Occurs each frame that this object continues to collide with another object
void OnCollisionStay(Collision collision)
{
Rigidbody rigid
= this.gameObject.GetComponent();

// Play a rolling sound if the sphere is rolling fast enough.
if (!rolling && rigid.velocity.magnitude >= 0.01f)
{
rolling
= true;
audioSource.clip
= rollingClip;
audioSource.Play();
}
// Stop the rolling sound if rolling slows down.
else if (rolling && rigid.velocity.magnitude <0.01f)
{
rolling
= false;
audioSource.Stop();
}
}

// Occurs when this object stops colliding with another object
void OnCollisionExit(Collision collision)
{
// Stop the rolling sound if the object falls off and stops colliding.
if (rolling)
{
rolling
= false;
audioSource.Stop();
}
}
}
SphereSounds
  • 保存脚本,返回到Unity中.
  • 导出发布并部署 app 到你的 HoloLens.
  • 移动远近来感受声音的变化.

章节 6.空间映射

现在我们将使用空间映射特性将游戏板放置在现实世界中的真实对象上。

目标

  • 把你的现实世界变成一个虚拟世界.
  • 把你的全息图放在你想把它放置的位置.

步骤

  •  在Unity 中, 点击Project 面板下的 Holograms 文件夹.
  • Spatial Mapping asset 拖拽到 Hierarchy面板的根节点.
  •  点击Hierarchy 面板下的Spatial Mapping 对象  .
  • 在右侧的 Inspector 面板, 改变如下设置:
    • 选择 Draw Visual Meshes box.
    •  定位到Draw Material 然后点击它右侧的圆. 在顶部的搜索字段中键入“wireframe”。单击结果,然后关闭窗口。执行此操作时,Draw Material的值应设置为线框.
  • 导出,发布并将应用程序部署到您的HoloLens。   
  • 当应用程序运行时,线框网格将覆盖你的现实世界。
  • 观看滚动球体将如何从平台掉落到地板上!

现在,我们将向您展示如何将OrigamiCollection移动到新位置:

  •  在Scripts 文件夹下, 创建一个新的脚本并命名为 TapToPlaceParent.
  •  在Hierarchy 面板下,展开 OrigamiCollection 然后选择 Stage 对象.
  •  拖拽TapToPlaceParent 脚本到 Stage 对象上.
  •  用VS打开TapToPlaceParent 脚本, 更新为如下代码:
TapToPlaceParent.cs
using UnityEngine;

public class TapToPlaceParent : MonoBehaviour
{
bool placing = false;

// Called by GazeGestureManager when the user performs a Select gesture
void OnSelect()
{
// On each Select gesture, toggle whether the user is in placing mode.
placing = !placing;

// If the user is in placing mode, display the spatial mapping mesh.
if (placing)
{
SpatialMapping.Instance.DrawVisualMeshes
= true;
}
// If the user is not in placing mode, hide the spatial mapping mesh.
else
{
SpatialMapping.Instance.DrawVisualMeshes
= false;
}
}

// Update is called once per frame
void Update()
{
// If the user is in placing mode,
// update the placement to match the user's gaze.

if (placing)
{
// Do a raycast into the world that will only hit the Spatial Mapping mesh.
var headPosition = Camera.main.transform.position;
var gazeDirection = Camera.main.transform.forward;

RaycastHit hitInfo;
if (Physics.Raycast(headPosition, gazeDirection, out hitInfo,
30.0f, SpatialMapping.PhysicsRaycastMask))
{
// Move this object's parent object to
// where the raycast hit the Spatial Mapping mesh.
this.transform.parent.position = hitInfo.point;

// Rotate this object's parent object to face the user.
Quaternion toQuat = Camera.main.transform.localRotation;
toQuat.x
= 0;
toQuat.z
= 0;
this.transform.parent.rotation = toQuat;
}
}
}
}
TapToPlaceParent
  • 导出,构建和部署应用程序.
  • 现在,您现在应该能够通过注视它,使用选择手势,然后移动到一个新的位置,并再次使用选择手势,将对象放在特定的位置。

章节 7.全息的乐趣

目标

  • 显示全息对象背后的世界入口的效果.

步骤

  • 在 Project 面板下打开Holograms 文件夹:
    •  拖拽Underworld 到 Hierarchy 面板下成为 OrigamiCollection 的孩子.
  • Scripts 文件夹下, 创建一个新的脚本并命名为 HitTarget.
  •  在Hierarchy 面板下, 展开 OrigamiCollection.
  •  展开Stage 对象然后选择 Target 对象 (blue fan).
  • 拖拽HitTarget 脚本到 Target 对象上.
  •  用VS打开HitTarget 脚本, 更新为以下代码:
HitTarget.cs
using UnityEngine;

public class HitTarget : MonoBehaviour
{
// These public fields become settable properties in the Unity editor.
public GameObject underworld;
public GameObject objectToHide;

// Occurs when this object starts colliding with another object
void OnCollisionEnter(Collision collision)
{
// Hide the stage and show the underworld.
objectToHide.SetActive(false);
underworld.SetActive(
true);

// Disable Spatial Mapping to let the spheres enter the underworld.
SpatialMapping.Instance.MappingEnabled = false;
}
}
HitTarget
  • 在Unity, 选择 Target 对象.
  • Hit Target 组件中可见两个公共属性, 需要引用场景中的对象:
    • 拖拽Hierarchy 面板下的 Underworld 对象到 Hit Target 组件下的 Underworld 属性中.
    • 拖拽Hierarchy 面板下的 Stage对象到 Hit Target 组件下的 Object to Hide 属性中。
  • 导出发布部署 app.
  •  将折纸集合放在地板上,然后使用选择手势使球体下降。
  • 当球碰到目标(blue fan)时,将发生爆炸。收集将被隐藏,一个洞会出现。

原文链接:https://developer.microsoft.com/en-us/windows/holographic/holograms_101

如有翻译上的错误请指正,谢谢


推荐阅读
  • 本文介绍了在Mac上安装Xamarin并使用Windows上的VS开发iOS app的方法,包括所需的安装环境和软件,以及使用Xamarin.iOS进行开发的步骤。通过这种方法,即使没有Mac或者安装苹果系统,程序员们也能轻松开发iOS app。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Windows 10中没有Documents and Settings文件夹怎么办?
    在Windows 10系统中找不到Documents and Settings文件夹,本文介绍了几种操作方法,包括查找临时文件夹、显示隐藏文件、复制文件夹地址等。同时解释了Windows 10中停用Documents and Settings文件夹的原因,并指出了替代的文件夹路径。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 本文讨论了如何在dotnet桌面(Windows)应用程序中添加图标。作者提到可以使用dotnet命令行工具与resource.rc文件一起使用来为标准.NET核心应用程序添加图标。作者还介绍了在创建控制台应用程序时如何编辑projeto1.csproj文件来添加图标。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 如何搭建Java开发环境并开发WinCE项目
    本文介绍了如何搭建Java开发环境并开发WinCE项目,包括搭建开发环境的步骤和获取SDK的几种方式。同时还解答了一些关于WinCE开发的常见问题。通过阅读本文,您将了解如何使用Java进行嵌入式开发,并能够顺利开发WinCE应用程序。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • 大坑|左上角_pycharm连接服务器同步写代码(图文详细过程)
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了pycharm连接服务器同步写代码(图文详细过程)相关的知识,希望对你有一定的参考价值。pycharm连接服务 ... [详细]
  • 其实之前也有下载过完整的android源码,但是从来没有对这个做过一些总结,在加上最近需要经常去看,索性就在从新下载,编译一下,其实这些东西官网上面都有。http:sou ... [详细]
  • 微信商户扫码支付 java开发 [从零开发]
    这个教程可以用作了解扫码支付的整体运行过程,已经实现了前端扫码,记录订单,回调等一套完整的微信扫码支付。相关链接:微信支 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了markdown[软件代理设置]相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 现在比较流行使用静态网站生成器来搭建网站,博客产品着陆页微信转发页面等。但每次都需要对服务器进行配置,也是一个重复但繁琐的工作。使用DockerWeb,只需5分钟就能搭建一个基于D ... [详细]
author-avatar
娜丷衣阵风丶
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有