VR初始化
SteamVR_Input类可以静态引用每个动作和动作集,在每个动作集中,可以找到其包含的动作的引用。
public SteamVR_Input_Sources source = SteamVR_Input_Sources.Any; //获取VR控制器发出的动作
SteamVR 2.0将动作抽象为以下6种类型,简介如下:
- Boolean类型的动作代表只有两种状态的动作——True或False,比如抓取(Grab)动作,只有抓取或未抓取两种状态,不存在中间状态。在Unity中对应类为SteamVR_Action_Boolean。
public SteamVR_Action_Boolean spawn; //用来判断VR控制器做出的选择是否正确
-
Single类型的动作能够返回0~1之间的数值,比如 Trigger 键按下到松开的过程。在Unity中对应类为SteamVR_Action_Single。
-
Vector2类型动作能够返回二维数,比如Touchpad上的触摸或手柄摇杆。使用这样的数值能够控制物体在四个方向的运动,典型的应用时使用Touchpad控制无人机或小车的运动。在Unity中对应类为SteamVR_Action_Vector2。
-
Vector3类型的动作能够返回三维数值,在Unity中对应类为SteamVR_Action_Vector3。
-
Pose类型的动作表示三维空间中的位置和旋转,一般用于跟踪VR控制器。在Unity中对应类为SteamVR_Action_Pose。
-
Skeleton类型的动作能够获取用户在持握手柄控制器时的手指关节数据,通过返回数据,结合手部渲染模型,能够更加真实的呈现手部在虚拟世界的姿态,虽然不及像LeapMotion等设备获取手指输入那样精确,但是足以获得良好的沉浸感。在Unity中对应类为SteamVR_Action_Skeleton。
SteamVR_Behavior_Pose来获取控制器的位置和旋转
private SteamVR_Behaviour_Pose trackedObj; //获取VR控制器的位置和旋转
SteamVR_RenderModel来显示控制器的3d模型,该模型将通过按键来动画
声音初始化
AudioSource
AudioSource 是 Unity 中的 Audio 组件,其主要用来播放游戏场景中的 AudioClip,AudioClip 就是导入到 Unity 中的声音文件。Unity 可导入的音频文件格式有 .aif,.wav,.mp3和.ogg。此外,Audio Source 还可以设置一些播放声音的效果,增强游戏场景中的声音效果。
public AudioSource audio; //播放声音
private AudioClip startSound; //开场音乐
private AudioClip selectDirSound; //选择时的音乐
private AudioClip wrongSound; //出错音乐
private AudioClip achieveSound; //成功音乐
其他初始化
private TrainingRecord record; //训练记录
private SceneTask sceneTask; //场景任务
private ArrayList task; //任务列表,ArrayList:引入命名空间: using System.Collections
private int taskIndex; //任务索引
private Vector3[] walkablePoints; //三维数组,表示空间点
private float[][] W;
private ArrayList screenTips; //场景提示
private int screenTipsIndex; //场景提示索引
private ArrayList soundTips; //声音提示
private NavMeshAgent p; //实现点击任意点寻路
private bool createArrow; //寻路箭头
private bool showScreenTip; //场景显示提示
private Transform camera; //任何一个GameObject身上都有Transform组件,它包含了该GameObject的位置(position),方向(rotate),大小(scale)。如果希望在游戏中更 新玩家位置、设置相机观察角度,都免不了要和Transform组件打交道。
private Ray ray; //射线是在三维世界中从一个点沿一个方向发射的一条无限长的线。在射线的轨迹上,一旦与添加了碰撞器的模型发生碰撞,将停止发射。我们可以利用射线实现子弹击中目标的检测,鼠标点击拾取物体等功能。
private RaycastHit hit; //射线碰撞
private bool isRayCast; //判断光线投射
private int playerPoint; //当前位置
private int nextPoint; //下一步位置
private bool walking; //判断是否行走
private bool rehearse; //
private float threeSecondsTimer;
private Vector3 playerOriginalPosition; //用户初始位置
private Vector3 playerballOriginalPosition; //
ArrayList
SceneTaskDictionary
函数
唤醒函数、开始函数、更新函数
Awake()、Start()、Update()
- 当脚本被加载时,会自动调用Awake()和Start()这2个函数场景启动时,Awake函数总是在任何Start函数调用前调用(场景中的每个对象都调用一次)。
- Awake只在预置物被实例化后才调用。·如果一个游戏对象在程序启动期间是未激活的,则不会调用Awake,直到该对象被激活,或绑定在对象上的任意脚本的函数被调用。
- Awake是最先被调用的,即使脚本组件不启用,最好用于初始化脚本和资源配置。
- start()只在脚本实例启用后第一帧刷新前被调用。 Start在Update第一帧调用前被调用,脚本必须为激活状态。·Start在Awake之后,调用第一个Update之前被调用,且脚本必须为激活状态。·这意味着你可以把脚本激活后要做的所有事都放在Start中实现。从而可以将一些初始化代码推后在必要时进行。
唤醒函数
handle.GetComponent<SteamVR_Behaviour_Pose>(); //获取手柄控制器触发事件,handle为左或右的手柄。
SceneTaskDictionary
walkablePoints表示位置点,有可达点和干扰点。
walkablePoints[0] = new Vector3(-23, 0, -32);
w表示可达的点之间的联系
W = new float[][]{
// 0 1 2 3 4 5 6 7 8
new float[]{ 0, 1, -1, -1, -1, 1, 1, -1, -1, -1},//0到各个点 值为1表示可达
new float[]{ -1, 0, 1, -1, -1, -1, -1, 1, -1, -1},//1到各个点
new float[]{ -1,-1, 0, 1, -1, -1, -1, -1, 1, -1},//2到各个点
new float[]{ -1,-1, -1, 0, 1, -1 ,-1, -1, -1, 1},//3到各个点
new float[]{ -1,-1, -1, -1, 0, -1 ,-1, -1, -1, -1},//4到各个点
};
Component
- 添加
GameObect.AddComponent(); - 删除
Destroy(GameObect.GetComponent());
LineRenderer线渲染器主要是用于在3D中渲染线段,虽然我们也可以使用GL图像库来渲染线段,但是使用LineRenderer我们可以对线段进行更多的操作,例如:设置颜色,宽度等。
NavMeshAgent可与快速实现点击任意点寻路。
resource
Resources.Load<AudioClip>("String"); //调用Resources方法加载AudioClip资源
Resources.Load<>();
- 读取文件时的根目录是 Assets/Resources,所有资源文件都放在该文件夹下,命令中的路径从 Resources 文件夹里开始写。
- 用 / 表示子文件夹。
- 读取的文件不要加文件的后缀。
- Load 后 <> 中写入读取的类型。
举个例子,如果我们想要读取音频文件 Assets/Resources/AudioClips/1.wav,那么命令写作
string fname = "AudioClips/1";
AudioClip clip = Resources.Load<AudioClip>(fname);
本文文件所在位置:D:\MCI_VR\MCI_new\building\Assets\Resources
又比如想要读取一个混音文件 Assets/Resources/AudioMixerGroup.mixer,同上写作
string fname = "AudioMixerGroup";
AudioMixer mixer = Resources.Load<AudioMixer>(fname);
开始函数
record = TrainingRecord.GetTrainingRecord(); //获取训练记录
TrainingRecord函数
MysqlObject函数
OpenSql()打开数据库函数:
String.Format (String, Object) 将指定的 String 中的格式项替换为指定的 Object 实例的值的文本等效项。
String.Format (String, Object[]) 将指定 String 中的格式项替换为指定数组中相应 Object 实例的值的文本等效项。
String.Format (IFormatProvider, String, Object[]) 将指定 String 中的格式项替换为指定数组中相应 Object 实例的值的文本等效项。指定的参数提供区域性特定的格式设置信息。
String.Format (String, Object, Object) 将指定的 String 中的格式项替换为两个指定的 Object 实例的值的文本等效项。
String.Format (String, Object, Object, Object) 将指定的 String 中的格式项替换为三个指定的 Object 实例的值的文本等效项。
数据库插入
string query = "INSERT INTO Record(patient_ID,scene_ID,train_datetime,train_long,total_Operation,wrong_Operation,remarks) VALUES("
+ Convert.ToString(patient_ID) + "," + Convert.ToString(scene_ID) + "," + "'" + train_datetime + "'" + "," + Convert.ToString(train_long) + ","
+ Convert.ToString(total_Operation) + "," + Convert.ToString(wrong_Operation)
+ ",'')";
debug输出
Debug.Log(query);
DataSet
DataSet是数据集,DataTable是数据表,DataSet存储多个DataTable。DataSet和DataTable像是专门存储数据的一个容器,在你查询数据库得到一些结果时可以存在里面。
dbConnection.State == ConnectionState.Open //判断当前数据库是否打开
ConnectionState包括了数据库的各种状态
public enum ConnectionState
{
Closed = 0,
Open = 1,
Connecting = 2,
Executing = 4,
Fetching = 8,
Broken = 16
}
????
MySqlDataAdapter da = new MySqlDataAdapter(sqlString, dbConnection);
da.Fill(ds);
DataTime.Now表示当前时间
record.dateTime = DateTime.Now; //记录训练开始时间
getchild(0)获取第0个子物体,playercontrol挂载在playerball中,cameraRig赋值为player.
camera = cameraRig.transform.GetChild(0).transform.GetChild(3).transform;
screenTip.transform.GetChild(0).GetComponent<TextMesh>().text = (string)screenTips[screenTipsIndex];
screenTip.transform.position = camera.position + camera.forward * 1.3f;
播放背景声音
PlaySound(1);
更新函数
???
LineRenderer line = handle.GetComponent<LineRenderer>();
line.positionCount = 2;
line.startColor = Color.blue;
line.endColor = Color.blue;
line.startWidth = 0.01f;
line.endWidth = 0.01f;
line.SetPosition(0, handle.transform.position);
line.SetPosition(1, handle.transform.position+handle.transform.forward * (float)0.5);
???
//使VRcameraRig跟随playerBall
float interpolation = cameraRigSpeed * Time.deltaTime; //完成最后一帧所用的时间(秒)
Vector3 position = cameraRig.transform.position;
position.y = Mathf.Lerp(cameraRig.transform.position.y, transform.position.y, interpolation);
position.x = Mathf.Lerp(cameraRig.transform.position.x, transform.position.x, interpolation);
position.z = Mathf.Lerp(cameraRig.transform.position.z, transform.position.z, interpolation);
cameraRig.transform.position = position;
teleport.transform.position = new Vector3(0, -20, 0);
???
screenTip.transform.GetChild(0).GetComponent<TextMesh>().text = (string)screenTips[screenTipsIndex];
screenTip.transform.position = camera.position + camera.forward * 1.3f;
record.trainingTime = (int)(DateTime.Now.Subtract(record.dateTime) ).TotalSeconds; //记录训练时间,以秒为单位
Thread thread = new Thread(new ThreadStart(TrainingRecord.UploadRecordToDatabase));
thread.Start();
减法Subtract
DateTime start = DateTime.Now.AddDays(-20);
DateTime end = DateTime.Now;
TimeSpan ts = end.Subtract(start);
double days = ts.TotalDays;
int differentDays = (int)DateTime.Now.Subtract(start).TotalDays;
bool result = days == differentDays; //输出 true
normalized&&Normalize
它们的区别和共同点是:共同点:实现规范化,让一个向量保持相同的方向,但它的长度为1.0,如果这个向量太小而不能被规范化,一个零向量将会被返回。不同点:Vector3.normalized的作特点是当前向量是不改变的并且返回一个新的规范化的向量;Vector3.Normalize的特点是改变当前向量,也就是当前向量长度是1。
normalized&&Normalize区别和联系
LookAt
其定义在UnityEngine.Transform类中
public void LookAt(Vector3 worldPosition);
public void LookAt(Transform target);
用法一:
transform.LookAt(new Vector3(1,1,1)); //使游戏对象看向该坐标点(游戏对象的z轴指向(1,1,1)点)
用法二:
transform.LookAt(gameobject.transform); //使游戏对象看向gameobject的transform的position;在场景中创建cube与Sphere两个游戏对象,将脚本挂载到Cube上
transform
transform是一个属性,可以用getcomponent来获取。transform的中文意思是位置,利用这个属性,可以访问rotation,position等等。
Vector3.Magnitude
返回向量的长度(只读),向量的长度是(xx+yy+z*z)的平方根。