Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Loss off accuracy in script

Discussion in 'Scripting' started by Bazoozoo, Jan 8, 2016.

  1. Bazoozoo

    Bazoozoo

    Joined:
    Mar 27, 2015
    Posts:
    28
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class RollCube : MonoBehaviour {
    5.  
    6.     public float playerPosOriginalZ;
    7.     public Transform parent;
    8.     private Vector3[] dirs = {Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back};
    9.     public int speed= 1000;
    10.     bool isRunning = false;
    11.    
    12.     void  Start (){
    13.         parent = new GameObject().transform;
    14.         speed = 1000;
    15.         playerPosOriginalZ = transform.position.z;
    16.     }
    17.    
    18.     void  Update (){
    19.         if (Input.GetKeyDown(KeyCode.LeftArrow) && !isRunning) {
    20.             StartCoroutine (FlopTheBlock(Vector3.left));          
    21.         }
    22.         else if (Input.GetKeyDown(KeyCode.RightArrow) && !isRunning) {
    23.             StartCoroutine (FlopTheBlock(Vector3.right));
    24.         }
    25.         else if (Input.GetKeyDown(KeyCode.UpArrow) && !isRunning) {
    26.             StartCoroutine (FlopTheBlock(Vector3.forward));  
    27.         }
    28.         else if (Input.GetKeyDown(KeyCode.DownArrow) && !isRunning) {
    29.             StartCoroutine (FlopTheBlock(Vector3.back));
    30.         }
    31.     }
    32.    
    33.     public IEnumerator FlopTheBlock (Vector3 direction){
    34.         isRunning = true;
    35.         Vector3 down = WhatsDown();
    36.         Vector3 dir = transform.InverseTransformDirection(direction);
    37.        
    38.         Vector3 pos = dir * 0.5f + down * 0.5f;
    39.         pos = transform.TransformPoint(pos);
    40.        
    41.         Vector3 axis= Vector3.Cross(Vector3.down, direction);
    42.        
    43.         transform.parent = null;
    44.         parent.rotation = Quaternion.identity;
    45.         parent.position = pos;
    46.         transform.parent = parent;
    47.        
    48.         Quaternion qTo= Quaternion.AngleAxis(-90, axis);
    49.        
    50.         while (parent.rotation != qTo) {
    51.             parent.rotation = Quaternion.RotateTowards(parent.rotation, qTo, speed * Time.deltaTime);
    52.             yield return 0;
    53.         }
    54.         isRunning = false;
    55.     }
    56.    
    57.     Vector3 WhatsDown (){
    58.         for (int i= 0; i < dirs.Length; i++) {
    59.             if (Vector3.Dot(transform.TransformDirection(dirs[i]), Vector3.down) > 0.9)
    60.                 return dirs[i];
    61.         }
    62.         return Vector3.zero;
    63.     }
    64.     void  OnTriggerEnter ( Collider other  ){
    65.         if(other.gameObject.layer == 8){
    66.             Time.timeScale = 0f;
    67.         }
    68.     }
    69. }
    The parent object transform loses accuracy over time when floptheblock method is called multiple times.
    Is there a way to have absolute integer movements?
     
  2. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    What precisely do you mean when you say "loses accuracy" and "integer movement"?

    Also, some context on what the script is supposed to be doing would be helpful.
     
  3. Bazoozoo

    Bazoozoo

    Joined:
    Mar 27, 2015
    Posts:
    28
    I'm trying to make a game with the same functionality as bloxorz. http://www.coolmath-games.com/0-bloxorz
    The script is supposed to flop a block on its sides like in the game however instead of the transform moving at constant distances it gradually gets out of sync.
     
  4. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    A naive solution could be to check the rotation when it's done, and fix it to the closest right angle.
     
  5. Mich_9

    Mich_9

    Joined:
    Oct 22, 2014
    Posts:
    118
    Use Quaternion.Lerp to get a more accurate rotation
    Code (CSharp):
    1. public IEnumerator FlopTheBlock(Vector3 direction)
    2.     {
    3.         isRunning = true;
    4.         Vector3 down = WhatsDown();
    5.         Vector3 dir = transform.InverseTransformDirection(direction);
    6.  
    7.         Vector3 pos = dir * 0.5f + down * 0.5f;
    8.         pos = transform.TransformPoint(pos);
    9.  
    10.         Vector3 axis = Vector3.Cross(Vector3.down, direction);
    11.  
    12.         transform.parent = null;
    13.         parent.rotation = Quaternion.identity;
    14.         parent.position = pos;
    15.         transform.parent = parent;
    16.  
    17.         Quaternion qFrom = parent.rotation;
    18.         Quaternion qTo = Quaternion.AngleAxis(-90, axis);
    19.         float starttime = Time.time;
    20.         float time = 0;
    21.  
    22.         while (parent.rotation != qTo)
    23.         {
    24.             time = Time.time - starttime;
    25.             //parent.rotation = Quaternion.RotateTowards(parent.rotation, qTo, speed * Time.deltaTime);
    26.             parent.rotation = Quaternion.Lerp(qFrom, qTo, time * speed);
    27.             yield return 0;
    28.         }
    29.         isRunning = false;
    30.     }
    You also have to lower the speed to 10 or an approximated value.
     
    Bazoozoo likes this.
  6. Bazoozoo

    Bazoozoo

    Joined:
    Mar 27, 2015
    Posts:
    28
    I'm still getting gradual loss of accuracy with this method. Any ideas?
     
  7. Mich_9

    Mich_9

    Joined:
    Oct 22, 2014
    Posts:
    118
    You said that you game have the same functionality as bloxorz, then I think the best method is to use some kind of TileSystem to position the cube exactly where you want it.
     
  8. Mich_9

    Mich_9

    Joined:
    Oct 22, 2014
    Posts:
    118
    If you don't want to implement all this yourself you can use this asset to speed up things.