Unity: How can I put one object on top of another - c#

I need put my 3D Object dynamicly to platform because 3D Object has a different size.
My code is _sceneObject.sceneItem.transform.localPosition = _gobletPlatform.localPosition; but he fixes on it, not on top of it.

Collider platformCollider = (_gobletPlatform.GetComponent<Collider>();
Vector3 pos = new Vector3 (_gobletPlatform.transform.position.x + platformCollider.bounds.size.x, _gobletPlatform.transform.position.y + platformCollider.bounds.size.y, _gobletPlatform.transform.position.z + platformCollider.bounds.size.z);
_sceneObject.sceneItem.transform.position = pos;
Note: I can't test this now. But, I hope it works.

Related

Detecting overlapping polygon2D colliders in Unity

I'm trying to program an isometric building placement script. Each building has a PolygonCollider2D component on it with a trigger. When placing a new building, I'm trying to check if the PolygonCollider2D of the placed building overlaps with anything else (to check if placement is valid). My code is as follows:
Adjust the points of the new placed building collider based on the mouse position
Vector2[] points = polygonCollider2D.points;
points.SetValue(polygonCollider2D.points[0] + (Vector2)mousePosition, 0);
points.SetValue(polygonCollider2D.points[1] + (Vector2)mousePosition, 1);
points.SetValue(polygonCollider2D.points[2] + (Vector2)mousePosition, 2);
points.SetValue(polygonCollider2D.points[3] + (Vector2)mousePosition, 3);
polygonCollider2D.points = points;
Set up contact filter:
ContactFilter2D contactFilter2D = new ContactFilter2D();
contactFilter2D.useTriggers = true;
contactFilter2D.SetLayerMask(polygonCollider2D.gameObject.layer);
Check for collisions
List<Collider2D> list = new List<Collider2D>();
Debug.Log(polygonCollider2D.OverlapCollider(contactFilter2D, list));
However if there is already a building there, it still does not register an overlap.
What am I missing / doing wrong ?
Thanks so much for the help!
Your code which sets the polygon collider points seems to be the issue here. If that code runs multiple times, it will repeatedly offset the collider further and further away from its original position. You probably don't want to be changing the actual collider; usually you should move object which has the collider. So you would replace those lines with something like this:
gameObject.transform.position = mousePosition;

Get the center point between many GameObjects in Unity

I have created a game in which you can control X characters at the same time in the same form and they can die at any time. My problem is when I want the game camera to include all these gameobjects.
I thought that a good option is to calculate the central point between the gameobjects in the scene and make the camera follow that point at a certain distance.
I already have the camera code, but I still need to know how to get that central point or another way of doing it. In addition, the camera does not follow any of the axes (X, Y, Z) linearly, since it is placed in such a way that is the view is isometric (the game is in 3D).
As a last important fact, it is that all gameobjects that are running in the game (that are alive), are stored in a public static List <GameObject> to be able to access the components of these gameobjects at any time. Also, if a character (gameobject) dies or is born, the list is updated without problems.
I leave you a graphic example with three different cases, being the black points, the characters that are in the scene (gameobjects) and the red points, the central point (vector) that I would like to find.
Also, I leave the camera code so you can test if you have any solution:
public class Camera_Movement : MonoBehaviour {
Vector3 newPos;
public static List<GameObject> playersInGame = new List<GameObject>();
void Update() {
// Get Central Vector
// Replace playersInGame[0].transform.position with central vector
//newPos = Vector3.Lerp(gameObject.transform.position, "central vector", Time.deltaTime);
newPos = Vector3.Lerp(gameObject.transform.position, playersInGame[0].transform.position, Time.deltaTime);
gameObject.transform.position = new Vector3(newPos.x, newPos.y, newPos.z);
}
}
Thank you very much in advance!
You need to take the average x and and average y.
That would look like the following:
var totalX = 0f;
var totalY = 0f;
foreach(var player in playersInGame)
{
totalX += player.transform.position.x;
totalY += player.transform.position.y;
}
var centerX = totalX / playersInGame.Count;
var centerY = totalY / playersInGame.Count;
Let me know if this works for you (don't have access to Unity at the moment), but I put together an example here: https://dotnetfiddle.net/jGd99I
To have a solution that your camera can be best positioned to see all of your objects, then try this:
public Vector3 FindCenterOfTransforms(List<Transform> transforms)
{
var bound = new Bounds(transforms[0].position, Vector3.zero);
for(int i = 1; i < transforms.Count; i++)
{
bound.Encapsulate(transforms[i].position);
}
return bound.center;
}

Unity Editor Pipeline Scripting: how to Pass Sprite to SpriteRenderer in OnPostprocessSprites() Event?

after importing sprites inside unity , i want to make a Prefab out Of them and assign them a SpriteRenderer and BoxCollider2D component , all automaticly.
every thing is good exept i cant pass the imported Sprite to the SpriteRenderer component any how.
i dont knoow what im missing here. any help will be appritiated.
void OnPostprocessSprites(Texture2D texture, Sprite[] sprites)
{
Sprite sp = sprites[0];
TextureImporter importer = (TextureImporter)assetImporter;
importer.textureType = TextureImporterType.Sprite;
GameObject GO = new GameObject();
GO.name = sp.name;
string ResAddress = importer.assetPath.Remove(importer.assetPath.Length - 4, 4).Replace("Assets/Resources/", "");
Debug.Log("Resource Address = " + ResAddress);// Images/Objects/car acceptable for Resource.load
//GO.AddComponent<SpriteRenderer>().sprite = sp;// not works
GO.AddComponent<SpriteRenderer>().sprite = (Sprite)Resources.Load(ResAddress);// not works
GO.AddComponent<BoxCollider2D>();
Object prefab = PrefabUtility.CreateEmptyPrefab(string.Format("Assets/Resources/X_Temp/{0}.prefab", GO.name));
if (prefab != null)PrefabUtility.ReplacePrefab(GO, prefab, ReplacePrefabOptions.ConnectToPrefab);
}
there is no Error or messages , it makes the prefab with BoxCollider And SpriteRendere Components But SpriteRenderer's Sprite Field Has No Sprite, and set to none or Missing.
how can i fix this?
also asked in Unity Community And No luck.
https://answers.unity.com/questions/1434068/how-to-pass-sprite-to-spriterenderer-in-onpostproc.html
https://forum.unity.com/threads/how-to-pass-sprite-to-spriterenderer-in-onpostprocesssprites-event.505638/
====== UPDATE And NOT RECOMMENDED ANSWER ======
void OnPostprocessSprites(Texture2D texture, Sprite[] sprites)
{
TextureImporter importer = (TextureImporter)assetImporter;
if (AssetDatabase.LoadAssetAtPath<Sprite>(importer.assetPath)==null)
{
AssetDatabase.Refresh();
return;
}
foreach (Sprite sp in sprites)
{
importer.textureType = TextureImporterType.Sprite;
GameObject GO = new GameObject();
GO.name = sp.name;
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(importer.assetPath);
GO.AddComponent<SpriteRenderer>().sprite = sprite;
string address = string.Format("Assets/Resources/Prefabs/{0}.prefab", GO.name);
PrefabUtility.CreatePrefab(address, GO);
PrefabUtility.ReconnectToLastPrefab(GO);
}
}
not recommended Because Of the following Crash Error :
A default asset was created for 'Assets/Resources/Images/Objects/car.png' because the asset importer crashed on it last time.You can select the asset and use the 'Assets -> Reimport' menu command to try importing it again, or you can replace the asset and it will auto import again.UnityEditor.AssetDatabase:Refresh()
This is really interesting. I don't think that Resources.Load(ResAddress) is returning null otherwise you should see null if you use Debug.Log on it. I assumed that the texture variable from the OnPostprocessSprites function would work if you convert it to Sprite then assign it to the SpriteRenderer like so:
Sprite tempSprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
GO.AddComponent<SpriteRenderer>().sprite = tempSprite;
That didn't work too despite the fact that tempSprite is not null. This quickly made me remember the AssetDatabase API which is specifically used to access and operate on assets.
You are looking for the AssetDatabase.LoadAssetAtPath function. It will return the proper Sprite asset you can use to change the SpriteRenderer.sprite property.
This should work:
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(assetPath);
GO.AddComponent<SpriteRenderer>().sprite = tempSprite;
It would make sense to call AssetDatabase.Refresh() after all these but it seems to work without calling AssetDatabase.Refresh(). I still think you should call it.

Unity 5.4.2 - Scale and position instantiated UI elements

So I've been working on a project for a class I'm in and have run into a pickle that I can't seem to resolve. I have asked the instructor and he was confused as I was.
Right now I've just been trying to set up a simple UI for displaying a list of buttons to select a level to load. At runtime the code simply creates the appropriate buttons and such, and places them within a scrollview's content object. Simple enough, right? Well, as you can see the position and right are completely wrong, by 800 units.
The Canvas is set to a Screen Space - Overlay and the Canvas Scaler is set to scale with screen size, which I'm guessing is the problem. I already had the problem of the position and scale being even more off (depending on the screen size), but "fixed" this by manually setting the transform's position and localscale.
I have however had no luck finding a solution to this, with all my googling, so I'd be very appreciative if someone could help me with this and explain to me what the problem is.
Here is the code that it executes for each of the levels. It's of course messy because I've been trying about as much as I could to figure out what the problem is.
Level thisLevel = levelManager.levelList [i];
GameObject levelButton = (GameObject)Instantiate (menuManager.levelButtonContainerObject);
levelButton.transform.SetParent (menuManager.mainMenuLevelContainer.transform, false);
levelButton.transform.position = Vector3.zero;
levelButton.transform.localPosition = Vector3.zero;
levelButton.transform.localScale = Vector2.one;
RectTransform levelButtonRect = levelButton.GetComponent<RectTransform> ();
// levelButtonRect.position = ApplyCanvasScale (new Vector3 (0f, -50 + (-100 * i), 0f));
levelButtonRect.position = new Vector3(0f, -50 + (-100 * i), 0f);
// levelButtonRect.position = Vector3.zero;
levelButtonRect.sizeDelta = new Vector2 (0f, 100f);
Debug.Log ("Position " + levelButtonRect.position + ", Scale " + levelButtonRect.sizeDelta);
Try adding these where you're setting position and scale:
levelButton.transform.offsetMin = Vector2.zero
levelButton.transform.offsetMax = Vector2.zero

Applying force to a dynamically created object

I have a problem with trying to apply force to an object after it has been dynamically created.
Let me start by mentioning that I havn't been working in silverlight and with c# for very long and my code is not likely to be very efficient in what it does, but I am trying to make it work.
I have a spaceship that will fire a bullet on keypress. I create this bullet and have it appear a few pixels above the spaceship. Now I want to have it travel across the screen and I just can't get it to work.
private void fireShot()
{
double playerY = 0;
double playerX = 0;
PhysicsSprite player = _physicsController.PhysicsObjects["Player"];
playerX = player.Position.X;
playerY = player.Position.Y;
ucStaticPlanet shot = new ucStaticPlanet();
shot.Name = "shot_" + shotcount;
shotcount++;
shot.SetValue(Canvas.LeftProperty, Convert.ToDouble(playerX));
shot.SetValue(Canvas.TopProperty, Convert.ToDouble(playerY - 50));
LayoutRoot.Children.Add(shot);//adds the planet to the canvas
_physicsController.AddPhysicsBodyForCanvasWithBehaviors(shot.LayoutRoot);
The bullet that is created does not move upon creation. It is instead just going to get dragged towards to the ground due to the gravity I have in place. I want the bullet to have some speed as it is created, so as to act like a bullet.
I appreciate any help I can get.

Categories