Copy/paste repository of some very useful scripts.
- Example Setup
- Color
- Transforms: Scale and Rotation
- Shape
- Physics
- World Properties
- Emitters
- Time
- Player Controls
- ViewPorts and Displays
- Sounds
- Helpful Math
- Objects: Existing, Fading out, Deactivating
- Animate Values
Example Setup
Example function from the Scripting Clipboard Sample Setup to help test out these functions as a beginner. If you're more advanced with scripting, you'll know how/where to use these pieces of script.
function MeshEntity:onPress(seg, normal, anchor_node) -- In the example you have used drag and drop to declare the sphere here. -- It will look something like this after the drag-drop: SphereEntity = findObjectByUID("...") -- You need to either, replace 'object' below with 'SphereEntity' or replace 'SphereEntity' above with 'object'. Make the names match basically... the next line is the line you copy into Simmetri script window. object.color = rgba(255,0,153,255) end -- Most of the lines of script to follow will use the word 'object' as the object variable name, upon which we will change properties or call functions.
Transforms: Position and Rotation
-- Move the object up a unit self:setWorldPosition(self:getWorldPosition() + vector3(0,1,0)) -- Explicitly set the object's local position (relative its parent node) -- to place it at the parent's origin self:setLocalPosition(vector3(0,0,0)) -- Get rotation angles (angles in radians) vAngles = self:getWorldRotationAsEulerAngles() -- Print the angle about the y-axis in degrees print(tostring(math.deg(vAngles.y))) -- Rotate the object 10 degrees about the y-axis vAngles.y = vAngles.y + math.rad(10) self:setWorldRotation(vAngles)
Color
Color is variable stored with 4 numbers; a vector4. The numbers are Red, Green, Blue, Alpha, and each is represented as value from 0-1. Example: (0.2, 0.4, 0.6, 1). There are a number of helpful functions for creating these color vector4's.
-- Color is stored in a vector4. -- Set color with Red, Green, Blue and Alpha: "rgba()" takes r,g,b,a values [each value is ranged: 0-255], and returns a color vector 4. object.color = rgba(255,0,153,255) -- Set color with Hue, Saturation and Brightness: "hsb(h,s,b)" takes hue/saturation/brightness values H[0,360] S[0,1] B[0,inf] and returns a vector4 color. object.color = hsb(180,0.5,1) -- Get access to the color: this returns vector4 of color values RGBA, each ranged: 0-1 sampleVariable = object.color() -- Access just one component of the color: the vector4 actually stores each component as x,y,z,w. These map x->r, y->g,z->b,w->a. --get red redAmount = object.color.x greenAmount = object.color.y blueAmount = object.color.z alphaAmount = object.color.w -- Change one part of the color relatively. Ex: make the color more red. object.color = object.color + rgba(36, 0, 0, 0) or object.color = object.color + vector4(0.1, 0, 0, 0) -- Make one object the same color as another object: Ex: make object1 the color of object 2. object1 = findObjectByUID("...") object2 = findObjectByUID("...") object1.color = object2.color -- Make a color brighter the higher in the air it goes. objHeight = object:getWorldPosition().y object.color = hsb(180,1,objHeight) -- Shift a color based on an object's velocity. See also 'Physics' below. Ex: resting object is yellow, as it moves faster its color shifts through green, blue and violet and reaches red at 10meters/second. speed = object:getRigidBody():getLinearVelocity():length() object.color = hsb( (speed*30)+60 ,1,1) --try: the above script in the object's onMove() event. Use "self" to refer to the object itself. function MeshEntity:onMove() speed = self:getRigidBody():getLinearVelocity():length() self.color = hsb( (speed*30)+60 ,1,1) end
Color with Color Components Attribute
With the Color Components Attribute add to a meshEntity's color property, we can manipulate the properties of HSBA individually. These HSBA values are ranged as follows (H:0-360)(S:0-1)(B:0-1 = normal range = glow). Image showing where to add the component, and code following for adjusting those values.
(A:0-1) object:getColorProperty():findAttribute("ColorComponentsAttribute").hue = 180 object:getColorProperty():findAttribute("ColorComponentsAttribute").saturation = 0.5 object:getColorProperty():findAttribute("ColorComponentsAttribute").brightness = 0.618 object:getColorProperty():findAttribute("ColorComponentsAttribute").alpha = 0.382
See Also: a fun starter project playing with color.
Shapes
Shape properties come in all... shapes and sizes. Spheres have radii, cylinders have radii and height, cubes have a dimensions x, y, and z.
-- Set BOX Shape: Box:getMeshModel():getShape().dimensions = vector3(1,4,1) -- Set PLANE Shape: Plane:getMeshModel():getShape().dimensions = vector2(1,1.618) -- Set SPHERE Shape: Sphere:getMeshModel():getShape().radius= 2.5 -- Set CYLINDER Shape: Cylinder:getMeshModel():getShape().radius = 2.5 Cylinder:getMeshModel():getShape().height = 3 -- Set CONE Shape: Cone:getMeshModel():getShape().radius1 = .5 Cone:getMeshModel():getShape().radius2 = 3 Cone:getMeshModel():getShape().height = 5 -- Set WEDGE Shape: Wedge:getMeshModel():getShape().dimensions = vector3(1,4,1) -- Set TUBE Shape: Tube:getMeshModel():getShape().radius1 = .5 Tube:getMeshModel():getShape().radius2 = 3 Tube:getMeshModel():getShape().height = 5 -- Set ROUNDED CYLINDER Shape: RoundedCylinder:getMeshModel():getShape().radius = .5 RoundedCylinder:getMeshModel():getShape().edgeRadius = 3 RoundedCylinder:getMeshModel():getShape().height = 5 -- Set ROUNDED BOX Shape: RoundedBox:getMeshModel():getShape().edgeRadius = 3 RoundedBox:getMeshModel():getShape().dimensions = vector3(1,4,1) -- Set CAPSULE Shape: Capsule:getMeshModel():getShape().radius = .5 Capsule:getMeshModel():getShape().edgeRadius = 3 Capsule:getMeshModel():getShape().height = 5 -- Set TEXT shape: (the words that appear on the screen) Text:getMeshModel():getShape().text = "new text; don't forget the quote marks" -- Set CLOTH shape: (same as plane) -- Set ROPE shape: (same as cylinder) -- Set MIRROR shape: (same as plane)
Physics
-- MAKE OBJECT MOVABLE, IMMOVABLE -- Example: make movable object:getRigidBody().movable = true -- APPLY A PHYSICS IMPULSE -- This function wants a vector 3 to define the force applied to the center of the object -- Example: impulse in the up direction at magnitue 10 object:getRigidBody():applyCentralImpulse(vector3(0,10,0)) -- SET A CONSTANT FORCE -- Ex: set a constant upward force (+y direction). -- This example makes an object experience anti-gravity... -- ...as (0,10,0) is greater than gravity at (0,-9.8,0) object:getRigidBody().constantForce = (vector3(0,10,0)) -- GET THE LINEAR VELOCITY (vector) -- Example: print the linear velocity vector a = object:getRigidBody():getLinearVelocity() print(tostring(a)) -- or print( tostring( object:getRigidBody():getLinearVelocity() ) ) -- GET THE SPEED (AKA: Linear Velocity Vector Magnitude, AKA: Vector Length) -- Query the Rigid Body to see what physics is acting on it right now -- Ex: linear velocity magnitude, AKA 'Speed' a = object:getRigidBody():getLinearVelocity():length() print(tostring(a)) -- SET THE LINEAR VELOCITY (vector) -- Ex: Set the linear velocity with a vector 3 (0,4,8). object:getRigidBody():setLinearVelocity(vector3(0,4,8)) -- GRAVITY: See "World Properties" section next for changing Gravity
World Properties: ocean, sky, time of day, etc.
There's two good ways to access the terrainSpace as an object in script so that you can fiddle with its properties:
- Drag and drop the "TerrainSpace" icon from the Hierarchy panel into the Scripting Window.
- Declare the following on any object, like the cube we click in our Example Setup:
function MeshEntity:onPress() space = self:getSpace() end
For the following script samples, we'll assume we are doing exactly technique 2 above. Our terrainSpace will be accessed through :getSpace() and stored in a variable called "space":
space = self:getSpace()
-- Change the spaces GRAVITY: space = self:getSpace() space.physics.gravity = vector3(0,0,0) -- no gravity at all, things will float neutrally -- Make the OCEAN appear: space:getOcean().visible = true -- Change the OCEAN water level: space:getOcean().waterLevel = 3.5 -- Animate SEA LEVEL RISE (see "Animate Values" below): clip = getAnimator():createKeyClip( space:getOcean():getWaterLevelProperty()) clip:addKey(seconds(2), 3.5) -- Animate SEA LEVEL RISE (relative to current water level) (see "Animate Values" below): -- Ex: 2 secs to raise 2 more feet each time the function runs clip = getAnimator():createKeyClip( space:getOcean():getWaterLevelProperty()) clip:addKey(seconds(2), space:getOcean().waterLevel + 2) -- Change the TIME OF DAY sky = space.horizon.space sky.timeOfDay = 16 -- number of hours in day, 23=11PM -- Animate a SUNSET (see "Animate Values" below): -- Ex: 4 secs to make timeOfDay = 18 clip = getAnimator():createKeyClip( space.horizon.space:getTimeOfDayProperty()) clip:addKey(seconds(4), 18) -- Add MORE FOG sky = space.horizon.space sky:getFog().density = .45 --values range: 0-1 -- Add MORE CLOUDS sky = space.horizon.space sky:getClouds().coverage = .45 --values range: 0-1 -- Animate STORM COMING IN sky = space.horizon.space clouds = sky:getClouds() fog = sky:getFog() clip = getAnimator():createKeyClip( clouds:getCoverageProperty()) clip:addKey(seconds(10), 1) clip = getAnimator():createKeyClip( fog:getDensityProperty()) clip:addKey(seconds(10), .25)
Emitters
For these snippets, we assume a node emitter called 'NodeEmitter' is added as a child of our interactable box (from the Scripting Clipboard Sample Setup)
-- Find the child NodeEmitter
nodeEmitter = self:findNodeByName("NodeEmitter")
-- Emit a single object from NodeEmitter
nodeEmitter:emitNode()
-- Emit multiple objects
nodeEmitter:emitBurst(10)
-- Point at another object
nodeEmitter:pointAt(object:getWorldPosition())
-- Clear emitted objects
nodeEmitter:reset()
--try: the above script in the NodeEmitter's onEmit() event.
-- Use "self" to refer to the object itself. function NodeEmitter:onEmit(obj)
-- where 'obj' is the new object emitted
-- This will set the emitted object as the current viewport's player node
-- Which will make the camera track it (if camera has a tracking player controller added to it)
getUniverse():getMasterDisplay().activeViewPort.playerNode = obj
end
Particle effects are similar. These snippets assume a particle emitter called 'ParticleEmitter' is added as a child of our interactable box (from the Scripting Clipboard Sample Setup)
-- Find the child ParticleEmitter
particleEmitter = self:findNodeByName("ParticleEmitter")
-- Emit a burst of 100 particles
particleEmitter:emitBurst(100)
-- Point at another object
particleEmitter:emitBurst:pointAt(object:getWorldPosition())
-- Clear emitted objects
particleEmitter:emitBurst:reset()
Time
-- Get the parent space's timeline timeline = self:getSpace():getTimeline() -- Slow down time (1/4X) timeline.timeScale = 0.25 -- Speed up time (2X) timeline.timeScale = 2 -- Stop timeline timeline.active = false -- Start timeline timeline.active = true -- Rewind timeline timeline:rewind() -- Set an explicit play time to the 4 second mark timeline:setPlayTime(seconds(4)) -- Retrieve the current play time tm = timeline:getPlayTime() -- Print time in seconds print(tostring(tm:toSeconds()))
Player Controls and Actors
-- Set the active player control to this object -- If it had a PlayerContoller attached to it, it -- would become controllable getUniverse():getMasterDisplay().activeViewPort.playerNode = self
ViewPorts and Displays
-- Change the active viewport to a different one -- such as one that represents a different camera angle -- Find the viewport in the univere's library viewport2 = getUniverse():getSharedLibrary():findObjectByName("ViewPort 2") -- Set the master display's active viewport getUniverse():getMasterDisplay().activeViewPort = viewport2
Sounds
For these snippets, we assume a sound called 'Sound' is added as a child of our interactable box (from the Scripting Clipboard Sample Setup)
-- Change the active viewport to a different one -- such as one that represents a different camera angle -- Find the child sound sound = self:findNodeByName("Sound") -- Play the sound sound:play() -- Play an shared copy of the sound (makes a copy of it first) soundCopy = sound:playSharedCopy() -- Set the transpose pitch of the sound copy to a random one -- Note: for this to work for each individual shared copy -- you need to select 'Detach From Shared Copies' from the Transpose Pitch's -- property menu soundCopy.transposePitch = math.random(-48,48)
Helpful Math / Other Operations
object = findObjectByUid("16UJDTYCFJC9K1K31DZDDRICG4/16LZSFYKFJUA80LQBJ7HKBPTIO") -- Move this object up by 1 unit self:setWorldPosition(self:getWorldPosition() + vector3(0,1,0)) -- Get the distance between this object and the other object distance = (object:getWorldPosition() - self:getWorldPosition()):length() -- Have this object lookat the other object (along its +Z axis) self:lookAt(object:getWorldPosition()) -- Get the unit normal (facing vector) between to objects and -- compute a point located halfway between two objects vDelta = object:getWorldPosition() - self:getWorldPosition() -- Like above, get the distance between the two objects distance = vDelta:length() -- Normalize the delta vector, giving us a directional unit vector -- with no length vDelta:normalize() -- Set the unit vector's length to the halfway point vDelta = vDelta * distance * 0.5 -- Place this object at that halfway point self:setWorldPosition(self:getWorldPosition() + vDelta)
Objects: Active, Fade Out, Remove from Space
-- Deativate this object (hides it, stops playing sound, etc) self.active = false -- Fade out this object and remove from space self:fadeOutAndOrphan() -- Wait 10 seconds then fade out and remove object from space self:fadeOutAndOrphan(seconds(10)) -- Fade out the object immediately but fade it across 5 seconds self:fadeOutAndOrphan(seconds(0), seconds(5)) -- Fade in an object self:fadeIn() -- Fade in an object slowly self:fadeIn(seconds(5))
Comments
0 comments
Please sign in to leave a comment.