I'm trying to test a simple oscillator not attached to any world object on the scene. Simply a tone, but following the example for a oscillator node does not seem to play anything. Does it require some kind of user interaction first to be allowed to play?
I also have a cube rotating on the scene, but it shouldn't affect anything. The script:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
function animate() {
requestAnimationFrame( animate );
cube.rotation.x += 0.05;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
}
animate();
// create web audio api context
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// create Oscillator node
var oscillator = audioCtx.createOscillator();
oscillator.type = 'square';
oscillator.frequency.setValueAtTime(440, audioCtx.currentTime); // value in hertz
var gainNode = audioCtx.createGain();
oscillator.connect(gainNode);
oscillator.connect(audioCtx.destination);
var initialFreq = 3000;
var initialVol = 0.500;
gainNode.gain.value = initialVol;
gainNode.gain.minValue = initialVol;
gainNode.gain.maxValue = initialVol;
oscillator.frequency.value = 3000;
oscillator.start();
Related
I have faced a problem while making solid ground that will make my sphere stop from falling through the plane…
the code below should prevent the sphere from falling through the plane, and also I know that you need to rotate the solid body...
const planeBody = new CANNON.Body({mass: 0})
but surprisingly it doesn’t have any effect at all, what should happen is that it should stop the sphere from falling through the plane…
also, there is another weird problem
the code below should make the plane fall along with the sphere if the sphere also has a mass equal to 1, and indeed that is what happens here
const planeBody = new CANNON.Body({mass: 1})
but when you try to rewrite it in this form, it stops from working
const planeBody = new CANNON.Body()
planeBody.mass = 1;
here is my complete code
import * as THREE from './threeJS/three.module.js';
import { OrbitControls } from './examples/jsm/controls/OrbitControls.js';
import { GUI } from '../dat.gui/files/dat.gui.module.js';
import * as THREEx from './threeX/threeX.keyboardState.js';
// gui
// const gui = new GUI();
// keyboard
const keyboard = new THREEx.default();
// console.log(THREEx.default);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x777777);
// Meshes
const plane = new THREE.Mesh(
new THREE.PlaneGeometry(40, 40),
new THREE.MeshStandardMaterial({ color: 0xdddddd, side: THREE.DoubleSide })
);
plane.rotateX(90 / 57.3);
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(3, 64, 32),
new THREE.MeshStandardMaterial({ color: 'red' })
);
sphere.position.y = 5;
let clientWidth = document.documentElement.clientWidth;
let clientHeight = document.documentElement.clientHeight;
// prettier-ignore
const camera = new THREE.PerspectiveCamera(45, clientWidth / clientHeight, 0.1, 1000);
const canvas = document.querySelector('.webgl');
const controls = new OrbitControls(camera, canvas);
controls.enableDamping = true;
camera.position.set(0, 20, 30);
controls.update();
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true,
});
renderer.setSize(clientWidth, clientHeight);
renderer.shadowMap.enabled = true;
// lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(0, 7, 5);
directionalLight.target = sphere;
directionalLight.target.updateMatrixWorld();
directionalLight.castShadow = true;
// shadows
// ! only three types of light that support shadows
// ! spotlight
// ! directional light
// ! point light
// ! castShadow means will it create a shadow? receiveShadow means will the shadow be on it?
sphere.castShadow = true;
plane.receiveShadow = true;
// Helpers
const AxesHelper = new THREE.AxesHelper(5);
scene.add(AxesHelper, camera, sphere, plane, directionalLight, ambientLight);
// Clock
const clock = new THREE.Clock();
let oldElapsedTime = 0;
// physics
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
// Sphere
const sphereShape = new CANNON.Sphere(3);
const sphereBody = new CANNON.Body({
mass: 1,
position: new CANNON.Vec3(0, 5, 0),
shape: sphereShape,
});
world.addBody(sphereBody);
// infinite Plane
const planeShape = new CANNON.Plane();
const planeBody = new CANNON.Body({
mass: 0,
});
planeBody.addShape(planeShape);
planeBody.quaternion.setFromAxisAngle(new CANNON.Vec3(-1, 0, 0), Math.PI * 0.5);
world.addBody(planeBody);
function animate() {
requestAnimationFrame(animate);
let ElapsedTime = clock.getElapsedTime();
let deltaTime = ElapsedTime - oldElapsedTime;
oldElapsedTime = deltaTime;
// to update the world 60 times per second
world.step(1 / 60, deltaTime, 3);
directionalLight.position.z = 3 * Math.sin(ElapsedTime);
directionalLight.position.x = 3 * Math.cos(ElapsedTime);
directionalLight.lookAt(sphere.position);
sphere.position.copy(sphereBody.position);
plane.position.copy(planeBody.position);
// sphere.position.x = keyboard.pressed('right')
// ? sphere.position.x + 0.1
// : keyboard.pressed('left')
// ? sphere.position.x - 0.1
// : sphere.position.x;
// sphere.position.z = keyboard.pressed('up')
// ? sphere.position.z - 0.1
// : keyboard.pressed('down')
// ? sphere.position.z + 0.1
// : sphere.position.z;
controls.update();
renderer.render(scene, camera);
}
animate();
//events
window.addEventListener('resize', () => {
clientWidth = document.documentElement.clientWidth;
clientHeight = document.documentElement.clientHeight;
camera.aspect = clientWidth / clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(clientWidth, clientHeight);
});
window.addEventListener('dblclick', () => {
if (!document.fullscreenElement) {
canvas.requestFullscreen();
} else {
document.exitFullscreen();
}
});
How to CastRay() for Unity.Physics.SphereCollider struct without SphereCollider.Create() factory method call (resulting in heap allocation I presume).
Code below doesn't work and not sure why exactly:
using Physics = Unity.Physics;
bool TraceRaySphere
(
float3 spherePos ,
float sphereRadius ,
float3 rayStart ,
float3 rayEnd ,
out Physics.RaycastHit raycastHit
)
{
var ray = new Physics.RaycastInput{
Start = rayStart ,
End = rayEnd ,
Filter = Physics.CollisionFilter.Default
};
var geometry = new Physics.SphereGeometry{
Center = spherePos ,
Radius = sphereRadius
};
var sphere = new Physics.SphereCollider{
Geometry = geometry ,
Filter = Physics.CollisionFilter.Default
};
return sphere.CastRay( ray , out raycastHit );
}
This works, but uses mentioned SphereCollider.Create(geometry) factory method I want to get rid of (if that's possible):
public static bool TraceRaySphere
(
float3 spherePos ,
float sphereRadius ,
float3 rayStart ,
float3 rayEnd ,
out RaycastHit raycastHit
)
{
var ray = new RaycastInput{
Start = rayStart ,
End = rayEnd ,
Filter = CollisionFilter.Default
};
var geometry = new SphereGeometry{
Center = spherePos ,
Radius = sphereRadius
};
var sphereBlobAsset = SphereCollider.Create( geometry );
bool didHit = sphereBlobAsset.Value.CastRay( ray , out raycastHit );
sphereBlobAsset.Dispose();
return didHit;
}
In my project i use following helper method to cast any Colliders (needs unsafe code execution flag because its working with the pointer)
public static unsafe bool ColliderCast(float3 rayFrom, float3 rayTo, quaternion rotation, CollisionWorld collisionWorld, PhysicsCollider collider)
{
ColliderCastInput input = new ColliderCastInput()
{
Collider = (Collider*)collider.Value.GetUnsafePtr(),
Orientation = rotation,
Start = rayFrom,
End = rayTo
};
return collisionWorld.CastCollider(input);
}
And i also have a CollisionGeome
trySingleton class which contains this
//Cache geometries (float3 = size, float3 = center)
private IDictionary<Tuple<float3, float3>, BoxGeometry> boxGeometries;
public BoxGeometry CreateOrGetBoxGeometry(float3 size, float3 center)
{
if(this.boxGeometries == null)
{
this.boxGeometries = new Dictionary<Tuple<float3,float3>, BoxGeometry>();
}
Tuple<float3, float3> key = new Tuple<float3, float3>(size, center);
if(!this.boxGeometries.ContainsKey(key))
{
this.boxGeometries.Add(key, new BoxGeometry { Size = key.Item1, Center = key.Item2, Orientation = quaternion.identity });
}
return this.boxGeometries[key];
}
This allows me to use
BoxCollider.Create
(
CollisionGeomeotrySingleton.Instance.CreateOrGetBoxGeometry(5, 5),
CollisionFilterSingleton.Instance.CollidesWithPlayerFilter
)
You could go now one step further and store the BoxCollider also in the CollisionGeometrySingleton
SphereCollider struct contains few hidden private fields that requires Init(args) method to be called in order to set those up with proper values:
public static bool TraceRaySphere
(
float3 spherePos ,
float sphereRadius ,
float3 rayStart ,
float3 rayEnd ,
out RaycastHit raycastHit
)
{
var ray = new RaycastInput
{
Start = rayStart ,
End = rayEnd ,
Filter = CollisionFilter.Default
};
var geometry = new SphereGeometry
{
Center = spherePos ,
Radius = sphereRadius
};
var sphere = default(SphereCollider);
sphere.Init( geometry , CollisionFilter.Default , Material.Default );
return sphere.CastRay( ray , out raycastHit );
}
However
this method is private (chances are this may change).
To make Init method available you need to modify ...\com.unity.physics#0.5.0-preview.1\Unity.Physics\Collision\Colliders\Physics_SphereCollider.cs source file and make it public.
I have this code (not originally my invention) that is working fine, but I have hit upon a problem with it. I can't seem to render the second submesh, with another material.
I can't figure out the problem lies in [renderer] part or the 2nd "submesh" that is perhaps never combining.
#script RequireComponent(MeshFilter)
#script RequireComponent(MeshRenderer)
private var matarray : Material[] = new Material[2];
var mat : Material;
var mat2 : Material;
function Start () {
matarray[0] = mat;
matarray[1] = mat2;
for (var child in transform)
child.position += transform.position;
transform.position = Vector3.zero;
transform.rotation = Quaternion.identity;
var meshFilters = GetComponentsInChildren(MeshFilter);
var combine : CombineInstance[] = new CombineInstance[meshFilters.Length-1];
var index = 0;
for (var i = 0; i < meshFilters.Length; i++) {
if (meshFilters[i].sharedMesh == null)
continue;
combine[index].mesh = meshFilters[i].sharedMesh;
combine[index++].transform = meshFilters[i].transform.localToWorldMatrix;
renderer.sharedMaterials = matarray;
meshFilters[i].active = false;
}
GetComponent(MeshFilter).mesh = new Mesh();
GetComponent(MeshFilter).mesh.CombineMeshes(combine);
renderer.active = true;
//here seems to be the trouble.
renderer.sharedMaterials = matarray;
}
Alternatively I have tried,
renderer.sharedMaterials[1] = matarray[1];
In short, I'm in trouble. I have to save few draw calls, which is not looking good unless this gets fixed.
OVERALL GOAL: Have the camera change target to the selected car
I'm new to the unity game engine and got a bit of a problem.
So, I have a successful car selector which changes between cars and starts the match with that car. Everything there works. The only issue is that my "CarCameraScript" has a transform variable which is always 1 of the 3 cars. I want it to change dependant on the selected car.
Here is the look at the code of the CarCameraScript
#pragma strict
var car : Transform;
var distance: float = 6.4;
var height: float = 1.4;
var rotationDamping : float = 3.0;
var heightDamping: float = 2.0;
var zoomRatio : float = 0.5;
var DefaultFOV : float = 60;
private var rotationVector : Vector3;
function Start () {
}
function LateUpdate () {
var wantedAngel = rotationVector.y;
var wantedHeight = car.position.y + height;
var myAngel = transform.eulerAngles.y;
var myHeight = transform.position.y;
myAngel = Mathf.LerpAngle(myAngel,wantedAngel,rotationDamping*Time.deltaTime);
myHeight = Mathf.Lerp(myHeight,wantedHeight,heightDamping*Time.deltaTime);
var currentRotation = Quaternion.Euler(0,myAngel,0);
transform.position = car.position;
transform.position -= currentRotation*Vector3.forward*distance;
transform.position.y = myHeight;
transform.LookAt(car);
}
function FixedUpdate () {
var localVilocity = car.InverseTransformDirection(car.rigidbody.velocity);
if (localVilocity.z<-0.5) {
rotationVector.y = car.eulerAngles.y + 180;
} else {
rotationVector.y = car.eulerAngles.y;
}
var acc = car.rigidbody.velocity.magnitude;
camera.fieldOfView = DefaultFOV + acc*zoomRatio;
}
This is what it looks like on the side panel.
http://i.stack.imgur.com/lYJP7.jpg
The area that says none (transform) is the place that should be variable dependant on the currently selected car.
Now, Here is my other script being the CharacterSelectScript
#pragma strict
//this is the currently selected Player. Also the one that will be saved to PlayerPrefs
var selectedPlayer : int = 0;
function Update()
{
if (Input.GetMouseButtonUp (0)) {
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit, 100))
{
// The pink text is where you would put the name of the object you want to click on (has attached collider).
if(hit.collider.name == "Player1")
SelectedCharacter1(); //Sends this click down to a function called "SelectedCharacter1(). Which is where all of our stuff happens.
if(hit.collider.name == "Player2")
SelectedCharacter2();
if(hit.collider.name == "Player3")
SelectedCharacter3();
}
else
{
return;
}
}
}
function SelectedCharacter1() {
Debug.Log ("Character 1 SELECTED"); //Print out in the Unity console which character was selected.
selectedPlayer = 1;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
function SelectedCharacter2() {
Debug.Log ("Character 2 SELECTED");
selectedPlayer = 2;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
function SelectedCharacter3() {
Debug.Log ("Character 3 SELECTED");
selectedPlayer = 3;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
How would I get it so that the SelectedPlayer changes the transform in the first script?
Any ideas?
I also have the prefab script which probably isnt important.
Also, should I join both scripts into one?
OVERALL GOAL: Have the camera change target to the selected car
i'm a newbie and i'm terrible at english but hopefully you can understand my problem
i create a simple space shooting game with easeljs, when i tried to create multiple bullets and assign an onTick handle to each one, i relize just one bullet fire out. Here is the code:
//handle fire(shooting)
if(fire && cd === 0){
for(var i=0; i<5; i++){
//codartjs.Bullet is a class extend createjs.Bitmap
var b = new codartjs.Bullet(bullet_img);
b.x = 200;
b.y = 200;
stage.addChild(b);
b.onTick = function(){
//this event handler work for only first instance
b.y -= 10;
};
}
cd = 100;
setTimeout(function(){
cd = 0;
},100);
}
What you can also try is having a central ticker and loop through each bullet element and update its position that way. Here is quick demo that will illustrate my point.
<script>
var canvas, stage;
var bullets;
var speed;
function init() {
stage = new createjs.Stage("test");
bullets = [];
var bg = new createjs.Shape();
bg.graphics.beginFill("#FFFFFF").drawRect(0, 0, stage.canvas.width, stage.canvas.height).endFill();
bg.cache(0, 0, stage.canvas.width, stage.canvas.height);
speed = 15;
stage.onClick = handleClick;
stage.mouseEnabled = true;
stage.enableMouseOver(10);
createjs.Ticker.setFPS(24);
stage.addChild(bg);
createjs.Ticker.addListener(window);
}
function getSprite() {
var s = new createjs.Shape();
s.graphics.beginFill("#000000").drawCircle(0, 0, 10).endFill();
return s;
}
function tick() {
for(var i=0;i<bullets.length;i++) {
var s = bullets[i];
s.x += speed;
}
stage.update();
}
function handleClick(event) {
var s = getSprite();
s.x = event.stageX;
s.y = event.stageY;
bullets.push(s);
stage.addChild(s);
}
</script>
Hope this helps.