I have a level in which I have placed many instances of a prefab Gameobject (targets). I need to use the coordinates of those targets in a script. Is there a way to obtain the xyz vector coordinates of all those objects and export them to a text file? Right now I need to manually copy-past each individual target from the Unity inspector to MonoDevelop, which is a PITA...
To get the coordinates of an object use item.transform.Position where item is a reference to the object you want to get coordinates for. The result is a Vector3 from which you can do .x, .y or .z to get individual coordinates/
Writing to a text file is well-documented.
Alternatively, you may want to look into Serialization
EDIT: To do this for all objects in the scene:
string filePath = "D:/mycoords.txt";
string coordinates = "";
var objects = GameObject.FindObjectsOfType(Transform) as Transform[];
foreach(Transform trans in objects)
{
coordinates+= "x: " + trans.position.x.ToString() + ", y: " + trans.position.y.ToString() + ", z: " + trans.position.z.ToString() + System.Environment.NewLine;
}
//Write the coords to a file
System.IO.File.WriteAllText(filePath,coordinates);
NOTE: FindObjectsOfType will not return any assets (meshes, textures, prefabs, ...) or inactive objects.
EDIT3: If you want to only get your Targets, add a script to you Target prefab called "SaveMeToFile" and use this code:
string filePath = "D:/mycoords.txt";
string coordinates = "";
var objects = GameObject.FindObjectsOfType(SaveMeToFile) as SaveMeToFile[];
foreach(SaveMeToFile smtf in objects)
{
Transform trans = smtf.transform;
coordinates+= "x: " + trans.position.x.ToString() + ", y: " + trans.position.y.ToString() + ", z: " + trans.position.z.ToString() + System.Environment.NewLine;
}
//Write the coords to a file
System.IO.File.WriteAllText(filePath,coordinates);
EDIT 4: Or if you have any component specific to your target you can use that instead of SaveMeToFile in the code above, saving you from having to create a new, worthless Monobehaviour
Related
I am developing an inventory system for my game. I have the UI set up, I have this:
As you can see, I have a Bag Panel, inside it there are a number of slots, that are the slots you can see in the right part of the image.
I am populating it this way:
inventoryPanel.SetActive(true);
GameObject bagObject= GameObject.Find("Bag");
List<GameObject> childrens = new List<GameObject>();
Transform[] listSlots = bagObject.GetComponentsInChildren<Transform>();
foreach(Transform child in listSlots)
{
if(!child.gameObject.name.Equals(bagObject.name))
childrens.Add(child.gameObject);
}
for (int i = 0; i < character.ItemsInInventory.Count; i++)
{
if (character.ItemsInInventory[i] != -1)
{
GameObject slot = childrens[i];
print("Slot: " + slot.name);
Image imagen = childrens[i].GetComponent<Image>();
string ruta = GetRutaSprite(character.ItemsInInventory[i]);
Sprite icono = Resources.Load<Sprite>(ruta);
imagen.name = "Item";
imagen.sprite = icono;
print("parent is " + slot.name);
imagen.transform.SetParent(slot.transform);
}
}
When I run this, I got this:
As you can see, Slot0 has dissapeared, and it is being substituted by item. What I would like to achieve is Item be a son of Slot0. I dont know why it happens this way, since I am setting the image's parent to the slot. In the print("Slot: " + slot.name); line it prints "Slot0", but in print("parent is " + slot.name); line it prints Item. Why is that? Also, the sword looks like it is behind something...it is not displayed correctly. I would like to show the icon AND the slot border.
How can I populate my inventory properly?
In your code, you just found the slot, get an image (which is border), and replace sprite on it with your items sprite.
You need to instantiate new image instead. It can be a prefab, or you can use your border image to create a copy from it (do not forget to change color). Or, if you have a separate Image inside slot, and you want to set the sprite for it, you need to get reference on it, but not on border. For this, you need a script on your slot, holding that reference.
for make a minimal changes in your code, you can do like this:
Sprite icono = Resources.Load<Sprite>(ruta);
Image newImage = Instantiate(imagen, slot.transform);
newImage .name = "Item";
newImage .sprite = icono;
print("parent is " + slot.name);
newImage.transform.SetParent(slot.transform);
But I defenitely recommend to rework it: at least, add a script on your slot, holding a reference to your second Image (which is not border).
I'm testing Gwt Highcharts but I have a big problem: I need to draw a scatter chart with symbol and rotate the symbol.
For example:
Point p1 = new Point(5, 5);
Marker m = new Marker();
m.setEnabled(true);
m.setRadius(4);
String myUrl = "url(" + GWT.getModuleBaseURL()+"images/snow.png" + ")";
m.setOption("symbol", myUrl);
p1.setMarker(m);
This all works fine
The problem is that I need to rotate the symbol by a degree value. I've tried the following code but it doesn't work:
String myRotate = "rotate(45)";
m.setOption("transform", myRotate);
What's wrong?
Thanks a Lot.
Maurizio
This is what we've came up with in our case:
private static native void rotateMarkers(double angle)/*-{
//Accessing the series we'll rotate
var points = $wnd.Highcharts.charts[0].series[3].points;
//rotating
var str = parseFloat(points[i].graphic.attr('x')) +
parseFloat(points[i].graphic.attr('width'))/2 +
","+ (parseFloat(points[i].graphic.attr("y")))+
")";
points[i].graphic.attr("transform","rotate("+angle+","+str);
}-*/;
It didn't work for us in non-jsni way, same way it didn't for you.
I am having an issue with my code, i'm trying to move a 3D box to the variable of the position of the mouse, I need to know how to change the box's x,y,z with my mouse position script.
All im asking really, is how do I change my boxes x,y,z with a variable in another script. Thanks!
Code:
#pragma strict
public var distance : float = 4.5;
var box = Transform;
private var firstObject : cube;
function Start () {
}
function Update () {
CastRayToWorld();
}
function CastRayToWorld() {
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var point : Vector3 = ray.origin + (ray.direction * distance);
Debug.Log( "World point " + point );
firstObject = GameObject.Find("pos").GetComponent("cube").pos = point;
firstObject.pos = point;
}
Make sure that the other object is aware of your box gameObject (lets say under the name 'adjustable'), then its simply a case of:
adjustable.transform.position = new Vector3(x, y, z)
To make sure that the object is aware of the boxes gameObject, you could make adjustable a public variable, and then manual drag the box from your scene into the field that would be created in the component on the object in question.
I'm trying to import an existing .anim file to an existing unity model.
I know how do so it in Unity, and build into a HTML file, but I'm wondering is there a method to do it just using unityscript or javascript?
I mean using javascript to load an .anim file into the model in unity web player, if there is any solution, thanks!
Resource.Load allows you to do just that.
var mdl : GameObject = Resources.Load("Animations/"+ animationFolder+"/" + aName);
if (!mdl) {
Debug.LogError("Missing animation asset: Animations/" + animationFolder+"/"+aName + " could not be found.");
} else {
var aClip = mdl.animation.clip;
charAnimation.AddClip(aClip, aName);
Debug.Log(charAnimation[aName].name + " loaded from resource file " + animationFolder + "/" + aName + ". Length check: " + charAnimation[aName].length);
}
I am creating something like in the sims where you have a character and you can add different clothes to the character.
All the models I use are using the same bones and rig. I have put these models in different asset bundles. At runtime I read the asset bundles and combine these models in one SkinnedMeshRenderer and thus in one object. But every time I add another object the bone count goes up.
I know why this is happening, but I would like to reduce the number of bones again.
I tried to find the duplicate bones and delete those and the bindpose on the same index as the bone deleted, but this still gives me the error "Number of bindposes doesn't match number of bones" even though they are both 45.
Here is the code that attaches the models:
private void UpdateSkinnedMesh()
{
float startTime = Time.realtimeSinceStartup;
// Create a list of for all data
List combineInstances = new List();
List materials = new List();
List bones = new List();
Transform[] transforms = baseModel.GetComponentsInChildren();
//TEMP
List elements = new List();
elements.Add(body);
if(_currentActiveProps.ContainsKey(ItemSubCategory.Skin))
elements.Add(tutu);
//Go over all active elements
foreach (CharacterElement element in elements)
{
//Get the skinned mesh renderer
SkinnedMeshRenderer smr = element.GetSkinnedMeshRenderer();
//Add materials to the entire list
materials.AddRange(smr.materials);
//Add all submeshes to a combined mesh
for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++)
{
CombineInstance ci = new CombineInstance();
ci.mesh = smr.sharedMesh;
ci.subMeshIndex = sub;
combineInstances.Add(ci);
}
//Bones are not saved in asset bundle, get the names and reference them again
foreach (string bone in element.GetBoneNames())
{
foreach (Transform transform in transforms)
{
if (transform.name != bone) continue;
bones.Add(transform);
break;
}
}
//Destroy the temp object
Destroy(smr.gameObject);
}
//Get skinned mesh renderer
SkinnedMeshRenderer r = baseModel.GetComponentInChildren();
//Create enew combined mesh
r.sharedMesh = new Mesh();
r.sharedMesh.CombineMeshes(combineInstances.ToArray(), false, false);
//Add bones and materials
r.bones = bones.ToArray();
r.materials = materials.ToArray();
Debug.Log("Bindposes: " + r.sharedMesh.bindposes.Length);
Debug.Log("Generating character took: " + (Time.realtimeSinceStartup - startTime) * 1000 + " ms");
Debug.Log("Bone count: " + r.bones.Length);
}
I already have asked the question on Unity Answers, but because it takes a few hours before a moderator approves the question, I wanted to try here as well.