- Home /
Unwanted, Unpredictable Values for Transform
I am trying to instantiate a pickup prefab within a room when an enemy is killed. I have tried to set it to where the prefab is instantiated at the position of the enemy. Simple, right?...
...not exactly. I tried the easy, obvious, really-should-be-correct position for the instantiated object (transform.position), but that nearly always had the item instantiate out of the room. (Just to let you know, the object which instantiates the prefab is within the room, is a child of the enemy, and is exactly where I want). Then I thought that I would try to use Mathf.Clamp() to limit where the prefab would instantiate. That worked partly, with the x and z values within proper range, but the y values were still off (it either wasn't in the room or out of reach about two-thirds of the time). I thought that I would let the x and z values be, and set the y value to a constant float. This is functional; the prefab doesn't usually instantiate with the proper y value, but is within reach two-thirds of the time, with the other one-third being under the room.
Does anyone have an idea of how to fix this perplexing problem? The code that I am using to instantiate the prefab (which is of a key, btw) is shown below.
private var key : GameObject;
var xMax : float;
var xMin : float;
var yPosit : float;
var zMax : float;
var zMin : float;
function Start () {
key = transform.gameObject.parent.MarshmellowManDamage.key;
}
function OnDestroy () {
var obj = Instantiate(key,Vector3(Mathf.Clamp(transform.position.x,xMin,xMax),Mathf.Clamp(transform.position.y,yPosit,yPosit),Mathf.Clamp(transform.position.z,zMin,zMax)),Quaternion.identity);
obj.transform.position.y = yPosit;
}
================================================================
Edit : I have changed the scaling of the prefab and the enemy, but the enemy now either flies around the room, or just drops and the keys are still a problem.
Your right it shouldn't if you are working off the game object you created. Hmmm.
Ok so the key model is imported with an import scale of 1 ? It's not the good old 0.01 scale problem is it?
Does any other code handle this prefab? If you were to spawn some other random prefab there (or GameObject), does it still randomize? If you spawn some random prefab there and it still moves, then it may be a bug with prefabs, or you have something that's picking up the GameObject somehow (like "Find," but that shouldn't be able to find a random prefab).
@You Class names are supposed to start with a capital letter. As are properties, which don't exist in UnityScript. .ClassName doesn't magically grab an instance of that class. It could if you had parentheses after it, but that's not what you're doing. You just have a poorly-named variable. And you still spelled marshmallow wrong. It only sounds like mellow.
@You: Lots of things don't go far enough for me, so I'm used to doing the hackiest things to emulate functionality (with considerable robustness, of course). You shouldn't have to fix stuff on the prefab...I have this feeling that the problem is more concentrated than you expect.
I meant concentrated as in smaller. Sorry about that, my $$anonymous$$d's a little hazy from lack of sleep. And at least you know what the problem is. That's a huge step if you definitively know the source of the problem. Good luck with fixing it :D.
Answer by Bunny83 · Jun 14, 2012 at 11:51 PM
Maybe i've missed it somewhere in the 27+ comments, but nobody mentioned this line:
key = transform.gameObject.parent.MarshmellowManDamage.key;
That doesn't make any sense...
a GameObject doesn't have a parent, only the transform component has one.
Even if parent would exist and would return something meaningful (usually a Transform), MarshmellowManDamage wouldn't be a property / variable of transform. You have to use GetComponent if you want to access a custom script component.
If you put a #pragma strict at the top the compiler won't even compile your code.
If i run your code without pragma strict, it obviously throws a null-ref-exception at the line in Start.
So if the "MarshmellowManDamage" script is attached to the parent object, you would do something like that:
key = transform.parent.GetComponent(MarshmellowManDamage).key;
So i have a script that looks like this and works fine:
// UnityScript
private var key : GameObject;
function Start () {
key = transform.parent.GetComponent(MarshmellowManDamage).key;
}
function OnDestroy () {
Instantiate(key, transform.position, Quaternion.identity);
}
Another final note: It seems it's not a good idea to use Instantiate in OnDestroy or OnDisable and test in the editor. This will instantiate the object into the edit-scene when you exit the game. That's a really strange behaviour. It does the same in a C# script. This will leak the object into the scene which is an absolutely "NoGo". It shouldn't be possible to corrupt the edit scene from the runtime.
I still use 3.5.0f1. Maybe this is already fixed...
Just a question - doesn't GetComponent() only get a copy of the script, as written in code, without additions in the inspector/changes from in game? That is how I have come to understand it...
Also, the OnDestroy() function has been working great for this purpose, since you really need to destroy the enemies before you go to the next scene anyway. I would like to not use the OnDestroy() function, but it works well for now (enough to where I can easily keep it).
@You: I'm not sure what you mean. GetComponent doesn't create a copy, it returns a reference to a certain component if there is one on this GameObject. .transform, .camera and the other shortcut properties are just an easier way to access those buildin components. It would be the same as .GetComponent(Transform) or .GetComponent(Camera).
You might got my last sentence wrong ;) Of course it works, but (at least in my version of 3.5) it executes the OnDestroy function when you stop your game in the editor. This will instantiate the prefab into the edit-scene. So it's permanent there from now on. Unity even prints an error that an object has leaked.
As i said, that's propably already fixed. I don't had the time to update my Unity version yet ;)
Okay, I'm now using GetComponent(). I think it will work better when I get the enemy back and working again (I messed it up while trying to fix this problem).
Also, I should have mentioned that I am using an older version than you are (3.4.2f3). I'm going to upgrade to the most recent version when I finish this project (which is going to be very soon). You have nothing to feel too stressed about ;).
Edit: Yeah, I'm definitely changing the function, just because it is dropping item prefabs!
Just so that I can finish this question (and accept an answer ;) ) I'm going to overview what happened.
Use gameObject.GetComponent().variable or transform.(parent/child).GetComponent().variable to call for variables in external scripts. (This might be obvious to some.)
Check to see that objects (the prefab and the object which will instantiate the prefab) are centered to be sure that the prefab instantiates where you want it.
$$anonymous$$eep the scaling of the prefab and the object which will instantiate the prefab to 1.
Check to be sure that another script isn't changing the position of the prefab.
If necessary, check to see if the collision exists using Debug.Log() in the desired collision or trigger variable.
Use a dictionary for words before it is too late to save your code from misspellings which will frustrate those who will try to help you (yes, @Jessy, that was for you).
Your answer
Follow this Question
Related Questions
How to calculate distance between objects? 5 Answers
How to assign saved transform values(tr,rot,sc) from a List, to the same gameobject ? 1 Answer
(noob) Top down shooter player controller look at mouse script (2D) 1 Answer
Change gameObject within a Transfom 1 Answer
How to set up the values of the variables after the object is instantiated 0 Answers