Search Unity

Animated Bill board does not appear when timeline animated

Discussion in 'Timeline' started by tre4bax, Feb 6, 2018.

  1. tre4bax

    tre4bax

    Joined:
    Aug 31, 2013
    Posts:
    22
    Hi there.

    I've built a prefab that is essentially a rotated vertical plane as a child of an Empty game object. The plane is orientated towards the player using

    transform.LookAt(player.transform);

    in the script attached to the gameobject.

    When I walk around the object it stays facing me all seems fine. I then decided to play with it on a timeline. When I do this however it disappears as soon as the timeline starts.

    I am assuming that something is happening to the rotation that makes it visible. If the object is not facing me I would not see it due to backface culling however it appears to be never facing me as I've tried looking at it from both sides. I'm assuming that the animation is causing this. I'm just not sure why as I am only animating the position of the game object and not the plane. That said the rotation that makes the plane visible is on the gameObject (solely because I have not yet figured out how to apply LookAt to the child object).

    Can anybody point me to the huge obvious thing I am clearly missing here?

    Trev
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Possibly related to timeline root motion, which modified position & rotation. You can try parenting your game object, and animating the parent in timeline instead.
     
  3. tre4bax

    tre4bax

    Joined:
    Aug 31, 2013
    Posts:
    22
    My object is parented to the game object and I have now modified the code so the Plane (child of the gameobject) rotates while the game object does not. Even so as soon as I run the animation my object disappears.

    Essentially even though I am only controlling the position the animation still stops any rotation from happening. To prove this I add a Cube into the prefab. I scaled the cube so that it was Tall and thin and then I set the billboard tracking to be on the game object again i.e. the whole game object turns to face me. With no animation The plane and the additional cube stay rotated to face me. If I animate the plane disappears and I get just the cube going backwards and forwards. I can walk right around it as the cube does not rotate to face me. Clearly animation through a timeline constrains the rotation :-(

    Anyway around this or do I need to write something for myself?
     
  4. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Can you post a simple repro project? I believe the setup you have should work.
     
  5. tre4bax

    tre4bax

    Joined:
    Aug 31, 2013
    Posts:
    22
    Okay this is the code. The setup is that Actor-Image is a plane with an empty game object called Actor as the parent to that plane in a prefab. The empty is the one with the script below attached to it.

    This loads an image from the hard drive at runtime and scales it so that the image is the correct height etc. The rotation in start is necessary to get the plane the right way up when using the look at against the plane. Previously the lookat was just based on transform. Neither works with the animation.

    I've not got to anything complicated yet.

    using System.Collections;
    using System.Collections.Generic;
    using System.Xml.Linq;
    using System.IO;
    using System.Drawing;
    using UnityEngine;




    public class actorScript : MonoBehaviour {

    private const float UnityPlaneFactor = 10f; //Planes are 10x bigger than cubes!
    private static int actorCount = 1;


    private Transform image = null;

    [SerializeField] string fileImageToLoad = "C:\\UVMAP.jpg";
    [SerializeField] float actorHeight = 1.7f;
    private PlayerMovement player;

    // Use this for initialization
    void Start ()
    {
    image=transform.Find("Actor-Image"); //find the image component where the picture will be painted
    image.localRotation= Quaternion.Euler(new Vector3(90, 0, 0));
    name = $"Actor_{actorCount++}";
    player = GameObject.FindObjectOfType<PlayerMovement>(); //get a link to the player object so I can track him
    AssignPlayer();
    }

    private void AssignPlayer()
    {
    Load(fileImageToLoad);
    }

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

    image.LookAt(player.transform); //Always look directly at the player
    }

    ///// <summary>
    ///// Load the specified FileImageToLoad. This is called as part of create but could be used to change the file image if required hence why available as a seperate
    ///// command.
    ///// </summary>
    ///// <param name="FileImageToLoad">File image to load.</param>
    public void Load(string fileImageToLoad) //, float WidthToHeightRatio = 1.0f)
    {
    try
    {


    //First get the texture in and calculate its Height to width ratio
    Image textureImage = Image.FromFile(fileImageToLoad);
    float widthToHeightRatio = ((float)textureImage.Width) / ((float)textureImage.Height);

    //create the texture and set the scale so that the height is the required height
    //and the width is whatever width is necessary to stay proportional to the height
    Texture2D NewTexture = new Texture2D(textureImage.Width, textureImage.Height);
    NewTexture.LoadImage(File.ReadAllBytes(fileImageToLoad));
    image.GetComponent<Renderer>().material.mainTexture = NewTexture;
    image.localScale = new Vector3(actorHeight * widthToHeightRatio/ UnityPlaneFactor, .1f, actorHeight/ UnityPlaneFactor); //this sets the object to the right proportions
    image.localPosition = new Vector3(image.localPosition.x, image.localScale.z / 2 * UnityPlaneFactor, image.localPosition.z ); //sets the plane at the right point above the base for this item.

    }
    catch { Debug.Log("Failed to load texture " + fileImageToLoad); }
    }
    }
     
  6. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Simple thing to try, change Update to LateUpdate. That will make the rotation update occur after timeline, as timeline updates animation in between Update() and LateUpdate().
     
  7. tre4bax

    tre4bax

    Joined:
    Aug 31, 2013
    Posts:
    22
    LateUpdate worked :)

    However I went in the end with a slight adaption of the above that rotated the Plane on top of the game object instead, so essentially your first suggestion. Knowing about LateUpdate is really useful so I learnt something. Thank you very much for your help.
     
    seant_unity likes this.