1
\$\begingroup\$

I have a very simple scenario:

  • A box-like Prefab which is imported from Blender automatically (I have the .blend file in the Assets folder).

  • A script that has two public GameObject fields. In one I place the above prefab, and in the other I place a terrain object (which I've created in Unity's graphical view):

    public Collider terrain;

    public GameObject aStarCellHighlightPrefab;

  • This script is attached to the camera.

The idea is to have the Blender prefab instantiated, have the terrain set as its parent, and then scale said prefab instance up.

I first did it like this, in the Start() method:

void Start () {
        cursorPositionOnTerrain = new RaycastHit();
        aStarCellHighlight = (GameObject)Instantiate(aStarCellHighlightPrefab, new Vector3(300,300,300), terrain.transform.rotation);
        aStarCellHighlight.name = "cellHighlight";
        aStarCellHighlight.transform.parent = terrain.transform;
        aStarCellHighlight.transform.localScale = new Vector3(100,100,100);
    }

and first thought it didn't work. However later I noticed that it did in fact work, in the sense where the scale was applied right at the start, but then right after the prefab instance came back to its initial scale.

Putting the scale code in the Update() methods fixes it in the sense where now it stays scaled all the time:

void Update () {
     aStarCellHighlight.transform.localScale = new Vector3(100,100,100);
     //...
}

However I've noticed that when I run this code, the object is first displayed without the scale being applied, and it takes about 5-10 seconds for the scale to happen. During this time everything works fine (like input and logging, etc). The scene is very simple, it's not like it has a lot of stuff to load or anything (there's a Ray cast from the camera on to the terrain, but that seems to happen without such delays).

My (2 part) question is:

  1. Why doesn't it take the scale transform when I do it at the beginning in the Start() method. Why do I have to keep scaling it in the Update() method?

  2. Why does it take so long for the scale to "apply/show up".

==UPDATE==

As per comments, here's a detailed description of my scene:

1 camera, 1 terrain (with a bunch of brushed in deformations), 1 directional light. I also have a .blend file in my Assets folder, which is automatically imported and I get my aStarCellHighlight prefab which is a cube with a transparency/diffuse texture:

enter image description here

to the camera I have attached to following script, to which I've then "bound" the terrain and aStarCellHighlight in the corresponding public fields:

public class RTSCamera : MonoBehaviour {

    public Collider terrain;
    public GameObject aStarCellHighlightPrefab;

    private bool isCursorOnTerrain;
    private RaycastHit cursorPositionOnTerrain;
    private GameObject aStarCellHighlight;

    void Start () {
        cursorPositionOnTerrain = new RaycastHit();
        aStarCellHighlight = (GameObject)Instantiate(aStarCellHighlightPrefab, terrain.transform.position, terrain.transform.rotation);
        aStarCellHighlight.name = "cellHighlight";
        aStarCellHighlight.transform.parent = terrain.transform;        
    }

    void Update () {
        trackCursorOnTerrain(false);
        placeCellHighLight();
    }

    private void trackCursorOnTerrain(bool debug) {
        Ray ray = this.camera.ScreenPointToRay(Input.mousePosition);

        isCursorOnTerrain = terrain.Raycast(ray,out cursorPositionOnTerrain, 5000);
        if(debug) {
            if(isCursorOnTerrain) {
                Debug.DrawLine (ray.origin, cursorPositionOnTerrain.point);
                Debug.Log("terrainRight="+cursorPositionOnTerrain.point.x+" terrainUp="+cursorPositionOnTerrain.point.z+" terrainAltitude="+cursorPositionOnTerrain.point.y);
            } else {
                Debug.DrawLine (ray.origin, ray.GetPoint(5000));
            }
        }
    }

    private void placeCellHighLight() {
        aStarCellHighlight.transform.localScale = new Vector3(50,50,200);
        if(isCursorOnTerrain) {
            aStarCellHighlight.transform.localPosition = cursorPositionOnTerrain.point + new Vector3(0,200,0);
        } else {
            aStarCellHighlight.transform.localPosition = Vector3.zero + new Vector3(0,200,0);
        }
    }
}

The script is supposed to basically draw a ray from camera's mouse cursor screen position to terrain, and then instantiate the Blender cube prefab, add is at a child of terrain, scale it to a visible size, and move it around on the terrain to where the mouse is, you know , "projecting" or whatever it is called.

when I hit play I the Blender prefab instance is created right away, it is shown as a descendat of terrain, is just not scaled properlly. Also if I move the mouse right away, the cube doesn't move with it:

enter image description here

Finally, if I just wait 10-20 seconds, the cube gets scaled, and now it moves with the cursor on the terrain:

enter image description here

Thanks for all any help!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Something's not right if it doesn't show up immediately with correct scale. Can you post the entire MonoBehavior script? \$\endgroup\$
    – Chuck D
    Nov 17, 2012 at 17:45
  • 1
    \$\begingroup\$ I'd put ten bucks on some other script being naughty. Can you throw together a test scene so we can verify? \$\endgroup\$ Nov 17, 2012 at 17:52

2 Answers 2

1
\$\begingroup\$

The object you instanciate, does it have some scripts attached to it? The instanciated object doesn't run its awake()/start() until the next chance it gets and not when you call Instanciate(). In the following code

class ObjectA{
    public ObjectB anObjectPrefab;
    void Start(){
        Instanciate(anObjectPrefab);
        FunctionA();
    }
    void FunctionA() { ... }
}

class ObjectB{
    void Start(){ ... }
}

The execution order will be:

  • ObjectA.Start()
  • ObjectA.FunctionA()
  • [Possibly other objects Starts()]
  • ObjectB.Start()

So as you can see, if you are doing some scaling in ObjectB.Start() and expect that setting the scale right after the instanciation will overwrite the values, that won't work... Of course that's just one possibility, but it did happen to me a few times so that's the first thing that jump to my mind.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the help, this is something I've never thought of and which is good to know. However, as you can see from my update, I only have one single script. I do the instantiation in Start() (and that happends ok). Then, if I also do the scaling (only) in Start() i basically don't see any scaling (or any transform i might put in Start()). If I do scaling and other transform in Update() it works, but not before 10-20 seconds when no transform is happening (even though the scene runs and other code in Update (like Ray debug, debug console output) works ok in that time. \$\endgroup\$ Nov 17, 2012 at 18:32
1
\$\begingroup\$

Well, I've solved it. I'm not very sure what was happening, but due to the fact that I've created and erased an then re-created the terrain multiple times in the scene (each time adding it to some scripts, etc), at some point something got jumbled up in Unity, probably because of this. Long story short, I created a new Unity project, copied in all my scripts and re created all the game elements and re-attached them to the scripts, and now everything works ok: I only need to scale the Blender object in the Start() method (and it stays scaled), and also it is transformed and shows up right from the start when I play the game.

Thanks you to everyone for the help, the hints they gave pointed me in the right direction.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .