这里写自定义目录标题
- 官网地址
- 说明
- unity编辑器使用
- 创建项目
- 制作全景视频
- 添加图片
- 添加文字
- C#控制手柄操作
- 添加按钮(目前还存在问题,全景视频内缺少手柄对应的射线)
- 调用外部接口
- 对接百度语音识别
- 某些名词/单词解释说明
官网地址
oculus官网:https://developer.oculus.com/ unity官网:https://docs.unity3d.com/cn/2018.4/Manual/VideoPanoramic.html
说明
Unity 是实时3D互动内容创作和运营平台 。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助Unity将创意变成现实。 Unity平台提供一整套完善的软件解决方案 ,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备
unity编辑器使用
a)下载unity Hub(unity官网)
b)下载之后,右上角设置按钮,
i.常规:配置好安装路径,安装内部软件,语言为简体中文
许可证管理:激活许可证=》个人版本=》我不以专业身份用
(手机下载unity connect软件,以便与登陆电脑,激活许可证)
c) 在unity内部下载unity编辑器,在安装菜单中,现在下载2019版本。点击“安装”按钮,选择对应的版本,然后下一步,选中jdk。最少需要8G以上内存
上面的图我安装了多个版本
创建项目
1.在项目菜单,右上角点击新建,选择unity的版本
配置里面:setting页面把Text Compression:ASTC
Player settings:
player:other setting->color space->Linear
Minimum API Level ->Androwid 6.0
Graphics APIs内的Vulkan删除
Quality: Pixel Light Count->1
Anisotropic Texturex->Per Texturex
Anti Aliasing -> 4x Multi…
Soft Prticles->取消勾选
制作全景视频
- 首先在Sence中创建一个Sphere球体,并设置位置大小
Position:0,0,0
Scale:100,100,-100
2.创建一个SurfaceShader,右键Assets–>Create–>Shader–>SandardSurfaceShader
代码:(作用将球形转成从内部观看,翻转观看面)
Shader "InsideVisible" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
Cull front // ADDED BY BERNIE, TO FLIP THE SURFACES
LOD 100
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
// ADDED BY BERNIE:
v.texcoord.x = 1 - v.texcoord.x;
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.texcoord);
return col;
}
ENDCG
}
}
}
3.创建Render Texture文件,右键Assets–>Create–>Render Texture。同时更改分辨率参数也就是Size,改为:4960X2160
4.新建材质material,然后把SandardSurfaceShader拖到material上,然后把material拖到球sphere的属性上添加材质。
5.添加视频:
在project的assets内,拖入全景视频,最好是mp4格式文件,然后点击sphere,在inspector内点击add component,添加video player。然后将asstes内的视频拖到video player内的video clip内。
6.导入插件:window=>asset store=>搜索oculus Integration,然后下载插件,下载完成之后点击import. 然后在asstes内看到oculus,在里面找到VR=》prefabs-》把ovrcamerarig拖到场景中
设置:position:0,0,0 scale:1,1,1
第6条可能出现打包没有反应的问题,那就需要直接引入oculus Integration包,因为oculus Integration升级之后项目就可能不能打包了
7.打包配置一
file=>build setting=>点击Android=》点击switch Platorm
8.打包配置二
点击player Settings…=>player=>other settings=>Mininum API Level 设置为Android 6.0…
9.打包配置三
点击XR Plugin-in Management,然后install,完成之后选择oculus,
10.打包:
file=>build setting=>build=》选择文件打包成apk
添加图片
1.将图片文件拖进assets内
2.然后点击图片修改Texture Type为Sprite,失焦的时候点击确定
3.在Hieachy里面右击添加ui=>image,点击canvas->image,把assets内的图片拖进右边sounce Image。
4.将canvas的Render Model设置为Work space
5.然后自己在定位到摄像机前,设置图片大小和位置
添加文字
1.在Hieachy右击,UI=>text
2.点击canvas内的text,在Text=>text内可以输入自己想要的文字,如果中文显示不出来的话,需要下载中文字体包,然后导入进去。
3.拖动文字,或者设置position,将文字拖到相应的区域
4.将canvas的Render Model设置为Work space
5.修改字体大小:Font Size的时候,会出现字体模糊看不清,
解决办法:选中Hieachy中的canvas,在canvas Scaler内将Dynaic Pixels Unit设置大一点,越大文字越清晰(目前没找到多大是个界限,大概正常清晰度为70+)
6.在c#中如何修改当前文本的内容:
GameObject.Find(“Canvas/Text”).GetComponent<UnityEngine.UI.Text>().text = “这是切换之后的文字”;
C#控制手柄操作
下载编辑器visual studio(有更好的c#识别和自动提示功能。)
1.在assets内右键,create=>c#script。 创建一个脚本,命名为control。
2.在Hieachy中选中sphere,将control文件拖到sphere的右边作为组件添加
3.在visual studio中打开control文件,
4.如何获取相应的图片或者文字文本:
1)。定义:在c#代码中定义:public GameObject text;
2)。在unity中,点击sphere,查看当前的control文件,会多出来Text/Image等等,然后将Hieachy中需要控制的图片或者文本拖进后面对应的选择框中。这样就绑定了代码内的变量和unity内的虚拟物体
3)。control内的start相当于初始化加载内容,Update相当于每次操作的时候执行内容。在Update内控制手柄。
对应的手柄代码是:(结合官网和百度查看)
// “A”
OVRInput.Get(OVRInput.Button.One);
// B
OVRInput.Get(OVRInput.Button.Two);
// X
OVRInput.GetUp(OVRInput.RawButton.X);
// 摇杆按
OVRInput.Get(OVRInput.Get(OVRInput.Button.SecondaryThumbstick));
// 摇杆上下左右 Up/Down/Left/Right
OVRInput.Get(OVRInput.Get(OVRInput.Button.SecondaryThumbstickUp));
// 右手食指
OVRInput.Get(OVRInput.Get(OVRInput.Button.SecondaryIndexTrigger));
// 左手食指按一半以上
OVRInput.Get(OVRInput.RawButton.LIndexTrigger);
4).设置图片或者文本或者对应的虚拟物体的现实和隐藏:
text.SetActive(true); //text为定义的变量,true显示,false为隐藏
5).如果是文本,如何改变文本内的文字内容
GameObject.Find("Canvas/Text").GetComponent<UnityEngine.UI.Text>().text = "这是切换之后的文字";
添加按钮(目前还存在问题,全景视频内缺少手柄对应的射线)
1.在Hieachy中右键=》ui=>Button
2.点击Button,可以在右边更改他的宽高,定位等等,移动到camera对应的屏幕前
3.展开Button,可以点击Text,在右边修改按钮文字内容。或者直接将assets的图片拖到Button上,用图片覆盖在Button上。
4.点击Button,在右侧的Inspector内,Button=>On Click内:
1)点击+号,添加一条按钮事件,
2)第一个下拉框选择Runtime Only
3)第二个下拉框选择GameObjext->AetActive(表示显示隐藏)
4)。第三个框内拖进去一个想要控制Hieachy内的虚拟物体,虚拟物体必须是之前添加在Hieachy中的
5)。checkbox选中表示点击这个按钮之后该虚拟物体现实,取消勾选表示点击该按钮之后该虚拟物体隐藏。
调用外部接口
定义接口参数类型:
[System.Serializable]
public class JsonObj
{
public string bdNameSpace;
public Data[] data;
}
[System.Serializable]
public class Data
{
public string name;
public string slogan;
}
接口函数:
public IEnumerator GetRequest()
{
string url = "http://bip.fat.qa.pab.com.cn/common-components/sdk/common/global/qa/product_list.json";
using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
{
yield return webRequest.SendWebRequest();
if (webRequest.isHttpError || webRequest.isNetworkError)
{
Debug.LogError(webRequest.error + "\n" + webRequest.downloadHandler.text);
}
else
{
JsonObj response = JsonUtility.FromJson<JsonObj>(webRequest.downloadHandler.text);
string data = "";
foreach (var v in response.data)
{
data += v.name + "---";
};
GameObject.Find("Canvas/Text").GetComponent<UnityEngine.UI.Text>().text = data;
}
}
}
接口函数调用:(在Update函数内调用)
void Update()
{
if (OVRInput.Get(OVRInput.Button.SecondaryIndexTrigger))
{//右手食指按钮操作
StartCoroutine(GetRequest());//调用接口函数
}
}
对接百度语音识别
1.下载插件: NugetForUnity.3.0.1
2.unity中导入文件:右上角Assets-》import package=>custom package,然后选中下载的文件
3.加载完成之后,左上角会出现菜单NuGet菜单,点击这个菜单,然后点击Manage NuGet Package,输入baidu.ai,然后下载第一个(带有百度icon的),点击后面的install,安装完成之后文字会变成uninstall
4.语音识别代码:
首先需要在百度官网上注册并获取:
APP_ID, API_KEY , SECRET_KEY
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//using Wit.BaiduAip.Speech;
using Baidu.Aip.Speech;
using Newtonsoft.Json.Linq;
using System.IO;
public class videoControl3 : MonoBehaviour
{
public Text text;
private const int lengthSec = 10; //录制时长
private const int frequency = 16000; //码率
private AudioClip _clipRecord;
public bool isAsync = false;//语音识别是否开启
[Obsolete]
void Start()
{
}
void Update()
{
if (OVRInput.GetDown(OVRInput.Button.Two))
{
Debug.Log("按键B");
if (!isAsync)
{//启动语音识别
text.text = "22222";
isAsync = true;
OnClickStartButton();
}
else
{//关闭语音识别
text.text = "33333";
isAsync = false;
OnClickStopButton();
}
}
}
private void OnClickStartButton()
{
var mDeviceName = Microphone.devices[0];
_clipRecord = Microphone.Start(mDeviceName, false, lengthSec, frequency);
text.text = "Listening...";
}
private void OnClickStopButton()
{
text.text = "Recognizing...";
Microphone.End(null);
var data = ConvertAudioClipToPCM16(_clipRecord);
// 设置APPID/AK/SK
string APP_ID = "自己的APP_ID";
string API_KEY = "自己的API_KEY";
string SECRET_KEY = "自己的SECRET_KEY";
var client = new Baidu.Aip.Speech.Asr(APP_ID, API_KEY, SECRET_KEY);
// 可选参数
var options = new Dictionary<string, object> {
{ "dev_pid", 1537 }
};
client.Timeout = 120000; // 若语音较长,建议设置更大的超时时间. ms
JObject result = client.Recognize(data, "pcm", 16000, options);
string x = (string)result["result"][0];
text.text = x;
}
public static byte[] ConvertAudioClipToPCM16(AudioClip clip)
{
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var samples_int16 = new short[samples.Length];
for (var index = 0; index < samples.Length; index++)
{
var f = samples[index];
samples_int16[index] = (short)(f * short.MaxValue);
}
var byteArray = new byte[samples_int16.Length * 2];
Buffer.BlockCopy(samples_int16, 0, byteArray, 0, byteArray.Length);
return byteArray;
}
}
某些名词/单词解释说明
- 1.各个场景内的固有属性解释
Cube:正方体
sphere:球体
Capsule:球体两端拉长
Cylinder:圆珠
Plane:水平平面
Quad:垂直平面
Terrain:地板
Tree:树
2.Inspector场景
Cube:申明一个模型
Box Collider:盒碰撞器
Use pravity:受重力影响
Rigidbody:添加的组件,即拥有物理的身体(刚体),接受重力影响,但是还没有形状,所以不能碰撞
is kinematic表示是否可以运动
Use Gravity:是否有重力作用
Box collider:添加的组件,碰撞组件后才拥有物理形状,开始接受空间刚体碰撞
3.position:
y上下(+y上),
z前后(+z前)
x向右(0,0,1)
back(0,0,-1),
down(0,-1,0) ,
forward(0,0,1),
left(-1,0,0),
one(1,1,1),
right(1,0,0),
up(0,1,0),
zero(0,0,0)
4.各个手柄对应的代码
// “A”
OVRInput.Get(OVRInput.Button.One);
// B
OVRInput.Get(OVRInput.Button.Two);
// X
OVRInput.GetUp(OVRInput.RawButton.X);
// 摇杆按
OVRInput.Get(OVRInput.Get(OVRInput.Button.SecondaryThumbstick));
// 摇杆上 Up/Down/Left/Right
OVRInput.Get(OVRInput.Get(OVRInput.Button.SecondaryThumbstickUp));
// 右手食指
OVRInput.Get(OVRInput.Get(OVRInput.Button.SecondaryIndexTrigger));
// 左手食指按一半以上
OVRInput.Get(OVRInput.RawButton.LIndexTrigger);