嘉藥-互動科技-Unity-RobotSim
- 這些工具能只能做遊戲、APP或AR/VR嗎?
- 擔心學了以後無處可用嗎?
- 這幾週的課程內容會教大家,我們是怎麼把工具當作工具用
例用工具解決問題
- 發現問題
- 假設解決辦法
- 使用工具製作出解決辦法
- 使用解決辦法來解決問題
如果製作一個線上可以模擬機器手臂運作的機器手臂模擬器應該可行?(假設解決辦法)
TOOL
A1~A6
想看看在Unity內可以怎麼玩機器手臂嗎?
Unity還有這種使用方式(之二)?! 只有想不到,沒有做不到。
想像力是你的超能力
客人這是你的章魚燒。給你~不給你~再給你~才怪~啦啦啦~
//Gripper.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gripper : MonoBehaviour
{
// Gripper程式會有2種模擬夾取
// 1.利用OnTriggerEnter自動取得在夾取範圍內的物件,夾取指令時將該物件的parent設為Gripper
// 2.以夾爪播放夾取動畫的方式移動夾爪,並利用Rigidbody產生夾取
//準備夾取的物件
public Transform readyGet;
//目前夾持的物件
public Transform holdingObject;
//夾取指令(將readyGet物件Parent設為Gripper)
public void Lock(Transform product)
{
if (holdingObject == null)
{
if (product)
{
product.transform.parent = transform;
holdingObject = product;
}
}
}
//傳回目前所夾持物
public Transform Unlock()
{
Transform returnObject = holdingObject;
holdingObject = null;//清空目前所持物
return returnObject;
}
//夾取readyGet物件
public void LockReadyGet()
{
Lock(readyGet);
}
//放開夾取物件
public void UnlockToWorld()
{
if (holdingObject)
{
holdingObject.parent = null;
}
holdingObject = null;//把手上拿著的東西丟到世界Root去
}
//偵測目前可夾取物
void OnTriggerEnter(Collider other)
{
readyGet = other.transform;
}
//移除目前圖夾取物
void OnTriggerExit(Collider other)
{
if (readyGet == other.transform)
{
readyGet = null;
}
}
}
//RobotCommandGripper.cs
using UnityEngine;
using RobotSim;
using System;
public class RobotCommandGripper : RobotCommand
{
//對應操作的夾爪
public Gripper gripper;
//夾爪動畫
public Animator animatorGripper;
//夾持命令
public bool Lock = false;
//檢查是否有設定好夾爪
public override bool Check()
{
if (gripper)
{
return true;
}
else
{
errorMassage = "Gripper is NULL";
return false;
}
}
//執行夾爪動作
public override int Execute()
{
if (Lock)
{
//夾取(以設定Parent方式)
gripper.LockReadyGet();
//夾取(播放動畫)
if (animatorGripper)
{
animatorGripper.speed = 1;
animatorGripper.Play("Lock", -1, 0);
}
}
else
{
//放開(以設定parent方式)
gripper.UnlockToWorld();
//放開(播放動畫)
if (animatorGripper)
{
animatorGripper.speed = 1;
animatorGripper.Play("UnLock", -1, 0);
}
}
//動作完成,執行下一行
return (line + 1);
}
public override string ExportDat()
{
//不需要輸出任何程式到Dat檔
return "";
}
public override string ExportSrc()
{
//輸出 GripperLock(true/false); 至 手臂程式src檔內
return tab + "GripperLock(" + Lock.ToString() + ");" + Environment.NewLine;
}
public override string UpdateName()
{
//更新Gameobject在階層視窗內的名稱
return (gameObject.name = "GripperLock(" + Lock.ToString() + ")");
}
}
//RobotCommandControlRobot.cs
using UnityEngine;
using UnityEngine.UI;
using RobotSim;
public class RobotCommandControlRobot : RobotCommand
{
public RobotPoint moveTarget; //等待點
public RobotPoint gripTarget; //夾取點
public Button ButtonForward; //UI向前按鈕
public Button ButtonBack; //UI向後按鈕
public Button ButtonLeft; //UI向左按鈕
public Button ButtonRight; //UI向右按鈕
public Button ButtonOK; //UI夾取按鈕
private float moveX = 0; //按下左或右時移動的距離
private float moveZ = 0; //按下前或後時前後移動的距離
private bool done = false; //是否已移動完畢(手臂可以繼續動作向下夾取)
public override bool Check()
{
if (moveTarget == null)
{
errorMassage = "未設定等待點";
return false;
}
if (gripTarget == null)
{
errorMassage = "未設定夾取點";
return false;
}
return true;
}
//在Unity環境中每FixedUpdate會呼叫此Execute()一次
public override int Execute()
{
Vector3 updatePosition = moveTarget.transform.position;
//原本的預備點
updatePosition.x += moveX;//更新左右位置
updatePosition.z += moveZ;//更新前後位置
moveX = 0;
moveZ = 0;
moveTarget.transform.position = updatePosition;
//將變更套用至預備點
updatePosition.y = gripTarget.transform.position.y;
//更新夾取點的高度值
gripTarget.transform.position = updatePosition;
//將變更套用至夾取點
robot.Inverse(moveTarget.transform);
//手臂動作更新
//若操作已完成,則讓手臂程式執行下一行程式,否則繼續執行目前這行程式
if (done)
{
done = false;
return (line + 1);
}
else
{
return line;
}
}
//當選擇匯出程式時會執行此ExportDat(),將回傳的值寫進手臂程式原始src檔中
public override string ExportDat()
{
return "";
}
//當選擇匯出程式時會執行此ExportSrc(),將回傳的值寫進手臂程式原始dat檔中
public override string ExportSrc()
{
return "";
}
//更新在階層列表上的此物件名稱
public override string UpdateName()
{
return (gameObject.name = "Move(" + moveTarget.name + "," + gripTarget.name + ")");
}
//初始化 設定UI按鈕按下時移動數值變更
void Start()
{
ButtonForward.onClick.AddListener(
delegate
{
moveZ = 0.01f;//向前移動1公分
});
ButtonBack.onClick.AddListener(
delegate
{
moveZ = -0.01f;//向後移動1公分
});
ButtonLeft.onClick.AddListener(
delegate
{
moveX = -0.01f;//向左移動1公分
});
ButtonRight.onClick.AddListener(
delegate
{
moveX = 0.01f;//向右移動1公分
});
ButtonOK.onClick.AddListener(
delegate
{
done = true;//動作完成,開始夾
});
}
}
//Gripper.cs
//放開夾取物件
public void UnlockToWorld()
{
if (holdingObject)
{
holdingObject.parent = null;
//若物件上有剛體則開啟重力(讓物體隨重力掉落)
if (holdingObject.GetComponent<Rigidbody>())
{
holdingObject.GetComponent<Rigidbody>().useGravity = true;
}
}
holdingObject = null;//把手上拿著的東西丟到世界Root去
}