AmazonSumerianで物体をクリックしたらその場所にエンティティを出現させるができたのでやり方をメモしておく。
参考情報
- SumerianのSlackのraycastのサンプル
- API Reference
やってみたこと
配置された球をクリックするとその場所にボックスが表示されるようにする。
- Create EntityでBoxを追加する
- 追加したBoxをAssetsにドラッグして追加したBox Entityは削除しておく。
- Create EntityでSphereを追加する
- 追加したSphereのscaleを10あたりにして適当な場所に配置する
- 追加したSphereにCollider Componentを追加してShapeをSphereにしておく。
- 追加したSphereにScript Componentを追加して以下のCustom Scriptを追加する。
'use strict';
var setup = function(args, ctx, sumerian) {
cameraAndRaySetup(args, ctx);
ctx.onMouseDown = function(evt){
ctx.collisionPoint = undefined;
ctx.collisionPoint = getRayCollideFromMouse(args, ctx, evt);
if (ctx.collisionPoint != undefined) {
console.log(ctx.collisionPoint);
createEntity(args, ctx, ctx.collisionPoint);
}
};
//adds a listener for mouse down
ctx.domElement.addEventListener('mousedown', ctx.onMouseDown);
};
function createEntity(args, ctx, point) {
if (!ctx.entities) {
ctx.entities = [];
}
// ここのコメントを外して下のcloneをコメントアウトすると球を作成するようになる
/*var blue = new sumerian.Material("Blue", sumerian.ShaderLib.simpleColored);
blue.uniforms.color = [0, 0, 1];
var entity = ctx.world.createEntity(new sumerian.Sphere(32, 32), blue, "TestSphere").addToWorld();*/
var entity = sumerian.EntityUtils.clone(ctx.world, args.entity).addToWorld();
ctx.entities.push(entity);
entity.setTranslation([point.x, point.y, point.z]);
}
function cleanEntities(ctx) {
if (!ctx.entities) {
return;
}
for (let i=0; i < ctx.entities.length; i++) {
ctx.world.removeEntity(ctx.entities[i]);
}
}
function getRayCollideFromMouse(args, ctx, evt){
//reset the result
ctx.result.reset();
ctx.x = evt.clientX * ctx.dpr;
ctx.y = evt.clientY * ctx.dpr;
ctx.activeCameraEntity.cameraComponent.camera.getPickRay(ctx.x, ctx.y, ctx.viewportWidth, ctx.viewportHeight, ctx.ray);
ctx.physicsSystem.raycastClosest(ctx.ray.origin, ctx.ray.direction, args.maxDistance, {}, ctx.result);
if (ctx.result.entity != null){
if(ctx.result.entity.hasTag(args.targetTag)){
ctx.resultsFromCollide = ctx.result.point;
return(ctx.resultsFromCollide);
}
}
else{
console.log('ray did not hit a enitiy with a collider and a tag labeled' + args.targetTag);
}
}
var cleanup = function(args, ctx) {
//remove the listener when application stops
ctx.domElement.removeEventListener('mousedown', ctx.onMouseDown);
cleanEntities(ctx);
};
function cameraAndRaySetup(args, ctx){
//the device pixel ratio on you screen
ctx.dpr = ctx.world.gooRunner.renderer.devicePixelRatio;
//defines a ray
ctx.ray = new sumerian.Ray();
//defines the physics sytem
ctx.physicsSystem = ctx.world.getSystem('PhysicsSystem');
//defines the result
ctx.result = new sumerian.RaycastResult();
}
var parameters = [{
key: 'maxDistance',
type: 'float',
'default': 10000,
min: 0
},{
key: 'targetTag',
type: 'string',
'default': 'surface'
},{
type: 'entity',
key: 'entity',
description: 'Entity drop area'
}];
- 上記Scriptのentity parameterにAssetsのBoxをドラッグして指定しておく。
- 追加したSphereのTagsにsurfaceを追加する。
はまったこと
- 元のスクリプトだとcameraAndRaySetup関数でctx.activeCameraEntity.cameraComponent.cameraをctx.cameraに保存して利用していたがそうするとカメラをズームしたときにうまくraycastできなかった。
- 追加したentityはeditor上には表示されず削除しておかないとそのまま残り続ける。