Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Placing object infront of another, in forward direction

Discussion in 'Scripting' started by firkinfedup, Sep 16, 2018.

  1. firkinfedup

    firkinfedup

    Joined:
    May 6, 2017
    Posts:
    10
    Hi there,

    So I have a script that I add to a sphere in my scene, the idea is that it places a small child sphere a short distance ahead of the parent object, in its forward direction. My code appears to work but I'm pretty sure it's off by like 20 degrees or so. If my parent object is not rotated at all, it's perfect, by my parent object is rotated by 45 degrees on the Y axis, which results in child object being slightly off.

    Code (CSharp):
    1. public class DirectionMarker : MonoBehaviour
    2. {
    3.  
    4.     #region private objects
    5.  
    6.     GameObject _marker;
    7.     Vector3 _lastPosition;
    8.     Vector3 _lastForward;
    9.     float _lastDistance;
    10.  
    11.     #endregion
    12.  
    13.     #region public properties
    14.  
    15.     public float Distance = 0.9f;
    16.  
    17.     #endregion
    18.  
    19.     #region monobehaviour methods
    20.  
    21.     void Start ()
    22.     {
    23.         _marker = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    24.         SphereCollider collider = _marker.GetComponent<SphereCollider>();
    25.         collider.enabled = false;
    26.         _marker.transform.parent = transform;
    27.         _marker.transform.name = string.Format("{0}_DirectionMarker", transform.name);
    28.         _marker.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
    29.     }
    30.    
    31.     void Update ()
    32.     {
    33.         if(_lastPosition != transform.position ||
    34.             _lastForward != transform.forward ||
    35.             _lastDistance != Distance)
    36.         {
    37.             _lastForward = transform.forward;
    38.             _lastPosition = (new Vector3(0.0f, 0.0f, 0.0f) + _lastForward) * Distance;
    39.             _marker.transform.localPosition = _lastPosition;
    40.         }
    41.     }
    42.  
    43.     #endregion
    44.  
    45. }
    upload_2018-9-16_11-58-1.png

    As you can see in the pic above, the child sphere, which is the marker, should be following the blue direction arrow, but it isn't any idea what's going on here?
     
  2. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    411
    If the small sphere is a child of the red sphere, then you should not need to reposition it every frame. The parent-child relationship will take care of that.

    If the small sphere is not a child of the red sphere, but you're looking to place it in front of the red sphere each frame, then you'll need some code to do that. Your above snippet is close for this case. On line 39, don't change the marker's localPosition (_marker.transform.localPosition), instead change its world position (_marker.transform.position).
     
  3. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,395
    I thought that too, but it doesn't work. It just sets its position relative to the World origin.

    First, to correct your code you can change Update() to be this:
    Code (CSharp):
    1. void Update()
    2. {
    3.     _marker.transform.position = transform.TransformPoint(Vector3.forward * Distance);
    4. }
    However, as kru points out, you have already parented the marker sphere to the main sphere. So in fact, in this case, simply removing the Update() method entirely will do the same thing.