update script/tutorials

This commit is contained in:
Andrew Meadows 2016-04-26 11:21:56 -07:00
parent 3a9cde8510
commit 39a1b9e75d
6 changed files with 508 additions and 679 deletions

View file

@ -1,6 +1,3 @@
// cowSpawner.js
// examples/cows
// //
// Created by Eric Levin on 3/25/16 // Created by Eric Levin on 3/25/16
// Copyright 2016 High Fidelity, Inc. // Copyright 2016 High Fidelity, Inc.
@ -11,43 +8,48 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
var orientation = MyAvatar.orientation; // references to our assets. entity scripts need to be served from somewhere that is publically accessible -- so http(s) or atp
orientation = Quat.safeEulerAngles(orientation); var SCRIPT_URL ="http://hifi-production.s3.amazonaws.com/tutorials/entity_scripts/cow.js";
orientation.x = 0; var MODEL_URL = "http://hifi-production.s3.amazonaws.com/tutorials/cow/cow.fbx";
orientation = Quat.fromVec3Degrees(orientation); var ANIMATION_URL = 'http://hifi-production.s3.amazonaws.com/tutorials/cow/cow.fbx';
var center = Vec3.sum(MyAvatar.getHeadPosition(), Vec3.multiply(2, Quat.getFront(orientation)));
// this part of the code describes how to center the entity in front of your avatar when it is created.
var orientation = MyAvatar.orientation;
orientation = Quat.safeEulerAngles(orientation);
orientation.x = 0;
orientation = Quat.fromVec3Degrees(orientation);
var center = Vec3.sum(MyAvatar.getHeadPosition(), Vec3.multiply(2, Quat.getFront(orientation)));
var SCRIPT_URL = Script.resolvePath("cowEntityScript.js?"); // An entity is described and created by specifying a map of properties
var cow = Entities.addEntity({ var cow = Entities.addEntity({
type: "Model", type: "Model",
modelURL: "http://hifi-content.s3.amazonaws.com/DomainContent/production/cow/newMooCow.fbx", modelURL: MODEL_URL,
name: "playa_model_throwinCow", name: "example_cow",
position: center, position: center,
animation: { animation: {
currentFrame: 278, currentFrame: 278,
running: true, running: true,
url: "http://hifi-content.s3.amazonaws.com/DomainContent/Junkyard/Playa/newMooCow.fbx" url: ANIMATION_URL
}, },
dimensions: { dimensions: {
x: 0.739, x: 0.739,
y: 1.613, y: 1.613,
z: 2.529 z: 2.529
}, },
dynamic: true, dynamic: true,
gravity: { gravity: {
x: 0, x: 0,
y: -5, y: -5,
z: 0 z: 0
}, },
shapeType: "box", lifetime: 3600,
script: SCRIPT_URL, shapeType: "box",
userData: "{\"grabbableKey\":{\"grabbable\":true}}" script: SCRIPT_URL,
}); userData: JSON.stringify({
grabbableKey: {
grabbable: true
}
})
});
Script.stop();
function cleanup() {
Entities.deleteEntity(cow);
}
Script.scriptEnding.connect(cleanup);

View file

@ -21,9 +21,7 @@ var DIE_SIZE = 0.20;
var madeSound = true; // Set false at start of throw to look for collision var madeSound = true; // Set false at start of throw to look for collision
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; SoundCache.getSound("http://hifi-production.s3.amazonaws.com/tutorials/dice/diceCollide.wav");
SoundCache.getSound("http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav");
var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissions to create new objects." var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissions to create new objects."
@ -32,17 +30,19 @@ var screenSize = Controller.getViewportDimensions();
var BUTTON_SIZE = 32; var BUTTON_SIZE = 32;
var PADDING = 3; var PADDING = 3;
Script.include(["libraries/toolBars.js"]); //a helper library for creating toolbars
Script.include(["../default/libraries/toolBars.js"]);
var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.dice.toolbar", function(screenSize) { var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.dice.toolbar", function(screenSize) {
return { return {
x: (screenSize.x / 2 - BUTTON_SIZE * 2 + PADDING), x: (screenSize.x / 2 - BUTTON_SIZE * 2 + PADDING),
y: (screenSize.y - (BUTTON_SIZE + PADDING)) y: (screenSize.y - (BUTTON_SIZE + PADDING))
}; };
}); });
var offButton = toolBar.addOverlay("image", { var offButton = toolBar.addOverlay("image", {
width: BUTTON_SIZE, width: BUTTON_SIZE,
height: BUTTON_SIZE, height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/close.png", imageURL: "http://hifi-production.s3.amazonaws.com/tutorials/dice/close.png",
color: { color: {
red: 255, red: 255,
green: 255, green: 255,
@ -56,7 +56,7 @@ var deleteButton = toolBar.addOverlay("image", {
y: screenSize.y - (BUTTON_SIZE + PADDING), y: screenSize.y - (BUTTON_SIZE + PADDING),
width: BUTTON_SIZE, width: BUTTON_SIZE,
height: BUTTON_SIZE, height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/delete.png", imageURL: "http://hifi-production.s3.amazonaws.com/tutorials/dice/delete.png",
color: { color: {
red: 255, red: 255,
green: 255, green: 255,
@ -65,7 +65,7 @@ var deleteButton = toolBar.addOverlay("image", {
alpha: 1 alpha: 1
}); });
var diceIconURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/images/dice.png" var diceIconURL = "http://hifi-production.s3.amazonaws.com/tutorials/dice/dice.png"
var diceButton = toolBar.addOverlay("image", { var diceButton = toolBar.addOverlay("image", {
x: screenSize.x / 2 + PADDING, x: screenSize.x / 2 + PADDING,
y: screenSize.y - (BUTTON_SIZE + PADDING), y: screenSize.y - (BUTTON_SIZE + PADDING),
@ -94,7 +94,7 @@ function shootDice(position, velocity) {
for (var i = 0; i < NUMBER_OF_DICE; i++) { for (var i = 0; i < NUMBER_OF_DICE; i++) {
dice.push(Entities.addEntity({ dice.push(Entities.addEntity({
type: "Model", type: "Model",
modelURL: HIFI_PUBLIC_BUCKET + "models/props/Dice/goldDie.fbx", modelURL: "http://hifi-production.s3.amazonaws.com/tutorials/dice/goldDie.fbx",
position: position, position: position,
velocity: velocity, velocity: velocity,
rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360), rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360),
@ -111,7 +111,7 @@ function shootDice(position, velocity) {
lifetime: LIFETIME, lifetime: LIFETIME,
shapeType: "box", shapeType: "box",
dynamic: true, dynamic: true,
collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav" collisionSoundURL: "http://hifi-production.s3.amazonaws.com/tutorials/dice/diceCollide.wav"
})); }));
position = Vec3.sum(position, Vec3.multiply(DIE_SIZE, Vec3.normalize(Quat.getRight(Camera.getOrientation())))); position = Vec3.sum(position, Vec3.multiply(DIE_SIZE, Vec3.normalize(Quat.getRight(Camera.getOrientation()))));
} }
@ -151,4 +151,4 @@ function scriptEnding() {
} }
Controller.mousePressEvent.connect(mousePressEvent); Controller.mousePressEvent.connect(mousePressEvent);
Script.scriptEnding.connect(scriptEnding); Script.scriptEnding.connect(scriptEnding);

View file

@ -1,37 +1,74 @@
// //
// Rat.js // Copyright 2016 High Fidelity, Inc.
// examples/toybox/entityScripts
// //
// Created by Eric Levin on11/11/15.
// Copyright 2015 High Fidelity, Inc.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ //
var center = Vec3.sum(MyAvatar.position, Vec3.multiply(1.5, Quat.getFront(Camera.getOrientation())));
var SCRIPT_URL = "http://hifi-production.s3.amazonaws.com/tutorials/entity_scripts/pistol.js";
var MODEL_URL = "http://hifi-production.s3.amazonaws.com/tutorials/pistol/gun.fbx";
var COLLISION_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/tutorials/pistol/drop.wav'
var pistolProperties = {
type: 'Model',
modelURL: MODEL_URL,
position: center,
dimensions: {
x: 0.05,
y: 0.23,
z: 0.36
},
script: SCRIPT_URL,
color: {
red: 200,
green: 0,
blue: 20
},
shapeType: 'box',
dynamic: true,
gravity: {
x: 0,
y: -5.0,
z: 0
},
lifetime: 3600,
restitution: 0,
damping: 0.5,
collisionSoundURL: COLLISION_SOUND_URL,
userData: JSON.stringify({
grabbableKey: {
invertSolidWhileHeld: true
},
wearable: {
joints: {
RightHand: [{
x: 0.07079616189002991,
y: 0.20177987217903137,
z: 0.06374628841876984
}, {
x: -0.5863648653030396,
y: -0.46007341146469116,
z: 0.46949487924575806,
w: -0.4733745753765106
}],
LeftHand: [{
x: 0.1802254319190979,
y: 0.13442856073379517,
z: 0.08504903316497803
}, {
x: 0.2198076844215393,
y: -0.7377811074256897,
z: 0.2780133783817291,
w: 0.574519157409668
}]
}
}
})
};
var pistol = Entities.addEntity(pistolProperties);
(function() { Script.stop();
var scriptURL = Script.resolvePath('pistol.js');
var _this;
PistolScriptSpawner = function() {
_this = this;
this.forceMultiplier = 1;
};
PistolScriptSpawner.prototype = {
enterEntity: function() {
Script.load(scriptURL);
},
preload: function(entityID) {
this.entityID = entityID;
},
};
// entity scripts always need to return a newly constructed object of our type
return new PistolScriptSpawner();
});

View file

@ -1,6 +1,3 @@
// cowEntityScript.js
// examples/cows
// //
// Created by Eric Levin on 3/25/16 // Created by Eric Levin on 3/25/16
// Copyright 2016 High Fidelity, Inc. // Copyright 2016 High Fidelity, Inc.
@ -12,57 +9,76 @@
// //
(function() { (function() {
Script.include("../libraries/utils.js");
var _this = this; var _this = this;
_this.COLLISION_COOLDOWN_TIME = 5000; _this.COLLISION_COOLDOWN_TIME = 5000;
_this.preload = function(entityID) {
this.preload = function(entityID) { //set our id so other methods can get it.
print("EBL Preload!!");
_this.entityID = entityID; _this.entityID = entityID;
_this.mooSound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/moo.wav") //load the mooing sound
_this.mooSoundOptions = {volume: 0.7, loop: false}; _this.mooSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/tutorials/cow/moo.wav")
_this.mooSoundOptions = {
volume: 0.7,
loop: false
};
//variables we will use to keep track of when to reset the cow
_this.timeSinceLastCollision = 0; _this.timeSinceLastCollision = 0;
_this.shouldUntipCow = true; _this.shouldUntipCow = true;
} }
this.collisionWithEntity = function(myID, otherID, collisionInfo) { _this.collisionWithEntity = function(myID, otherID, collisionInfo) {
if(_this.shouldUntipCow) { //we dont actually use any of the parameters above, since we don't really care what we collided with, or the details of the collision.
Script.setTimeout(function() {
_this.untipCow(); //5 seconds after a collision, upright the cow. protect from multiple collisions in a short timespan with the 'shouldUntipCow' variable
_this.shouldUntipCow = true; if (_this.shouldUntipCow) {
}, _this.COLLISION_COOLDOWN_TIME); //in Hifi, preface setTimeout with Script.setTimeout
} Script.setTimeout(function() {
_this.untipCow();
_this.shouldUntipCow = true;
}, _this.COLLISION_COOLDOWN_TIME);
}
_this.shouldUntipCow = false; _this.shouldUntipCow = false;
} }
this.untipCow = function() { _this.untipCow = function() {
// keep yaw but reset pitch and roll // keep yaw but reset pitch and roll
var cowProps = Entities.getEntityProperties(_this.entityID, ["rotation", "position"]); var cowProps = Entities.getEntityProperties(_this.entityID, ["rotation", "position"]);
var eulerRotation = Quat.safeEulerAngles(cowProps.rotation); var eulerRotation = Quat.safeEulerAngles(cowProps.rotation);
eulerRotation.x = 0; eulerRotation.x = 0;
eulerRotation.z = 0; eulerRotation.z = 0;
var newRotation = Quat.fromVec3Degrees(eulerRotation); var newRotation = Quat.fromVec3Degrees(eulerRotation);
//we zero out the velocity and angular velocity so the cow doesn't change position or spin
Entities.editEntity(_this.entityID, { Entities.editEntity(_this.entityID, {
rotation: newRotation, rotation: newRotation,
velocity: {x: 0, y: 0, z: 0}, velocity: {
angularVelocity: {x: 0, y: 0, z:0} x: 0,
y: 0,
z: 0
},
angularVelocity: {
x: 0,
y: 0,
z: 0
}
}); });
//play the mooing sound when we untip! if it isn't already playing.
_this.mooSoundOptions.position = cowProps.position; _this.mooSoundOptions.position = cowProps.position;
if (!_this.soundInjector) { if (!_this.soundInjector) {
_this.soundInjector = Audio.playSound(_this.mooSound, _this.mooSoundOptions); _this.soundInjector = Audio.playSound(_this.mooSound, _this.mooSoundOptions);
} else { } else {
//if its already playing, just restart
_this.soundInjector.setOptions(_this.mooSoundOptions); _this.soundInjector.setOptions(_this.mooSoundOptions);
_this.soundInjector.restart(); _this.soundInjector.restart();
} }
} }
}); });

View file

@ -1,477 +1,360 @@
// //
// pistol.js // pistol.js
// examples
// //
// Created by Eric Levin on 11/12/2015 // Created by Eric Levin on11/11/15.
// Copyright 2013 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
// //
// This is an example script that turns the hydra controllers and mouse into a entity gun.
// It reads the controller, watches for trigger pulls, and adds a force to any entity it hits
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
Script.include("../../../libraries/utils.js"); (function() {
Script.include("../../../libraries/constants.js");
var GUN_FORCE =20; var ZERO_VECTOR = {
Messages.sendMessage('Hifi-Hand-Disabler', "both");
var gameName = "Kill All The Rats!"
// var HOST = "localhost:5000"
var HOST = "desolate-bastion-1742.herokuapp.com";
var socketClient = new WebSocket("ws://" + HOST);
var username = GlobalServices.username;
var currentScore = 0;
function score() {
currentScore++;
socketClient.send(JSON.stringify({
username: username,
score: currentScore,
gameName: gameName
}))
}
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
var fireSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/GUN-SHOT2.raw");
var LASER_LENGTH = 100;
var LASER_WIDTH = 2;
var POSE_CONTROLS = [Controller.Standard.LeftHand, Controller.Standard.RightHand];
var TRIGGER_CONTROLS = [Controller.Standard.LT, Controller.Standard.RT];
var MIN_THROWER_DELAY = 1000;
var MAX_THROWER_DELAY = 1000;
var RELOAD_INTERVAL = 5;
var GUN_MODEL = HIFI_PUBLIC_BUCKET + "cozza13/gun/m1911-handgun+1.fbx?v=4";
var BULLET_VELOCITY = 10.0;
var GUN_OFFSETS = [{
x: 0.04,
y: 0.26,
z: 0.04
}, {
x: 0.04,
y: 0.26,
z: 0.04
}];
var GUN_ORIENTATIONS = [Quat.fromPitchYawRollDegrees(0, 90, 90), Quat.fromPitchYawRollDegrees(0, -90, 270)];
//x -> y
//y -> z
// z -> x
var BARREL_OFFSETS = [ {
x: -0.12,
y: 0.12,
z: 0.04
}, {
x: 0.12,
y: 0.12,
z: 0.04
} ];
var pointers = [];
pointers.push(Overlays.addOverlay("line3d", {
start: ZERO_VECTOR,
end: ZERO_VECTOR,
color: COLORS.RED,
alpha: 1,
visible: true,
lineWidth: LASER_WIDTH
}));
pointers.push(Overlays.addOverlay("line3d", {
start: ZERO_VECTOR,
end: ZERO_VECTOR,
color: COLORS.RED,
alpha: 1,
visible: true,
lineWidth: LASER_WIDTH
}));
var mapping = Controller.newMapping();
var validPoses = [false, false];
var barrelVectors = [0, 0];
var barrelTips = [0, 0];
// If enabled, anything can be shot, otherwise, an entity needs to have "isShootable" set in its userData
var shootAnything = true;
function update(deltaTime) {
// FIXME we should also expose MyAvatar.handPoses[2], MyAvatar.tipPoses[2]
var tipPoses = [MyAvatar.leftHandTipPose, MyAvatar.rightHandTipPose];
for (var side = 0; side < 2; side++) {
// First check if the controller is valid
var controllerPose = Controller.getPoseValue(POSE_CONTROLS[side]);
validPoses[side] = controllerPose.valid;
// Need to adjust the laser
var tipPose = tipPoses[side];
var handRotation = tipPoses[side].rotation;
var barrelOffset = Vec3.multiplyQbyV(handRotation, BARREL_OFFSETS[side]);
barrelTips[side] = Vec3.sum(tipPose.translation, barrelOffset);
barrelVectors[side] = Vec3.multiplyQbyV(handRotation, {
x: 0, x: 0,
y: 1, y: 0,
z: 0 z: 0
}); };
var _this;
var DISABLE_LASER_THRESHOLD = 0.2;
var TRIGGER_CONTROLS = [
Controller.Standard.LT,
Controller.Standard.RT,
];
var RELOAD_THRESHOLD = 0.95;
var laserTip = Vec3.sum(Vec3.multiply(LASER_LENGTH, barrelVectors[side]), barrelTips[side]); Pistol = function() {
// Update Lasers _this = this;
Overlays.editOverlay(pointers[side], { this.equipped = false;
start: barrelTips[side], this.forceMultiplier = 1;
end: laserTip, this.laserLength = 100;
alpha: 1,
});
} this.fireSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/tutorials/pistol/GUN-SHOT2.raw");
} this.ricochetSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/tutorials/pistol/Ricochet.L.wav");
this.playRichochetSoundChance = 0.1;
this.fireVolume = 0.2;
this.bulletForce = 10;
this.showLaser = false;
this.laserOffsets = {
y: 0.095
};
this.firingOffsets = {
z: 0.16
}
function displayPointer(side) {
Overlays.editOverlay(pointers[side], {
visible: true
});
}
function hidePointer(side) {
Overlays.editOverlay(pointers[side], {
visible: false
});
}
function fire(side, value) {
if (value == 0) {
return;
}
Audio.playSound(fireSound, {
position: barrelTips[side],
volume: 0.5
});
var shotDirection = Vec3.normalize(barrelVectors[side]);
var pickRay = {
origin: barrelTips[side],
direction: shotDirection
}; };
createMuzzleFlash(barrelTips[side]);
var intersection = Entities.findRayIntersectionBlocking(pickRay, true); Pistol.prototype = {
if (intersection.intersects) { canShoot: false,
Script.setTimeout(function() {
createEntityHitEffect(intersection.intersection); startEquip: function(id, params) {
if (shootAnything && intersection.properties.dynamic === 1) { this.equipped = true;
// Any dynamic entity can be shot this.hand = params[0] == "left" ? 0 : 1;
Entities.editEntity(intersection.entityID, { },
velocity: Vec3.multiply(shotDirection, GUN_FORCE)
continueEquip: function(id, params) {
if (!this.equipped) {
return;
}
this.updateProps();
if (this.showLaser) {
this.updateLaser();
}
this.toggleWithTriggerPressure();
},
updateProps: function() {
var gunProps = Entities.getEntityProperties(this.entityID, ['position', 'rotation']);
this.position = gunProps.position;
this.rotation = gunProps.rotation;
this.firingDirection = Quat.getFront(this.rotation);
var upVec = Quat.getUp(this.rotation);
this.barrelPoint = Vec3.sum(this.position, Vec3.multiply(upVec, this.laserOffsets.y));
this.laserTip = Vec3.sum(this.barrelPoint, Vec3.multiply(this.firingDirection, this.laserLength));
this.barrelPoint = Vec3.sum(this.barrelPoint, Vec3.multiply(this.firingDirection, this.firingOffsets.z))
var pickRay = {
origin: this.barrelPoint,
direction: this.firingDirection
};
},
toggleWithTriggerPressure: function() {
this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[this.hand]);
if (this.triggerValue < RELOAD_THRESHOLD) {
this.canShoot = true;
}
if (this.canShoot === true && this.triggerValue === 1) {
this.fire();
this.canShoot = false;
}
if (this.triggerValue < DISABLE_LASER_THRESHOLD && this.showLaser === true) {
this.showLaser = false;
Overlays.editOverlay(this.laser, {
visible: false
});
} else if (this.triggerValue >= DISABLE_LASER_THRESHOLD && this.showLaser === false) {
this.showLaser = true
Overlays.editOverlay(this.laser, {
visible: true
}); });
} }
if (intersection.properties.name === "rat") {
score();
createBloodSplatter(intersection.intersection);
Entities.deleteEntity(intersection.entityID);
} },
//Attempt to call entity method's shot method updateLaser: function() {
var forceDirection = JSON.stringify({
forceDirection: shotDirection Overlays.editOverlay(this.laser, {
start: this.barrelPoint,
end: this.laserTip,
alpha: 1
}); });
Entities.callEntityMethod(intersection.entityID, 'onShot', [forceDirection]);
}, 0);
}
}
function scriptEnding() {
Messages.sendMessage('Hifi-Hand-Disabler', 'none');
mapping.disable();
for (var i = 0; i < pointers.length; ++i) {
Overlays.deleteOverlay(pointers[i]);
}
MyAvatar.detachOne(GUN_MODEL);
MyAvatar.detachOne(GUN_MODEL);
clearPose();
}
MyAvatar.attach(GUN_MODEL, "LeftHand", GUN_OFFSETS[0], GUN_ORIENTATIONS[0], 0.40);
MyAvatar.attach(GUN_MODEL, "RightHand", GUN_OFFSETS[1], GUN_ORIENTATIONS[1], 0.40);
function showPointer(side) {
Overlays.editOverlay(pointers[side], {
visible: true
});
}
mapping.from(Controller.Standard.LT).hysteresis(0.0, 0.5).to(function(value) {
fire(0, value);
});
mapping.from(Controller.Standard.RT).hysteresis(0.0, 0.5).to(function(value) {
fire(1, value);
});
mapping.enable();
Script.scriptEnding.connect(scriptEnding);
Script.update.connect(update);
function createEntityHitEffect(position) {
var flash = Entities.addEntity({
type: "ParticleEffect",
position: position,
lifetime: 4,
"name": "Flash Emitter",
"color": {
red: 228,
green: 128,
blue: 12
}, },
"maxParticles": 1000,
"lifespan": 0.15,
"emitRate": 1000,
"emitSpeed": 1,
"speedSpread": 0,
"emitOrientation": {
"x": -0.4,
"y": 1,
"z": -0.2,
"w": 0.7071068286895752
},
"emitDimensions": {
"x": 0,
"y": 0,
"z": 0
},
"polarStart": 0,
"polarFinish": Math.PI,
"azimuthStart": -3.1415927410125732,
"azimuthFinish": 2,
"emitAcceleration": {
"x": 0,
"y": 0,
"z": 0
},
"accelerationSpread": {
"x": 0,
"y": 0,
"z": 0
},
"particleRadius": 0.03,
"radiusSpread": 0.02,
"radiusStart": 0.02,
"radiusFinish": 0.03,
"colorSpread": {
red: 100,
green: 100,
blue: 20
},
"alpha": 1,
"alphaSpread": 0,
"alphaStart": 0,
"alphaFinish": 0,
"additiveBlending": true,
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
});
Script.setTimeout(function() { releaseEquip: function(id, params) {
Entities.editEntity(flash, { this.hand = null;
isEmitting: false this.equipped = false;
}); Overlays.editOverlay(this.laser, {
}, 100); visible: false
});
},
} triggerPress: function(hand, value) {
if (this.hand === hand && value === 1) {
//We are pulling trigger on the hand we have the gun in, so fire
this.fire();
}
},
fire: function() {
function createBloodSplatter(position) { Audio.playSound(this.fireSound, {
var splatter = Entities.addEntity({ position: this.barrelPoint,
type: "ParticleEffect", volume: this.fireVolume
position: position, });
lifetime: 4,
"name": "Blood Splatter",
"color": {
red: 230,
green: 2,
blue: 30
},
"maxParticles": 1000,
"lifespan": 0.3,
"emitRate": 1000,
"emitSpeed": 0.5,
"speedSpread": 0,
"emitOrientation": {
"x": -0.4,
"y": 1,
"z": -0.2,
"w": 0.7071068286895752
},
"emitDimensions": {
"x": 0,
"y": 0,
"z": 0
},
"polarStart": 0,
"polarFinish": Math.PI,
"azimuthStart": -3.1415927410125732,
"azimuthFinish": 2,
"emitAcceleration": {
"x": 0,
"y": -5,
"z": 0
},
"accelerationSpread": {
"x": 0,
"y": 0,
"z": 0
},
"particleRadius": 0.05,
"radiusSpread": 0.03,
"radiusStart": 0.05,
"radiusFinish": 0.05,
"colorSpread": {
red: 40,
green: 0,
blue: 30
},
"alpha": 1,
"alphaSpread": 0,
"alphaStart": 0,
"alphaFinish": 0,
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
});
Script.setTimeout(function() { var pickRay = {
Entities.editEntity(splatter, { origin: this.barrelPoint,
isEmitting: false direction: this.firingDirection
}); };
}, 100) this.createGunFireEffect(this.barrelPoint)
var intersection = Entities.findRayIntersectionBlocking(pickRay, true);
if (intersection.intersects) {
this.createEntityHitEffect(intersection.intersection);
if (Math.random() < this.playRichochetSoundChance) {
Script.setTimeout(function() {
Audio.playSound(_this.ricochetSound, {
position: intersection.intersection,
volume: _this.fireVolume
});
}, randFloat(10, 200));
}
if (intersection.properties.dynamic === 1) {
// Any dynaic entity can be shot
Entities.editEntity(intersection.entityID, {
velocity: Vec3.multiply(this.firingDirection, this.bulletForce)
});
}
}
},
} unload: function() {
Overlays.deleteOverlay(this.laser);
},
createEntityHitEffect: function(position) {
var sparks = Entities.addEntity({
type: "ParticleEffect",
position: position,
lifetime: 4,
"name": "Sparks Emitter",
"color": {
red: 228,
green: 128,
blue: 12
},
"maxParticles": 1000,
"lifespan": 0.15,
"emitRate": 1000,
"emitSpeed": 1,
"speedSpread": 0,
"emitOrientation": {
"x": -0.4,
"y": 1,
"z": -0.2,
"w": 0.7071068286895752
},
"emitDimensions": {
"x": 0,
"y": 0,
"z": 0
},
"polarStart": 0,
"polarFinish": Math.PI,
"azimuthStart": -3.1415927410125732,
"azimuthFinish": 2,
"emitAcceleration": {
"x": 0,
"y": 0,
"z": 0
},
"accelerationSpread": {
"x": 0,
"y": 0,
"z": 0
},
"particleRadius": 0.03,
"radiusSpread": 0.02,
"radiusStart": 0.02,
"radiusFinish": 0.03,
"colorSpread": {
red: 100,
green: 100,
blue: 20
},
"alpha": 1,
"alphaSpread": 0,
"alphaStart": 0,
"alphaFinish": 0,
"additiveBlending": true,
"textures": "http://hifi-production.s3.amazonaws.com/tutorials/pistol/star.png"
});
function createMuzzleFlash(position) { Script.setTimeout(function() {
var smoke = Entities.addEntity({ Entities.editEntity(sparks, {
type: "ParticleEffect", isEmitting: false
position: position, });
lifetime: 1, }, 100);
"name": "Smoke Hit Emitter",
"maxParticles": 1000,
"lifespan": 4,
"emitRate": 20,
emitSpeed: 0,
"speedSpread": 0,
"emitDimensions": {
"x": 0,
"y": 0,
"z": 0
},
"polarStart": 0,
"polarFinish": 0,
"azimuthStart": -3.1415927410125732,
"azimuthFinish": 3.14,
"emitAcceleration": {
"x": 0,
"y": 0.5,
"z": 0
},
"accelerationSpread": {
"x": .2,
"y": 0,
"z": .2
},
"radiusSpread": .04,
"particleRadius": 0.07,
"radiusStart": 0.07,
"radiusFinish": 0.07,
"alpha": 0.7,
"alphaSpread": 0,
"alphaStart": 0,
"alphaFinish": 0,
"additiveBlending": 0,
"textures": "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"
});
Script.setTimeout(function() {
Entities.editEntity(smoke, {
isEmitting: false
});
}, 100);
var flash = Entities.addEntity({
type: "ParticleEffect",
position: position,
lifetime: 4,
"name": "Muzzle Flash",
"color": {
red: 228,
green: 128,
blue: 12
}, },
"maxParticles": 1000,
"lifespan": 0.1,
"emitRate": 1000,
"emitSpeed": 0.5,
"speedSpread": 0,
"emitOrientation": {
"x": -0.4,
"y": 1,
"z": -0.2,
"w": 0.7071068286895752
},
"emitDimensions": {
"x": 0,
"y": 0,
"z": 0
},
"polarStart": 0,
"polarFinish": Math.PI,
"azimuthStart": -3.1415927410125732,
"azimuthFinish": 2,
"emitAcceleration": {
"x": 0,
"y": 0,
"z": 0
},
"accelerationSpread": {
"x": 0,
"y": 0,
"z": 0
},
"particleRadius": 0.05,
"radiusSpread": 0.01,
"radiusStart": 0.05,
"radiusFinish": 0.05,
"colorSpread": {
red: 100,
green: 100,
blue: 20
},
"alpha": 1,
"alphaSpread": 0,
"alphaStart": 0,
"alphaFinish": 0,
"additiveBlending": true,
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
});
Script.setTimeout(function() { createGunFireEffect: function(position) {
Entities.editEntity(flash, { var smoke = Entities.addEntity({
isEmitting: false type: "ParticleEffect",
}); position: position,
}, 100) lifetime: 1,
"name": "Smoke Hit Emitter",
"maxParticles": 1000,
"lifespan": 4,
"emitRate": 20,
emitSpeed: 0,
"speedSpread": 0,
"emitDimensions": {
"x": 0,
"y": 0,
"z": 0
},
"polarStart": 0,
"polarFinish": 0,
"azimuthStart": -3.1415927410125732,
"azimuthFinish": 3.14,
"emitAcceleration": {
"x": 0,
"y": 0.5,
"z": 0
},
"accelerationSpread": {
"x": 0.2,
"y": 0,
"z": 0.2
},
"radiusSpread": 0.04,
"particleRadius": 0.07,
"radiusStart": 0.07,
"radiusFinish": 0.07,
"alpha": 0.7,
"alphaSpread": 0,
"alphaStart": 0,
"alphaFinish": 0,
"additiveBlending": 0,
"textures": "http://hifi-production.s3.amazonaws.com/tutorials/pistol/smoke.png"
});
Script.setTimeout(function() {
Entities.editEntity(smoke, {
isEmitting: false
});
}, 100);
var flash = Entities.addEntity({
type: "ParticleEffect",
position: this.barrelPoint,
"name": "Muzzle Flash",
lifetime: 4,
parentID: this.entityID,
"color": {
red: 228,
green: 128,
blue: 12
},
"maxParticles": 1000,
"lifespan": 0.1,
"emitRate": 1000,
"emitSpeed": 0.5,
"speedSpread": 0,
"emitOrientation": {
"x": -0.4,
"y": 1,
"z": -0.2,
"w": 0.7071068286895752
},
"emitDimensions": {
"x": 0,
"y": 0,
"z": 0
},
"polarStart": 0,
"polarFinish": Math.PI,
"azimuthStart": -3.1415927410125732,
"azimuthFinish": 2,
"emitAcceleration": {
"x": 0,
"y": 0,
"z": 0
},
"accelerationSpread": {
"x": 0,
"y": 0,
"z": 0
},
"particleRadius": 0.05,
"radiusSpread": 0.01,
"radiusStart": 0.05,
"radiusFinish": 0.05,
"colorSpread": {
red: 100,
green: 100,
blue: 20
},
"alpha": 1,
"alphaSpread": 0,
"alphaStart": 0,
"alphaFinish": 0,
"additiveBlending": true,
"textures": "http://hifi-production.s3.amazonaws.com/tutorials/pistol/star.png"
});
Script.setTimeout(function() {
Entities.editEntity(flash, {
isEmitting: false
});
}, 100)
} },
preload: function(entityID) {
this.entityID = entityID;
this.laser = Overlays.addOverlay("line3d", {
start: ZERO_VECTOR,
end: ZERO_VECTOR,
color: COLORS.RED,
alpha: 1,
visible: true,
lineWidth: 2
});
},
};
// entity scripts always need to return a newly constructed object of our type
return new Pistol();
});

View file

@ -1,148 +1,39 @@
// //
// clap.js // Created by James B. Pollack @imgntn on April 18, 2016.
// examples // Copyright 2016 High Fidelity, Inc.
// //
// Copyright 2014 High Fidelity, Inc.
//
// This sample script watches your hydra hands and makes clapping sound when they come close together fast,
// and also watches for the 'shift' key and claps when that key is pressed. Clapping multiple times by pressing
// the shift key again makes the animation and sound match your pace of clapping.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; // An animation of the avatar clapping its hands while standing
var ANIM_URL = "http://hifi-production.s3.amazonaws.com/tutorials/avatarAnimation/clap.fbx";
var clapAnimation = HIFI_PUBLIC_BUCKET + "animations/ClapAnimations/ClapHands_Standing.fbx"; // overrideRoleAnimation only replaces a single animation at a time. the rest of the motion is driven normally
var ANIMATION_FRAMES_PER_CLAP = 10.0; // @animationRole - name of animation
var startEndFrames = []; // @animationURL - url
startEndFrames.push({ start: 0, end: 10}); // @playbackRate - frames per second
startEndFrames.push({ start: 10, end: 20}); // @loopFlag - should loop
startEndFrames.push({ start: 20, end: 30}); // @startFrame
startEndFrames.push({ start: 30, end: 40}); // @endFrame
startEndFrames.push({ start: 41, end: 51}); MyAvatar.overrideRoleAnimation("idleStand", ANIM_URL, 30, true, 0, 53);
startEndFrames.push({ start: 53, end: 0});
var lastClapFrame = 0; //stop a a minute because your hands got tired.
var lastAnimFrame = 0; Script.setTimeout(function(){
MyAvatar.restoreRoleAnimation("idleStand");
Script.stop();
},60000)
var claps = []; //or stop when the script is manually stopped
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap1Rvb.wav")); Script.scriptEnding.connect(function () {
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap2Rvb.wav")); MyAvatar.restoreRoleAnimation("idleStand");
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap3Rvb.wav"));
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap4Rvb.wav"));
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap5Rvb.wav"));
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap6Rvb.wav"));
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap7Rvb.wav"));
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap8Rvb.wav"));
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap9Rvb.wav"));
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap10Rvb.wav"));
var numberOfSounds = claps.length;
var clappingNow = false;
var collectedClicks = 0;
var clickStartTime, clickEndTime;
var clickClappingNow = false;
var CLAP_START_RATE = 15.0;
var clapRate = CLAP_START_RATE;
var startedTimer = false;
function maybePlaySound(deltaTime) {
// Set the location and other info for the sound to play
var animationDetails = MyAvatar.getAnimationDetails(clapAnimation);
var frame = Math.floor(animationDetails.frameIndex);
if (frame != lastAnimFrame) {
lastAnimFrame = frame;
}
for (var i = 0; i < startEndFrames.length; i++) {
if (frame == startEndFrames[i].start && (frame != lastClapFrame)) {
playClap(1.0, Camera.getPosition());
lastClapFrame = frame;
}
}
var palm1Position = MyAvatar.getLeftPalmPosition();
var palm2Position = MyAvatar.getRightPalmPosition();
var distanceBetween = Vec3.length(Vec3.subtract(palm1Position, palm2Position));
var palm1Velocity = Controller.getPoseValue(Controller.Standard.LeftHand).velocity;
var palm2Velocity = Controller.getPoseValue(Controller.Standard.RightHand).velocity;
var closingVelocity = Vec3.length(Vec3.subtract(palm1Velocity, palm2Velocity));
const CLAP_SPEED = 0.7;
const CLAP_DISTANCE = 0.15;
if ((closingVelocity > CLAP_SPEED) && (distanceBetween < CLAP_DISTANCE) && !clappingNow) {
var volume = closingVelocity / 2.0;
if (volume > 1.0) volume = 1.0;
playClap(volume, palm1Position);
clappingNow = true;
} else if (clappingNow && (distanceBetween > CLAP_DISTANCE * 1.2)) {
clappingNow = false;
}
}
function playClap(volume, position) {
var clip = Math.floor(Math.random() * numberOfSounds);
Audio.playSound(claps[clip], {
position: position,
volume: volume
});
}
var FASTEST_CLAP_INTERVAL = 150.0;
var SLOWEST_CLAP_INTERVAL = 750.0;
Controller.keyPressEvent.connect(function(event) {
if(event.text == "SHIFT") {
if (!clickClappingNow) {
clickClappingNow = true;
clickStartTime = new Date();
lastClapFrame = 0;
} else {
// start or adjust clapping speed based on the duration between clicks
clickEndTime = new Date();
var milliseconds = Math.max(clickEndTime - clickStartTime, FASTEST_CLAP_INTERVAL);
clickStartTime = new Date();
if (milliseconds < SLOWEST_CLAP_INTERVAL) {
clapRate = ANIMATION_FRAMES_PER_CLAP * (1000.0 / milliseconds);
playClap(1.0, Camera.getPosition());
MyAvatar.stopAnimation(clapAnimation);
MyAvatar.startAnimation(clapAnimation, clapRate, 1.0, true, false);
}
collectedClicks = collectedClicks + 1;
}
}
}); });
var CLAP_END_WAIT_MSECS = 300; //overRideAnimation replaces all animations, so you dont have to provide a role name
Controller.keyReleaseEvent.connect(function(event) { // @animationURL - url
if (event.text == "SHIFT") { // @playbackRate - frames per second
collectedClicks = 0; // @loopFlag - should loop
if (!startedTimer) { // @startFrame
collectedClicks = 0; // @endFrame
Script.setTimeout(stopClapping, CLAP_END_WAIT_MSECS); //MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53);
startedTimer = true;
}
}
});
function stopClapping() {
if (collectedClicks == 0) {
startedTimer = false;
MyAvatar.stopAnimation(clapAnimation);
clapRate = CLAP_START_RATE;
clickClappingNow = false;
} else {
startedTimer = false;
}
}
// Connect a call back that happens every frame
Script.update.connect(maybePlaySound);