Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by TedB · Nov 25, 2009 at 04:20 AM · animationrotation

Rolling cubes one space and one rotation at a time, with a delay

I am about a week in to Unity but reading through all the tutorials, guides and documentation I can as quickly as I can.

I have what I'm sure is a simple scenario but I'm having trouble determing the method to tackle it in Unity.

What I want to do is have a row of cubes roll 90 degrees and one position downward followed by a delay of 2 seconds (an arbitrary number of seconds), and then repeat. Put another way, I want the cube to roll over on its side in the direction it is rolling.

From what I've gathered so far, I thought one way would be to transform the cube at set intervals:

private var cubeTimer : float = 0.0; private var currentCube : GameObject;

private var cubeTime : float = 2.0; private var cubeSpeed : float = 50.0;

function Update () { cubeTimer += Time.deltaTime; spinAmount = Time.deltaTime * cubeSpeed;

 if (cubeTimer > cubeTime){
     transform.position.x = transform.position.x +1;
     cubeTimer = 0.0;
 }
 transform.Rotate(0, 0, -spinAmount);

}

That's rotating it, but that rotation doesn't match up with the movement in the x-axis properly, so it looks awful. How could I sync the roll to exactly match up with the x-asix movement?

Should I be doing this as a RigidBody and AddMotion instead? I tried that, but the roll didn't seem predictable depending on where the block was on the plane.

There are animation curves I know, but I wonder how I would sync the rotation and movement on the x-axis.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by Jaap Kreijkamp · Nov 25, 2009 at 04:36 AM

A simple solution is to do the rotation as an animation where at the end of the animation the cube has moved the +1 distance.

Alternatively use Transform.rotateArount to rotate around a point on the edge of the cube you're currently rolling over.

If not clear what I mean, let me know, can make an example or so.

EDIT: too much fun to pass, here sample code in C# (sorry not too fond of javascript but shouldn't be too hard to convert if you need), Just create new C# class called RollCube and copy/paste code below over it.

EDIT2: now have rotation done from Coroutine so we can delay after rolling to a side.

using UnityEngine; using System.Collections;

public class RollCube : MonoBehaviour {

 public float cubeSize = 1f; 
 public float cubeSpeed = 50f;
 public float delay = 2f;

 private float totalRotation = 0f; // determines if we're past the 90 degrees
 private float startHeight = 0f; // for correcting height errors

 // next two vars are for determining the corner
 // to rotate over
 private float fwdWeight = 0.5f;
 private float upWeight = -0.5f; 


 // Use this for initialization
 void Start () {
     startHeight = transform.position.y;
     StartCoroutine(CORollCube());
 }

 IEnumerator CORollCube() {
     while (true) {            
         // we calc the spinamount but make sure it won't shoot over the 90 degrees
         float spinAmount = Mathf.Min(Time.deltaTime * cubeSpeed, 90f - totalRotation);

         // we rotate around one of the edges of the cube (the stationary one of course)
         transform.RotateAround(transform.position + (fwdWeight * transform.forward + upWeight * transform.up) * cubeSize, Vector3.right, spinAmount);

         // add to amount of spin in this update the total rotation
         totalRotation += spinAmount;

         // check if we have to move to the next edge
         if (totalRotation >= 90f) {
             // we move to next corner as pivot point
             totalRotation -= 90f;
             float t = fwdWeight;
             fwdWeight = -upWeight;
             upWeight = t;

             // make sure height stays correct
             Vector3 pos = transform.position;
             pos.y = startHeight;
             transform.position = pos;

             // wait for delay amount of seconds
             yield return new WaitForSeconds(delay);
         }
         else {
             // ready for this frame
             yield return 0;
         }
     }
 }

}

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TedB · Nov 28, 2009 at 04:41 AM 0
Share

Thanks for the quick answer and code for rotating and moving the cube forward at the same time. Looks great!

I'm having trouble applying it though with a delay after the move. I figured I could pause it after a 90 rotation with a yield WaitForSeconds(2) but that doesn't stop it at all. $$anonymous$$y goal is to be able to start and stop the cube advancing one position at a time if a player does something, otherwise, keep moving, with a pause between moves. Am I on the right track? Any idea what's up with yield not yielding?

avatar image TedB · Nov 30, 2009 at 02:51 AM 0
Share

That update with the coroutine works great. I was trying to do the coroutine in JavaScript but evidently not correctly. I'll leave it as C# for now.

avatar image ArunChnadran · Jan 25, 2012 at 07:58 AM 0
Share

That came handy to me! Was not trying out for any of these things but obviously there was a rotation and shifting of pivot points! Thanx!!!

avatar image
1

Answer by TedB · Nov 28, 2009 at 04:48 AM

// Reposting this non-working answer because it was unreadable when posted as a comment to the previous answer

var cubeSize : float = 1; var cubeSpeed : float = 80;

private var totalRotation : float = 0; // determines if we're past the 90 degrees private var startHeight : float = 0; // for correcting height errors

// next two vars are for determining the corner // to rotate over private var fwdWeight : float = 0.5; private var upWeight : float = -0.5;

// Use this for initialization function Start () { startHeight = transform.position.y; }

// Update is called once per frame function Update () {

 DoRoll(2);

}

function DoRoll (delay: float) { var spinAmount : float = Time.deltaTime * cubeSpeed; var t : float; var pos : Vector3;

 // we rotate around one of the edges of the cube (the stationary one of course)
 transform.RotateAround(transform.position + (fwdWeight * transform.forward + upWeight * transform.up) * cubeSize, Vector3.right, spinAmount);

 // add to amount of spin in this update the total rotation
 totalRotation += spinAmount;

 // check if we have to move to the next edge
 if (totalRotation >= 90) {
         // we move to next corner as pivot point
         totalRotation -= 90;
         t = fwdWeight;
         fwdWeight = -upWeight;
         upWeight = t;

         // make sure height stays correct
         pos = transform.position;
         pos.y = startHeight;
         transform.position = pos;
         print ("At rotation " + totalRotation);
         yield WaitForSeconds(delay);

 }

}

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ArunChnadran · Jan 25, 2012 at 08:49 AM 0
Share

thanx for the conversion too!!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

2 People are following this question.

avatar image avatar image

Related Questions

Animating (simple rotation) armature by script 1 Answer

Problem with animation: they always start at the same rotation!! 1 Answer

Animate a cube rotation with script only 3 Answers

Using Quaternions and C# script to animate a mesh 1 Answer

The name 'Joystick' does not denote a valid type ('not found') 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges