一、工程准备
1、官网下载支持Unity4.6版本 survival shooter资源;
2、确保你的ZSPACE有最新的SDK install
http://developer.zspace.com/downloads
3、下载 Zspace ZSCore package
4、设置Unity打开的参数: -force-opengl -enable -stereoscopic3d
"%CD%\_unity.exe" -force-opengl -enable-stereoscopic3d
二、Setting up Stereoscope(Stereoscope:立体镜)
1、将Prefab :ZSCore拖到Main Camera 下,设置rotation 为0;
检查NVIDIA Control Panel,确定 Stero-Display mode 和Stero-Enable 都已经开启,参数值为ON
2、打开CoreDiagnostic: Window->zSpace->CoreDiagnostic
调整viewer Scale值到最适合的值。如(40)
3、找到Prefab:ZSCore,调整ZSCore 下Viewer Scale值为40;
三、the Stylus Controlloer(笔尖控制)
在Main Camera下创建空物体StylusController
1、在StylusController 上添加脚本Line Render .
创建一个stylusMaterial(用一个64*64的texture,stylusMaterial的tint color可以设置为:37,156,156,150)
参数设置:
Parameters
Start width:0.1
End Width:0.05
Start Color/End Color: 64,198,196,149
2、在StylusController 上添加脚本Stylus Script
using UnityEngine;
using System.Collections;
public class stylus : MonoBehaviour {
private ZSCore zs_core_;
private ZSCore.TrackerTargetType target_type = ZSCore.TrackerTargetType.Primary;
private LineRenderer stylus_render_line;
private Vector3 projection_point_;
private const float cam_ray_length_=100.0f;
public void Start()
{
zs_core_ = GameObject.Find("ZSCore").GetComponent<ZSCore>();
zs_core_.Updated += new ZSCore.CoreEventHandler(OnCoreUpdated);
stylus_render_line = GetComponent<LineRenderer>();
}
public Vector3 GetPonterLocation()
{
return projection_point_;
}
private void OnCoreUpdated(ZSCore sender)
{
UpdateStylusPose();
UpdateProjectionPoint();
DrawStylusBeam();
}
private void UpdateStylusPose()
{
Matrix4x4 pose= zs_core_ .GetTrackerTargetWorldPose(target_type );
transform .position = new Vector3 (pose .m03,pose .m13 ,pose .m23);
transform .rotation = Quaternion.LookRotation (pose .GetColumn(2),pose .GetColumn(1));
}
private void UpdateProjectionPoint()
{
RaycastHit hit_;
if (Physics.Raycast(transform.position, transform.forward, out hit_, cam_ray_length_))
{
projection_point_ = hit_.point;
}
else
{
Ray ray = new Ray(transform.position, transform.forward);
projection_point_ = ray.GetPoint(cam_ray_length_);
}
}
private void DrawStylusBeam()
{
stylus_render_line.SetPosition(0, transform.position);
stylus_render_line.SetPosition(1, projection_point_);
}
}
using System.Collections;
public class stylus : MonoBehaviour {
private ZSCore zs_core_;
private ZSCore.TrackerTargetType target_type = ZSCore.TrackerTargetType.Primary;
private LineRenderer stylus_render_line;
private Vector3 projection_point_;
private const float cam_ray_length_=100.0f;
public void Start()
{
zs_core_ = GameObject.Find("ZSCore").GetComponent<ZSCore>();
zs_core_.Updated += new ZSCore.CoreEventHandler(OnCoreUpdated);
stylus_render_line = GetComponent<LineRenderer>();
}
public Vector3 GetPonterLocation()
{
return projection_point_;
}
private void OnCoreUpdated(ZSCore sender)
{
UpdateStylusPose();
UpdateProjectionPoint();
DrawStylusBeam();
}
private void UpdateStylusPose()
{
Matrix4x4 pose= zs_core_ .GetTrackerTargetWorldPose(target_type );
transform .position = new Vector3 (pose .m03,pose .m13 ,pose .m23);
transform .rotation = Quaternion.LookRotation (pose .GetColumn(2),pose .GetColumn(1));
}
private void UpdateProjectionPoint()
{
RaycastHit hit_;
if (Physics.Raycast(transform.position, transform.forward, out hit_, cam_ray_length_))
{
projection_point_ = hit_.point;
}
else
{
Ray ray = new Ray(transform.position, transform.forward);
projection_point_ = ray.GetPoint(cam_ray_length_);
}
}
private void DrawStylusBeam()
{
stylus_render_line.SetPosition(0, transform.position);
stylus_render_line.SetPosition(1, projection_point_);
}
}
四、Using the Stylus for Player Movement
在Player上添加脚本 PlayerMovement
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour {
public float speed = 6.0f;
public stylus stylusScript;
private ZSCore zs_core;
private ZSCore.TrackerTargetType target_type_ = ZSCore.TrackerTargetType.Primary;
private Animator anim_;
private Rigidbody player_rigidbody_;
void Awake()
{
anim_ = GetComponent<Animator>();
player_rigidbody_ = GetComponent<Rigidbody>();
zs_core = GameObject.Find("ZSCore").GetComponent<ZSCore>();
}
void FixedUpdate()
{
bool moved_ = Move();
Turning();
Animating(moved_);
}
bool Move()
{
bool did_move = false;
float h_ = 0.0f;
float v_ = 0.0f;
Vector3 destination_ = new Vector3(0.0f, 0.0f, 0.0f);
//moving with the stylus? check if 2nd or 3rd stylus buttons are pressed
if (zs_core.IsTrackerTargetButtonPressed(target_type_, 1) ||
zs_core.IsTrackerTargetButtonPressed(target_type_, 2))
{
if (zs_core.IsTrackerTargetButtonPressed(target_type_, 2))
{
//move backwards with button3
destination_ = Vector3.MoveTowards(transform.position, stylusScript.GetPointerLocation(),
-speed * Time.deltaTime);
}
//move backwards with button2
else
{
destination_ = Vector3.MoveTowards(transform.position, stylusScript.GetPointerLocation(),
-speed * Time.deltaTime);
}
//cancel any movement
destination_.Set(destination_.x, 0.0f, destination_.z);
//Note: this will always be true,as the stlyus beam doesn't enter inside
//the player to reach its origin point
did_move = transform.position != destination_;
player_rigidbody_.MovePosition(destination_);
}
else //otherwise check for keyboard input
{
h_ = Input.GetAxisRaw("Horizontal");
v_ = Input.GetAxisRaw("Vertical");
destination_.Set(h_, 0.0f, v_);
destination_ = destination_.normalized * speed * Time.deltaTime;
player_rigidbody_.MovePosition(transform.position + destination_);
did_move = h_ !=0.0f||v_ !=0.0f;
}
return did_move;
}
void Turning()
{
Vector3 pointer_location_ = stylusScript.GetPointerLocation();
Vector3 player_to_stylus_ = pointer_location_ - transform.position;
Quaternion newRotation = Quaternion.LookRotation(player_to_stylus_);
//Don't turn in x or z axes
newRotation.x = 0;
newRotation.z = 0;
//player_rigidbody_.MoveRotate(newRotation);
}
void Animating(bool moved)
{
anim_.SetBool("IsWalking", moved);
}
}
using System.Collections;
public class PlayerMovement : MonoBehaviour {
public float speed = 6.0f;
public stylus stylusScript;
private ZSCore zs_core;
private ZSCore.TrackerTargetType target_type_ = ZSCore.TrackerTargetType.Primary;
private Animator anim_;
private Rigidbody player_rigidbody_;
void Awake()
{
anim_ = GetComponent<Animator>();
player_rigidbody_ = GetComponent<Rigidbody>();
zs_core = GameObject.Find("ZSCore").GetComponent<ZSCore>();
}
void FixedUpdate()
{
bool moved_ = Move();
Turning();
Animating(moved_);
}
bool Move()
{
bool did_move = false;
float h_ = 0.0f;
float v_ = 0.0f;
Vector3 destination_ = new Vector3(0.0f, 0.0f, 0.0f);
//moving with the stylus? check if 2nd or 3rd stylus buttons are pressed
if (zs_core.IsTrackerTargetButtonPressed(target_type_, 1) ||
zs_core.IsTrackerTargetButtonPressed(target_type_, 2))
{
if (zs_core.IsTrackerTargetButtonPressed(target_type_, 2))
{
//move backwards with button3
destination_ = Vector3.MoveTowards(transform.position, stylusScript.GetPointerLocation(),
-speed * Time.deltaTime);
}
//move backwards with button2
else
{
destination_ = Vector3.MoveTowards(transform.position, stylusScript.GetPointerLocation(),
-speed * Time.deltaTime);
}
//cancel any movement
destination_.Set(destination_.x, 0.0f, destination_.z);
//Note: this will always be true,as the stlyus beam doesn't enter inside
//the player to reach its origin point
did_move = transform.position != destination_;
player_rigidbody_.MovePosition(destination_);
}
else //otherwise check for keyboard input
{
h_ = Input.GetAxisRaw("Horizontal");
v_ = Input.GetAxisRaw("Vertical");
destination_.Set(h_, 0.0f, v_);
destination_ = destination_.normalized * speed * Time.deltaTime;
player_rigidbody_.MovePosition(transform.position + destination_);
did_move = h_ !=0.0f||v_ !=0.0f;
}
return did_move;
}
void Turning()
{
Vector3 pointer_location_ = stylusScript.GetPointerLocation();
Vector3 player_to_stylus_ = pointer_location_ - transform.position;
Quaternion newRotation = Quaternion.LookRotation(player_to_stylus_);
//Don't turn in x or z axes
newRotation.x = 0;
newRotation.z = 0;
//player_rigidbody_.MoveRotate(newRotation);
}
void Animating(bool moved)
{
anim_.SetBool("IsWalking", moved);
}
}
五、Shooting with the stylus
六、Haptic Feedback
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class PlayerHealth : MonoBehaviour {
public int statingHealth = 100;
public int currentHealth;
public Slider healthSlider;
public ImageEffectOpaque damageImage;
public AudioClip deathClip;
public float flashSpeed=5.0f;
public Color flashcolour=new Color (1.0f,0.0f,0.0f,0.1f);
public float vibrateTime=0.4f;
private ZSCore zs_core_;
private ZSCore .TrackerTargetType target_type= ZSCore.TrackerTargetType .Primary ;
private Animator anim;
private AudioSource player_audio;
private PlayerMovement player_movement_;
private PlayShooting player_shooting_;
private bool is_dead_;
private bool is_damaged;
void Awake()
{
anim = GetComponent<Animator>();
player_audio =GetComponent <AudioSource >();
player_movement_=GetComponent <PlayerMovement>();
player_shooting_= GetComponent <PlayShooting >();
currentHealth = statingHealth ;
zs_core_ = GameObject.Find ("ZSCore").GetComponent<ZSCore>();
}
void Update()
{
if(is_damaged)
{
damageImage .color=flashcolour ;
zs_core_ .SetTrackerTargetVibrationEnabled(target_type,true );
zs_core_ .StartTrackerTargetVibration(target_type ,vibrateTime ,0.0f,1);
}
else
{
damageImage .color=Color .Lerp (damageImage .color,Color .clear ,flashSpeed*Time .deltaTime );
}
is_damaged=false ;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
using UnityEngine.UI;
using System.Collections;
public class PlayerHealth : MonoBehaviour {
public int statingHealth = 100;
public int currentHealth;
public Slider healthSlider;
public ImageEffectOpaque damageImage;
public AudioClip deathClip;
public float flashSpeed=5.0f;
public Color flashcolour=new Color (1.0f,0.0f,0.0f,0.1f);
public float vibrateTime=0.4f;
private ZSCore zs_core_;
private ZSCore .TrackerTargetType target_type= ZSCore.TrackerTargetType .Primary ;
private Animator anim;
private AudioSource player_audio;
private PlayerMovement player_movement_;
private PlayShooting player_shooting_;
private bool is_dead_;
private bool is_damaged;
void Awake()
{
anim = GetComponent<Animator>();
player_audio =GetComponent <AudioSource >();
player_movement_=GetComponent <PlayerMovement>();
player_shooting_= GetComponent <PlayShooting >();
currentHealth = statingHealth ;
zs_core_ = GameObject.Find ("ZSCore").GetComponent<ZSCore>();
}
void Update()
{
if(is_damaged)
{
damageImage .color=flashcolour ;
zs_core_ .SetTrackerTargetVibrationEnabled(target_type,true );
zs_core_ .StartTrackerTargetVibration(target_type ,vibrateTime ,0.0f,1);
}
else
{
damageImage .color=Color .Lerp (damageImage .color,Color .clear ,flashSpeed*Time .deltaTime );
}
is_damaged=false ;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
七、Finishing The Game
file-build-PC
参数设置:
Architecture:X86
Use Director3D 11* 、 Static Batching、Dynamic Batching、Stereocopic rendering勾选为true
八、运行发布出来的exe文件
在发布的文件中新建txt.
"%_dp0\YourGameName.exe" -force-opengl -enable -stereoscopic3d
在将txt另存为bat批处理文件。
双击bat,即可打开运行。