Unity 3D Spinning a gameobject - animation

I am trying to spin a 3D Gameobject in unity. It is actually a cylinder with just a texture of a poker chip on it. I want to spin it 360 degrees once it has collided with a raycast. It is working just fine in the Unity emulator, however, on the device itself the chip comes to a stop after its spin and then continues to spin in an endless loop. Here is a snippet of the code in question. Thank you for any help in advance.
// Spin the chip
if (Animate) {
if (Speed > 0 && Chip.tag.Contains("Chip")) {
Chip.transform.Rotate(0, Speed*Time.deltaTime, 0);
Speed -= 3;
Debug.Log(Speed);
}
else {
// Reset
Animate = false;
Speed = 360;
Chip.transform.localRotation = Quaternion.Euler(0.0,0.0,0.0);
}
}
To summorize this the best I can the gameobject Chip is assigned when it collides on raycast as such
// Set the chip
Chip = hit.transform;
Everything is done in the update function. Once the raycast hits it calls a betting function then after the betting is calculated it changes the Boolean Animate to true causing the spinning of the chip.

Something is setting Animate = true in some other code, hard to tell whats going on without seeing the rest of it.
Put some debug next to every spot where Animate is set to true, you should see something else setting it, only possible explanation as to why it continues to spin.
Another option is to use the Animation tool and instead of rotating, you just play the animation which performs the rotation for you.
Edit: Chances are its around the touch code, cause when you debug in the editor your using key strokes. A gotcha I've experienced a few times.

James Gramosli is correct in that some other code is triggering the animation again and it is most likely your touch code. It is a common problem when moving between editor and a touch-enabled device. You can determine if this is the case by using the UnityRemote to verify the control flow of your code.
That said, I would change your code to the following which removes the spin code from the Update loop that runs every frame. It is a small optimization, but primarily it cleans up the architecture and makes it more modular and a little neater.
It is not clear from your code snippet, but I will assume you are using UnityScript.
In your script that handles the touch code when you click on the chip, insert this line:
hit.transform.SendMessage("Spin", hit.transform, SendMessageOptions.DontRequireReceiver);
Put this code in a separate script called "SpinChip" and then add the script to your chip object.
var StartSpeed = 360.0;
var Deceleration = 3.0;
function Spin()
{
if (Animating)
{
print("Chip is already spinning, not starting another animation");
return;
}
/*
This code isn't necessary if this exists in a separate script and is only ever attached to the clickable chip
if (!gameObject.tag.Contains("Chip"))
{
print("That wasn't a chip you clicked");
return;
}
*/
print("Chip has been told to spin");
StartCoroutine(SpinningAnimation);
}
function SpinningAnimation()
{
print("Chip spin start");
transform.localRotation = Quaternion.identity;
Speed = StartSpeed;
Animating = true;
while (Speed > 0)
{
transform.Rotate(0, Speed*Time.deltaTime, 0);
Speed -= Deceleration;
yield; // wait one frame
}
print("Chip has completed the spin");
Animating = false;
}
What this code does is create a co-routine that runs once per update loop when activated that will spin the chip for you, and is independent of your actual button clicking code.

var rotSpeed: float = 60; // degrees per second
function Update(){
transform.Rotate(0, rotSpeed * Time.deltaTime, 0, Space.World);
}
Here is a code that rotates your game object, you can use it just with a vector 3 :transform.Rotate(x, y, z); or with Space transform.Rotate(x, y, z, Space.World);
rotSpeed is the rotation speed.

In your update function . The Bool variable Animate may becoming true . This may be reason your cylinder continues to rotate.
Other Solution is : You can create an animation of your cylinder and then take a stopwatch . So that after sometime you can stop you animation using the time of stopwatch

Related

Slowly move a circle in PIXIJS

I have a circle with PIXI and I need that when the touch is fulfilled another object said circle returns to its original position, but it happens that I do not know any function or method for the movement to be appreciable, all I have achieved is that it disappear and appear in its initial position. How did the transition happen?
Just add the movement into rendering loop
I use PIXI.tickerTicker() for loop
let ticker = new PIXI.ticker.Ticker();
the rendering loop in your situation should be
function loop(){
renderer.render(stageContainer);
yourCircle.position.x += moveSpeed; //your question
if(resetCirclePosition)
yourCircle.position.x = defaultPos;
}
and then to start ticker use
ticker.add(loop);
ticker.start();
Look at ticker documentation http://pixijs.download/dev/docs/PIXI.ticker.Ticker.html

Unity3D: How to "chain" animations without resetting?

I imported a cube mesh that contains four smaller sub-cubes.
The mesh also contains an animation that pushes the smaller cubes out of the big one. When this is done, one of the small cubes "splits" again (it's not really splitting - it just pushes four children out again).
I'd like to trigger these animations when the user clicks on the big cube.The animation was initially exported as one clip but I cut it in half so that I can either trigger the first or the second split.
I attached a Box Collider to the big cube to be able to get an OnMouseDown event and from there I pass an int parameter to my AnimationController that starts the appropriate animation:
public class ClickToAnimate : MonoBehaviour {
private Animator _animator;
private int _clicks = 1;
void Start()
{
_animator = GetComponent<Animator>();
}
void OnMouseDown()
{
_animator.SetInteger("Clicks", _clicks);
if (_clicks == 3)
{
_clicks = 1;
}
else
{
_clicks++;
}
}
}
The state switching works fine but when I transition from FirstSplit to SecondSplit, the first animation is reverted so that the four medium cubes are driven back in the big cube before the second animation is played.
I tried enabling "Apply Root Motion" but that doesn't help (probably because the big cube is never actually moving?). So how can I "chain" these animations without resetting them in each step? Are my general ideas regarding the AnimationController and animation splitting correct to handle this and what am I missing?

How do i rotate an object in unity at a set of amount time stop it and then again

I'm not good at coding so please help me with my problem.
What i mean with: How do i rotate an object in unity at a set of amount time stop it and then again
is how can i rotate an object at a set of amount time then stop it at a set of amount time then stop it etc.
VideoNations
Easiest way would be like this:
// control the timing of rotating here
var rotate=true;
function Start () {
// rotate an object for 2 seconds
rotate=true;
yield WaitForSeconds(2f);
// stop it for a second
rotate=false;
yield WaitForSeconds(1f);
// rotate again
rotate=true;
}
// rotate here
function Update() {
if(rotate)
transform.eulerAngles+=Vector3(0, Time.deltaTime*90, 0);
}
If you want the rotation enabling-disabling to loop, wrap the contents of Start in a while(true) {...}.

Torque in Bullet

I'm working on a game which involves spaceships. We're using OGRE and Bullet.
The player's ship is supposed to pitch and yaw with the mouse -- moving the mouse left will yaw the ship left, for example. The problem is, I can't figure out how to apply torque in Bullet.
Before we started integrating Bullet, our solution was to directly modify the OGRE scene node like so (using OIS for input):
bool Game::mouseMoved(const OIS::MouseEvent &event) {
shipNode->yaw(Ogre::Degree(-event.state.X.rel));
shipNode->pitch(Ogre::Degree(event.state.Y.rel));
return true;
}
And that worked fine.
Now that we're using Bullet, my plan was to apply torque to the rigid body, like so:
bool Game::mouseMoved(const OIS::MouseEvent &event) {
//shipNode->yaw(Ogre::Degree(-event.state.X.rel));
//shipNode->pitch(Ogre::Degree(event.state.Y.rel));
shipRigidBody->applyTorqueImpulse(btVector3(-event.state.X.rel, event.state.Y.rel, 0));
return true;
}
Then, after stepping the simulation, update the scene node's orientation, like so:
void Game::update(const Ogre::FrameEvent &event) {
// ... snip ...
physicsWorld->stepSimulation(event.timeSinceLastFrame, 10);
btTransform shipTransform;
shipMotionState->getWorldTransform(shipTransform);
shipNode->setPosition(shipTransform.getOrigin().x(), /* ... snip ... */);
shipNode->setOrientation(shipTransform.getRotation().getAngle(), shipTransform.getRotation().getAxis().x(), /* ... snip ... */);
}
But with this setup, I can't orient the ship at all.
Next, I tried just applying a torque impulse of (100, 10, 200) every frame no matter what, then printing out shipTransform.getRotation().getAngle()). Always 0. At this point, I became extremely confused, since you'd think that always applying torque would make the body's orientation change.
So, my question is: Am I missing something stupid about btRigidBody::applyTorqueImpulse()? Or am I barking up the wrong tree entirely?
PS: shipRigidBody is constructed like this:
shipMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 100, 0)));
shipShape = new btBoxShape(btVector3(50, 20, 75));
shipShape->calculateLocalInertia(btScalar(1), btVector3(0, 0, 0));
shipRigidBody = new btRigidBody(btRigidBody::btRigidBodyConstructionInfo(1, shipMotionState, shipShape));
I also have code which accelerates the ship forwards or backwards based on keyboard input, and that code (which uses btRigidBody::applyCentralImpulse()) is working fine.

Example on how to control tweens using Ticker in CreateJS

I'm working with CreateJS and wondered if anyone here has examples of controlling tweens using the Ticker object. I'm trying to get a sprite to follow a path defined by waypoints but i don't want to control each tween (in between waypoints) by time. I want to have smooth movement between each waypoint controlled by the Ticker object. I tried this code which doesn't seem to work at all.
var index = 0;
function move(){
index++;
if (index < path.length) {
createjs.Tween.get(person)
.to({x:gridSize * path[index][0] - pathOffset,y:gridSize * path[index][1] - pathOffset})
.call(move);
}
}
move();
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", function(event){
createjs.Tween.tick(1);
stage.update();
});
This code seems to only jump between waypoints and not tween at all. Any ideas what i may be doing wrong or any code/tutorials which might help?
You need to add a duration(in milliseconds) to your tween, otherwise it would default to 0, this will cause the "jump", e.g.: 500 for half a second
instead of: .to({x:..., y:...})
use: .to({x:..., y:...},500)
And a second thing: You don't NEED to call createjs.Tween.tick(1); this is usually called automatically by the Tween-class.
Here is some help and some small examples: http://www.createjs.com/Docs/TweenJS/classes/Tween.html
Advanced Examples:
https://github.com/CreateJS/TweenJS/tree/master/examples

Resources