Search Unity

Resolved Move object inside another rotating object

Discussion in 'Scripting' started by Monkey_M, Nov 25, 2020.

  1. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    Hi guys,

    I would like to move an object within a rotating object. I would like the child object in its movement to consider the rotation of the father.



    As you can see in the video the red cube goes back and forth but in the same point, I would like it to rotate (remaining between the two white cubes as at the beginning)

    To move the red cube I created this script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DinDong : MonoBehaviour
    6. {
    7.     public Transform dad; //yellow sphare
    8.  
    9.     private bool modeOut = true;
    10.     private float currentLerpTime = 0f;
    11.     private float targetTime = 1f;
    12.     private float distance = 3f;
    13.     private Vector3 startValue, endValue;
    14.     private Vector3 value1, value2;
    15.  
    16.     private void Start()
    17.     {
    18.         value1 = startValue;
    19.         value2 = (transform.position + (transform.position - dad.position).normalized * distance);
    20.         ChangeValues();
    21.     }
    22.  
    23.     private void ChangeValues()
    24.     {
    25.         if (modeOut)
    26.         {
    27.             startValue = value1;
    28.             endValue = value2;
    29.         }else
    30.         {
    31.             startValue = value2;
    32.             endValue = value1;
    33.         }
    34.     }
    35.  
    36.     // Update is called once per frame
    37.     void Update()
    38.     {
    39.  
    40.         //increment timer once per frame
    41.         currentLerpTime += Time.deltaTime;
    42.         if (currentLerpTime > targetTime)
    43.         {
    44.             currentLerpTime = targetTime;
    45.         }
    46.  
    47.         //lerp!
    48.         float perc = currentLerpTime / targetTime;
    49.         transform.position = Vector3.Lerp(startValue, endValue, perc);
    50.  
    51.  
    52.         if (currentLerpTime == targetTime)
    53.         {
    54.             transform.position = endValue;
    55.             //rest time
    56.             currentLerpTime = 0f;
    57.  
    58.             modeOut = !modeOut;
    59.             ChangeValues();
    60.         }
    61.  
    62.  
    63.     }
    64.  
    65. }
    66.  
    Any ideas to solve it?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Looks like you are capturing the positions in Start(), which only runs once. Is that your problem?

    NOTE: Vector3 is a struct (value type) which means when you go:

    Code (csharp):
    1. foo = transform.position;
    You made a copy that will never again change "just because" transform.position changes.
     
  3. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    Hello Kurt-Dekker thanks,

    You're right, but even if you recalculate it it won't change. I have to insert a change that takes into account the rotation of the father but I don't know how to do it
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    First naive attempt: call Start() from within Update(), see if that does it.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Also just noticed your line 52 compares floating point values for equality. Don't do that. I'll leave you to google the why, but basically use something like Mathf.Approximately() or do your own difference calculations.
     
    Havyx likes this.
  6. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    Thanks, I fixed the check on the floats but I had already contained the problem with the previous check.

    As for the rotation of the red cube, if I call start each update disappears as it goes away. I'm sure I need to do something with the rotation but I can't do it.
     
  7. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    Anyone have any ideas? I'm on a blocked road
     
  8. DPunK

    DPunK

    Joined:
    May 15, 2019
    Posts:
    25
    One things that comes to mind is to have a child empty game object inside the roating object. This empty object will rotate by default with it's parent and can serve as a reference point from which the object starts it's journey. You can have another similar object to reference the end position or you can calculate it like you did by adding the direction (empty object - parent)

    Another thing is, I think you can take the direction from parent to the target position and multiply it by the rotation of the parent to get a rotated end pos
     
  9. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    Hi DPunK thank you,

    I had thought of a solution similar to 1 but I have to do it with about 300 objects and it seemed too expensive...

    Could you explain better solution 2 instead please?
     
  10. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    Ok guys actually it was enough to use local coordinates and everything works fine.
    I ditched the problem for a while and when I got back I thought how stupid it was. If someone needed:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DinDong : MonoBehaviour
    6. {
    7.     public Transform dad; //yellow sphare
    8.  
    9.     private bool modeOut = true;
    10.     private float currentLerpTime = 0f;
    11.     private float targetTime = 1f;
    12.     private float distance = 0.5f;
    13.     private Vector3 startValue, endValue;
    14.     private Vector3 value1, value2;
    15.  
    16.  
    17.     private void Start()
    18.     {
    19.         value1 = transform.localPosition;
    20.         value2 = (transform.localPosition + (transform.localPosition - Vector3.zero).normalized * distance);
    21.  
    22.         ChangeValues();
    23.     }
    24.  
    25.     private void ChangeValues()
    26.     {
    27.         if (modeOut)
    28.         {
    29.             startValue = value1;
    30.             endValue = value2;
    31.         }
    32.         else
    33.         {
    34.             startValue = value2;
    35.             endValue = value1;
    36.         }
    37.         transform.position = startValue;
    38.     }
    39.  
    40.     // Update is called once per frame
    41.     void Update()
    42.     {
    43.         //increment timer once per frame
    44.         currentLerpTime += Time.deltaTime;
    45.         if (currentLerpTime > targetTime)
    46.         {
    47.             currentLerpTime = targetTime;
    48.         }
    49.  
    50.         float perc = currentLerpTime / targetTime;
    51.         transform.localPosition = Vector3.Lerp(startValue, endValue, perc);
    52.  
    53.  
    54.         if ( Mathf.Approximately(currentLerpTime, targetTime) )
    55.         {
    56.             transform.position = endValue;
    57.  
    58.             //rest time
    59.             currentLerpTime = 0f;
    60.  
    61.             modeOut = !modeOut;
    62.             ChangeValues();
    63.         }
    64.  
    65.  
    66.     }
    67.  
    68. }