====== ExportTransform ====== The ExportTransform class is a class that can interfere with Transform and Rigidbody. You can change the position, rotation and scale of a VCI, or you can rotate and blow them by applying force. ---- ===== List of member variables and functions ===== **For the complete list, refer to "types.lua" file in "EmbeddedScriptWorkspace" folder. ** **To shorten the description, ''Vector3 type'' is abbreviated as ''Vec'' and ''number type'' is abbreviated as ''num''. **\\ **Arguments are shown in ''()'' and return values are shown after semicolons '':''. ** | Name | Description | VC version | | GetName fun(): string | Get the name of a subitem || | GetLocalPosition fun(): Vec3 | Get the position of a SubItem\\ (Subitem local)|| | GetPosition fun(): Vec3 | Get the position of a SubItem | | | GetLocalRotation fun(): Quaternion | Get the rotation of a SubItem\\(Subitem local)|| | GetRotation fun(): Quaternion | Get the rotation of a SubItem || | GetLocalScale fun(): Vec3 | Get the scale of a SubItem || | GetForward fun(): Vec3 | Get the forward direction (positive z axis) based on a SubItem || | GetRight fun(): Vec3 | Get the right direction (positive x axis) based on a SubItem || | GetUp fun(): Vec3 | Get the up direction (positive y axis) based on a SubItem || | GetLocalToWorldMatrix fun(): Matrix4x4 | Matrix when converting from the local coordinate to the world coordinate || | GetAnimation fun(): ExportAnimation | Used for [[en: vci:script:reference:exportanimation|ExportAnimation]] | | | IsMine bool | Returns true in case of subItem owner, otherwise returns nil | | | IsSubItem bool | Returns true in case of SubItem, otherwise returns false | | | SetPosition fun(position: Vec3) | Change the position of a Subitem to the value specified with Vec3| | | SetLocalPosition fun(localPosition: Vec3) | Change the position of a Subitem to the value specified with Vec3| | | SetRotation fun(rotation: Quaternion) | Change the Rotation of a Subitem to the value specified with quaternion| | | SetLocalRotation fun(localRotation: Quaternion) | Change the Rotation of a Subitem to the value specified with quaternion| | | SetLocalScale fun(localScale: Vec3) | Change the scale of a Subitem to the value specified with Vec3| | | SetVelocity fun(velocity: Vec3) | Change the force applied to a Subitem to the value specified with Vec3| | | SetAngularVelocity fun(angularVelocity: Vec3) | Change the rotation applied to a Subitem to the direction specified with Vec3| | | AddForce fun(force: Vec3) | Apply the force specified with Vec3 to a Subitem| | ** Attachable item ** | Name | Description | VC version | | IsAttached bool | Returns true when attached | 1.9.2a and later | | AttachableDistance number | Returns the distance at which it is attachable | 1.9.2a and later | | AttachableHumanBodyBones usertype | Returns the list of attachable bone names as a table | 1.9.2a and later | | AttachToAvatar fun() | When it is attachable, ties to attach | 1.9.2a and later | | DetachFromAvatar fun() | When it is attached, detaches | 1.9.2a and later | To use the ExportTransform class, you must first instantiate a Subitem by specifying its name like ''Subitem = vci.assets.GetSubItem("Subitem")''.\\ Then, you can call the methods like ''Subitem.MethodName()''. ===== Synchronization of VCI ===== When you are creating something that moves over a network, you have to take the synchronization into account.\\ In a scenario where there are three people (A, B and C) in a single Virtual Cast studio, the act of applying the result of person A moving an object to the computer of person B and C is called "synchronization."\\ On the other hand, when something moves only in the computer of the person who moved it, that situation is called "working in local only."\\ Following are the most common way of synchronization in VCI. * Transform is synchronized by Virtual Cast feature.\\ * Methods with ''_ALL_'' will be synchronized and run.\\ * Use [[en/vci/script/reference/syncvariable|sync variables]] to sync the state of VCIs.\\ As for the synchronization of transform, the result of the script run in the client of the user who spawned the VCI will be synced across other clients via the base functions of Virtual Cast, without needing special attention from you.\\ For details on the synchronization of transform, refer to [[en:vci:component:sdk:subitem:owned|About VCI items and subitems]]. ===== GetSubItem() ===== Example\\ --ExportTransform -- Object name set to the SubItem is "SubItem" SubItem = vci.assets.GetSubItem("SubItem") print(SubItem.GetName()) print(SubItem.ToString()) \\ The result\\ SubItem VCIEmbedded.LuaMoonSharp.ExportTransform By passing an object name of a SubItem as the argument to ''vci.assets.GetSubItem()'',\\ you can instantiate the ExportTransform of the SubItem you passed as the argument.\\ By using the functions of the ExportTransform instantiated, you can change or acquire the value of the transform.\\ ==== Declaring multiple SubItems in a for statement ==== -- Declare a table with for statement local _Items = {} for i=1, 5 do _Items[i] = vci.assets.GetSubItem("Item"..tostring(i)) print("Registered ".._Items[i].. "in the table.") end By giving SubItems serialized names, such as ''Item1'' ''Item2'' ''Item3'',\\ you can ''GetSubItem()'' in the order from 1 using for statement.\\ * i can be converted into string with ''tostring(i)''.\\ ===== IsMine ===== Example\\ subitem = vci.assets.GetSubItem('SubItem') function updateAll() -- All users execute this regardless of ownership if subitem.IsMine then -- true when you are the owner of the subitem. subitem.SetPosition = Vector3.__new(1, 2, 3) end end Used to run a certain process only when the user is the owner of the SubItem.\\ For details of ownership, refer to [[en:vci:script:reference:eventfunction:ownership|Relation between ownership and event functions]]. ===== Get transform ===== Example\\ --ExportTransform -- Object name set to the SubItem is "SubItem" SubItem = vci.assets.GetSubItem("SubItem") print(SubItem.GetPosition()) print(SubItem.GetLocalPosition()) print(SubItem.GetRotation()) print(SubItem.GetLocalRotation()) print(SubItem.GetLocalScale()) print(SubItem.GetForward()) \\ The result\\ (0.0, 1.2, 0.0) (0.0, 1.2, 0.0) (0.0, 0.0, 0.0, 1.0) (0.0, 0.0, 0.0, 1.0) (1.0, 1.0, 1.0) (0.0, 0.0, 1.0) ===== GetName() ===== **return value: string**\\ You can get the name of the VCI object name. ===== GetPosition() / GetLocalPosition() ===== **return value: Vector3**\\ You can get the current position of the Subitem.\\ Position() uses the origin in Unity (0,0,0) as the reference point. On the other hand, LocalPosition() uses the spawn position as the reference point. ===== GetRotation() / GetLocalRotation() ===== **return value: Quaternion**\\ You can get the rotation (Quaternion) of the Subitem.\\ Rotation() uses entire Unity as its reference rotation (Z+ forward). LocalRotation() uses the direction at which the VCI is spawned as the reference rotation.\\ ''SetRotation(Quaternion.identity)'' changes the orientation using Unity's Z+ as the forward direction. ===== GetLocalScale() ===== **return value: Vector3**\\ You can get the scale of the SubItem. When changing the scale of a SubItem that is scalable, retrieve the scale value by GetLocalScale(), then multiply it by the desired scale factor to set "a scale value changed based on the current scale."\\ (Only using SetLocalScale() means it is a scale change without considering current scale). ===== GetForward() ===== **return value: Vector3**\\ Get the current forward direction of the SubItem.\\ (Vector of positive Z-axis based on the SubItem) One use case of this is to retrieve the vector of the forward direction by GetForward(), then when onUngrab() (when you release the SubItem) is called, you can use AddForce() and the retrieved forward direction vector to push the item in the forward direction.\\ You can use this to "shoot the item to forward direction." ===== SetPosition() / SetLocalPosition() ===== **Argument: vector3**\\ Change the current position of a Subitem to the value specified with Vector3.\\ Position() uses the origin in Unity (0,0,0) as the reference point. On the other hand, LocalPosition() uses the spawn position as the reference point. When setting position or rotation, if any force is being applied to the SubItem, the calculation for the force being applied happens right after the values are set, which may produce an unintended result.\\ Therefore, it is recommended to use SetVelocity(0,0,0) to set the force to be zero after a Set method is called. The order should be SetPosition() then SetVelocity(0,0,0).\\ (If its the opposite, some force could be applied by SetPosition() after the force is being set to 0. ===== SetRotation() / SetLocalRotation() ===== **Argument: Quaternion**\\ Change the current attitude (rotation) of a Subitem to the value specified with Quaternion.\\ Rotation() uses entire Unity as its reference rotation (Z+ forward). LocalRotation() uses the direction at which the VCI is spawned as the reference rotation. When setting position or rotation, if any force is being applied to the SubItem, the calculation for the force being applied happens right after the values are set, which may produce an unintended result.\\ Therefore, it is recommended to use SetVelocity(0,0,0) to set the force to be zero after a Set method is called. The order should be SetPosition() then SetVelocity(0,0,0).\\ (If its the opposite, some force could be applied by SetPosition() after the force is being set to 0. ===== SetLocalScale() ===== **Argument: vector3**\\ Change the scale of a Subitem to the value specified with Vector3. When changing the scale of a SubItem that is scalable, retrieve the scale value by GetLocalScale(), then multiply it by the desired scale factor to set "a scale value changed based on the current scale." ===== SetVelocity() ===== **Argument: vector3**\\ Change the force being applied to a VCI to the value set with a Vector3. In the example below, the object with the name "subitem" moves toward Z direction when being grabbed.\\ The object will hold the Velocity value right after the code is executed.\\ By setting Vector3.zero you can disable the motion being applied by physics calculation. Example\\ item = vci.assets.GetSubItem("subitem") function onGrab() local velocity = Vector3.__new(0, 0, 10) print(velocity) item.SetVelocity(velocity) end ===== SetAngularVelocity() ===== **Argument: vector3**\\ This will apply a rotational force based on the Vector3 value. In the example below, the rotational force "velocity" will be applied to the object with the name "subitem". Example\\ item = vci.assets.GetSubItem("subitem") function onGrab() local velocity = Vector3.__new(10, 0, 0) print(velocity) item.SetAngularVelocity(velocity) end ===== AddForce() ===== **Argument: vector3**\\ Force will be added toward the Vector3 direction. In the example below, the object with the name "subitem" moves toward Z direction when being grabbed.\\ AddForce will apply the force little by little as if an object is being accelerated. Example\\ item = vci.assets.GetSubItem("subitem") function onGrab() local force = Vector3.__new(0, 0, 10) print(force) item.AddForce(force) end ===== Controlling an attachable item ===== VC version: 1.9.2a and later You can control the subitem with [[en:vci:component:sdk:attachable| VCIAttachable]] component attached. Attach with AttachToAvatar and detach with DetachFromAvatar. You can check the attached state with IsAttached. The attachability is decided based on the distance specified in VCIAttachable and the distance to a bone. You cannot attach if you don't have the ownership for the SubItem. Example\\ local item = vci.assets.GetSubItem("Cube") local dist = item.AttachableDistance print("AttachableDistance: "..dist) print("Bones") local bones = item.AttachableHumanBodyBones for key,value in ipairs(bones) do print(key .. " : " .. value) end function update() if vci.me.GetButtonInput(1) then print("Attach") item.AttachToAvatar() end if vci.me.GetButtonInput(2) then print("Detach") item.DetachFromAvatar() end end vci.StartCoroutine( coroutine.create( function() while true do local isAttached = item.IsAttached if isAttached then print("Attached") else print("Not attached") end sleep(1) end end ) ) function sleep(sec) local t0 = os.time() + sec while os.time() < t0 do coroutine.yield() end end ==== Example data ==== A VCI that attaches when you hold a hand over it and detaches after five seconds. An effect will be played while the item is attached. {{:vci:script:reference:2020041612403245.jpg?400|}} {{ :vci:script:reference:attachsample.zip |}} local item = vci.assets.GetSubItem("Ball") local effect = vci.assets.GetEffekseerEmitter("Ball") vci.StartCoroutine( coroutine.create( function() while true do if item.IsAttached == false then item.AttachToAvatar() sleep(0.1) if item.IsAttached then effect.Play() sleep(5) item.DetachFromAvatar() effect.Stop() sleep(1) end end sleep(0.5) end end ) ) function sleep(sec) local t0 = os.time() + sec while os.time() < t0 do coroutine.yield() end end