VR康复训练--空间认知部分(Unity/VR/C#)未完待续

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)的平方根。

发布了35 篇原创文章 · 获赞 2 · 访问量 953

猜你喜欢

转载自blog.csdn.net/y18771025420/article/details/103442290
今日推荐